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,
|
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue