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:
Ryan Macnak 2015-08-04 16:11:55 -07:00
parent a42e6199da
commit e8320e4081
2 changed files with 65 additions and 16 deletions

View file

@ -1054,23 +1054,72 @@ DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodDispatcher, 4) {
// a zigzagged lookup to see if this call failed because of an arity mismatch, // a zigzagged lookup to see if this call failed because of an arity mismatch,
// need for conversion, or there really is no such method. // 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); const bool is_getter = Field::IsGetterName(target_name);
if (is_getter) { if (is_getter) {
// o.foo failed, closurize o.foo() if it exists // o.foo (o.get:foo) failed, closurize o.foo() if it exists. Or,
const String& field_name = // o#foo (o.get:#foo) failed, closurizee o.foo or o.foo(), whichever is
String::Handle(Field::NameFromGetter(target_name)); // 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()) { while (!cls.IsNull()) {
function ^= cls.LookupDynamicFunction(field_name); function ^= cls.LookupDynamicFunction(field_name);
if (!function.IsNull()) { if (!function.IsNull()) {
const Function& closure_function = CLOSURIZE(function);
Function::Handle(function.ImplicitClosureFunction());
const Object& result =
Object::Handle(closure_function.ImplicitInstanceClosure(receiver));
arguments.SetReturn(result);
return; return;
} }
cls = cls.SuperClass(); cls = cls.SuperClass();
} }
// Fall through for noSuchMethod
} else { } else {
// o.foo(...) failed, invoke noSuchMethod is foo exists but has the wrong // o.foo(...) failed, invoke noSuchMethod is foo exists but has the wrong
// number of arguments, or try (o.foo).call(...) // number of arguments, or try (o.foo).call(...)
@ -1117,14 +1166,10 @@ DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodDispatcher, 4) {
} }
} }
// Handle noSuchMethod invocation. NO_SUCH_METHOD();
const Object& result = Object::Handle(
DartEntry::InvokeNoSuchMethod(receiver, #undef NO_SUCH_METHOD
target_name, #undef CLOSURIZE
orig_arguments,
orig_arguments_desc));
CheckResultError(result);
arguments.SetReturn(result);
} }

View file

@ -116,6 +116,10 @@ RawFunction* Resolver::ResolveDynamicAnyArgs(
field_name ^= Field::NameFromGetter(function_name); field_name ^= Field::NameFromGetter(function_name);
if (field_name.CharAt(0) == '#') { if (field_name.CharAt(0) == '#') {
if (!FLAG_lazy_dispatchers) {
return Function::null();
}
// Resolving a getter "get:#..." is a request to closurize an instance // Resolving a getter "get:#..." is a request to closurize an instance
// property of the receiver object. It can be of the form: // property of the receiver object. It can be of the form:
// - get:#id, which closurizes a method or getter id // - get:#id, which closurizes a method or getter id