mirror of
https://github.com/dart-lang/sdk
synced 2024-11-05 18:22:09 +00:00
Adjust implementation of the hash-closurization to work with --no-lazy-dispatchers.
R=hausner@google.com Review URL: https://codereview.chromium.org//1269143003 .
This commit is contained in:
parent
a42e6199da
commit
e8320e4081
2 changed files with 65 additions and 16 deletions
|
@ -1054,23 +1054,72 @@ DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodDispatcher, 4) {
|
|||
// a zigzagged lookup to see if this call failed because of an arity mismatch,
|
||||
// need for conversion, or there really is no such method.
|
||||
|
||||
#define NO_SUCH_METHOD() \
|
||||
const Object& result = Object::Handle( \
|
||||
DartEntry::InvokeNoSuchMethod(receiver, \
|
||||
target_name, \
|
||||
orig_arguments, \
|
||||
orig_arguments_desc)); \
|
||||
CheckResultError(result); \
|
||||
arguments.SetReturn(result); \
|
||||
|
||||
#define CLOSURIZE(some_function) \
|
||||
const Function& closure_function = \
|
||||
Function::Handle(some_function.ImplicitClosureFunction()); \
|
||||
const Object& result = \
|
||||
Object::Handle(closure_function.ImplicitInstanceClosure(receiver)); \
|
||||
arguments.SetReturn(result); \
|
||||
|
||||
const bool is_getter = Field::IsGetterName(target_name);
|
||||
if (is_getter) {
|
||||
// o.foo failed, closurize o.foo() if it exists
|
||||
const String& field_name =
|
||||
String::Handle(Field::NameFromGetter(target_name));
|
||||
// o.foo (o.get:foo) failed, closurize o.foo() if it exists. Or,
|
||||
// o#foo (o.get:#foo) failed, closurizee o.foo or o.foo(), whichever is
|
||||
// encountered first on the inheritance chain. Or,
|
||||
// o#foo= (o.get:#set:foo) failed, closurize o.foo= if it exists.
|
||||
String& field_name =
|
||||
String::Handle(Field::NameFromGetter(target_name));
|
||||
|
||||
const bool is_extractor = field_name.CharAt(0) == '#';
|
||||
if (is_extractor) {
|
||||
field_name = String::SubString(field_name, 1);
|
||||
ASSERT(!Field::IsGetterName(field_name));
|
||||
field_name = Symbols::New(field_name);
|
||||
|
||||
if (!Field::IsSetterName(field_name)) {
|
||||
const String& getter_name =
|
||||
String::Handle(Field::GetterName(field_name));
|
||||
|
||||
// Zigzagged lookup: closure either a regular method or a getter.
|
||||
while (!cls.IsNull()) {
|
||||
function ^= cls.LookupDynamicFunction(field_name);
|
||||
if (!function.IsNull()) {
|
||||
CLOSURIZE(function);
|
||||
return;
|
||||
}
|
||||
function ^= cls.LookupDynamicFunction(getter_name);
|
||||
if (!function.IsNull()) {
|
||||
CLOSURIZE(function);
|
||||
return;
|
||||
}
|
||||
cls = cls.SuperClass();
|
||||
}
|
||||
NO_SUCH_METHOD();
|
||||
return;
|
||||
} else {
|
||||
// Fall through for non-ziggaged lookup for o#foo=.
|
||||
}
|
||||
}
|
||||
|
||||
while (!cls.IsNull()) {
|
||||
function ^= cls.LookupDynamicFunction(field_name);
|
||||
if (!function.IsNull()) {
|
||||
const Function& closure_function =
|
||||
Function::Handle(function.ImplicitClosureFunction());
|
||||
const Object& result =
|
||||
Object::Handle(closure_function.ImplicitInstanceClosure(receiver));
|
||||
arguments.SetReturn(result);
|
||||
CLOSURIZE(function);
|
||||
return;
|
||||
}
|
||||
cls = cls.SuperClass();
|
||||
}
|
||||
|
||||
// Fall through for noSuchMethod
|
||||
} else {
|
||||
// o.foo(...) failed, invoke noSuchMethod is foo exists but has the wrong
|
||||
// number of arguments, or try (o.foo).call(...)
|
||||
|
@ -1117,14 +1166,10 @@ DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodDispatcher, 4) {
|
|||
}
|
||||
}
|
||||
|
||||
// Handle noSuchMethod invocation.
|
||||
const Object& result = Object::Handle(
|
||||
DartEntry::InvokeNoSuchMethod(receiver,
|
||||
target_name,
|
||||
orig_arguments,
|
||||
orig_arguments_desc));
|
||||
CheckResultError(result);
|
||||
arguments.SetReturn(result);
|
||||
NO_SUCH_METHOD();
|
||||
|
||||
#undef NO_SUCH_METHOD
|
||||
#undef CLOSURIZE
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -116,6 +116,10 @@ RawFunction* Resolver::ResolveDynamicAnyArgs(
|
|||
field_name ^= Field::NameFromGetter(function_name);
|
||||
|
||||
if (field_name.CharAt(0) == '#') {
|
||||
if (!FLAG_lazy_dispatchers) {
|
||||
return Function::null();
|
||||
}
|
||||
|
||||
// Resolving a getter "get:#..." is a request to closurize an instance
|
||||
// property of the receiver object. It can be of the form:
|
||||
// - get:#id, which closurizes a method or getter id
|
||||
|
|
Loading…
Reference in a new issue