Fix resolving of implicit closures: treat null objects same as instances of Object.
Review URL: https://chromereviews.googleplex.com/3551013 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@138 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
@@ -448,7 +448,9 @@ DEFINE_RUNTIME_ENTRY(ResolvePatchInstanceCall, 1) {
|
||||
DartFrame* caller_frame = iterator.NextFrame();
|
||||
String& function_name = String::Handle();
|
||||
if ((!receiver.IsNull() && code.IsNull()) || !FLAG_inline_cache) {
|
||||
// Let megamorphic lookup handle noSuchMethod.
|
||||
// We did not find a method; it means either that we need to invoke
|
||||
// noSuchMethod or that we have encountered a situation with implicit
|
||||
// closures. All these cases are handled by the megamorphic lookup stub.
|
||||
CodePatcher::PatchInstanceCallAt(
|
||||
caller_frame->pc(), StubCode::MegamorphicLookupEntryPoint());
|
||||
if (FLAG_trace_ic) {
|
||||
@@ -528,15 +530,24 @@ DEFINE_RUNTIME_ENTRY(ResolvePatchInstanceCall, 1) {
|
||||
}
|
||||
|
||||
|
||||
static RawFunction* LookupDynamicFunction(Class* cls, const String& name) {
|
||||
static RawFunction* LookupDynamicFunction(const Class& in_cls,
|
||||
const String& name) {
|
||||
Class& cls = Class::Handle();
|
||||
// For lookups treat null as an instance of class Object.
|
||||
if (in_cls.IsNullClass()) {
|
||||
cls = Isolate::Current()->object_store()->object_class();
|
||||
} else {
|
||||
cls = in_cls.raw();
|
||||
}
|
||||
|
||||
Function& function = Function::Handle();
|
||||
while (!cls->IsNull()) {
|
||||
while (!cls.IsNull()) {
|
||||
// Check if function exists.
|
||||
function = cls->LookupDynamicFunction(name);
|
||||
function = cls.LookupDynamicFunction(name);
|
||||
if (!function.IsNull()) {
|
||||
break;
|
||||
}
|
||||
*cls = cls->SuperClass();
|
||||
cls = cls.SuperClass();
|
||||
}
|
||||
return function.raw();
|
||||
}
|
||||
@@ -554,11 +565,6 @@ DEFINE_RUNTIME_ENTRY(ResolveImplicitClosureFunction, 2) {
|
||||
kResolveImplicitClosureFunctionRuntimeEntry.argument_count());
|
||||
const Instance& receiver = Instance::CheckedHandle(arguments.At(0));
|
||||
const String& original_func_name = String::CheckedHandle(arguments.At(1));
|
||||
if (receiver.IsNull()) {
|
||||
// No implicit closure functions on null.
|
||||
GrowableArray<const Object*> args;
|
||||
Exceptions::ThrowByType(Exceptions::kNullPointer, args);
|
||||
}
|
||||
const String& getter_prefix = String::Handle(String::New("get:"));
|
||||
Closure& closure = Closure::Handle();
|
||||
if (!original_func_name.StartsWith(getter_prefix)) {
|
||||
@@ -574,7 +580,7 @@ DEFINE_RUNTIME_ENTRY(ResolveImplicitClosureFunction, 2) {
|
||||
func_name = String::SubString(original_func_name, getter_prefix.Length());
|
||||
func_name = String::NewSymbol(func_name);
|
||||
const Function& function =
|
||||
Function::Handle(LookupDynamicFunction(&receiver_class, func_name));
|
||||
Function::Handle(LookupDynamicFunction(receiver_class, func_name));
|
||||
if (function.IsNull()) {
|
||||
// There is no function of the same name so can't be the case where
|
||||
// we are trying to create an implicit closure of an instance function.
|
||||
|
||||
@@ -87,6 +87,7 @@ InterfaceFactory3NegativeTest: Fail # 5387405
|
||||
GenericParameterizedExtendsTest: Skip # Bug 5392297
|
||||
ConstObjectsAreImmutableTest: Fail # Bug 5202940
|
||||
SuperNegativeTest: Fail # Now that super calls are automatically injected this test doesn't make sense
|
||||
NullToStringTest: Fail # Bug 5421978
|
||||
|
||||
# Crashes in dartc.
|
||||
FunctionTypeAliasTest: Crash # Bug 4519208.
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
// Test correct handling of NULL object in invocation and implicit closures.
|
||||
|
||||
main() {
|
||||
var nullObj = null;
|
||||
var x = nullObj.toString();
|
||||
Expect.isTrue(x is String);
|
||||
var y = nullObj.toString;
|
||||
Expect.isNotNull(y);
|
||||
}
|
||||
Reference in New Issue
Block a user