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:
srdjan@google.com
2011-10-06 16:31:31 +00:00
parent 1bcf461c37
commit 44392fdb03
3 changed files with 30 additions and 11 deletions
+17 -11
View File
@@ -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.
+1
View File
@@ -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.
+12
View File
@@ -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);
}