| Index: runtime/vm/object_test.cc
|
| diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
|
| index 8d93d307a97299637be975a8f285a4787bca1082..527ce026d2944d709231dbf42c813ae4bd806b6d 100644
|
| --- a/runtime/vm/object_test.cc
|
| +++ b/runtime/vm/object_test.cc
|
| @@ -3468,17 +3468,21 @@ TEST_CASE(FindFieldIndex) {
|
|
|
|
|
| TEST_CASE(FindFunctionIndex) {
|
| + // Tests both FindFunctionIndex and FindImplicitClosureFunctionIndex.
|
| const char* kScriptChars =
|
| "class A {\n"
|
| " void a() {}\n"
|
| - " void b() {}\n"
|
| + " void b() { return a; }\n"
|
| "}\n"
|
| "class B {\n"
|
| " dynamic d() {}\n"
|
| "}\n"
|
| + "var x;\n"
|
| "test() {\n"
|
| - " new A();\n"
|
| + " x = new A().b();\n"
|
| + " x();\n"
|
| " new B();\n"
|
| + " return x;\n"
|
| "}";
|
| Dart_Handle h_lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
| EXPECT_VALID(h_lib);
|
| @@ -3488,30 +3492,38 @@ TEST_CASE(FindFunctionIndex) {
|
| lib ^= Api::UnwrapHandle(h_lib);
|
| EXPECT(!lib.IsNull());
|
| const Class& class_a = Class::Handle(GetClass(lib, "A"));
|
| - const Array& class_a_funcs = Array::Handle(class_a.functions());
|
| const Class& class_b = Class::Handle(GetClass(lib, "B"));
|
| const Function& func_a = Function::Handle(GetFunction(class_a, "a"));
|
| const Function& func_b = Function::Handle(GetFunction(class_a, "b"));
|
| const Function& func_d = Function::Handle(GetFunction(class_b, "d"));
|
| + EXPECT(func_a.HasImplicitClosureFunction());
|
| + const Function& func_x = Function::Handle(func_a.ImplicitClosureFunction());
|
| intptr_t func_a_index = class_a.FindFunctionIndex(func_a);
|
| intptr_t func_b_index = class_a.FindFunctionIndex(func_b);
|
| intptr_t func_d_index = class_a.FindFunctionIndex(func_d);
|
| + intptr_t func_x_index = class_a.FindImplicitClosureFunctionIndex(func_x);
|
| // Valid index.
|
| EXPECT_GE(func_a_index, 0);
|
| // Valid index.
|
| EXPECT_GE(func_b_index, 0);
|
| // Invalid index.
|
| EXPECT_EQ(func_d_index, -1);
|
| + // Valid index.
|
| + EXPECT_GE(func_x_index, 0);
|
| Function& func_a_from_index = Function::Handle();
|
| - func_a_from_index ^= class_a_funcs.At(func_a_index);
|
| - ASSERT(!func_a_from_index.IsNull());
|
| + func_a_from_index ^= class_a.FunctionFromIndex(func_a_index);
|
| + EXPECT(!func_a_from_index.IsNull());
|
| // Same function.
|
| EXPECT_EQ(func_a.raw(), func_a_from_index.raw());
|
| Function& func_b_from_index = Function::Handle();
|
| - func_b_from_index ^= class_a_funcs.At(func_b_index);
|
| - ASSERT(!func_b_from_index.IsNull());
|
| + func_b_from_index ^= class_a.FunctionFromIndex(func_b_index);
|
| + EXPECT(!func_b_from_index.IsNull());
|
| // Same function.
|
| EXPECT_EQ(func_b.raw(), func_b_from_index.raw());
|
| + // Retrieve implicit closure function.
|
| + Function& func_x_from_index = Function::Handle();
|
| + func_x_from_index ^= class_a.ImplicitClosureFunctionFromIndex(func_x_index);
|
| + EXPECT_EQ(func_x.raw(), func_x_from_index.raw());
|
| }
|
|
|
|
|
| @@ -3535,24 +3547,65 @@ TEST_CASE(FindClosureIndex) {
|
| // Add closure function to class.
|
| cls.AddClosureFunction(function);
|
|
|
| - // Token position 0 should return a valid index.
|
| - intptr_t good_closure_index = cls.FindClosureIndex(0);
|
| + // The closure should return a valid index.
|
| + intptr_t good_closure_index = cls.FindClosureIndex(function);
|
| EXPECT_GE(good_closure_index, 0);
|
| - // Token position 1 should return an invalid index.
|
| - intptr_t bad_closure_index = cls.FindClosureIndex(1);
|
| + // The parent function should return an invalid index.
|
| + intptr_t bad_closure_index = cls.FindClosureIndex(parent);
|
| EXPECT_EQ(bad_closure_index, -1);
|
|
|
| // Retrieve closure function via index.
|
| - const GrowableObjectArray& closures = GrowableObjectArray::Handle(
|
| - cls.closures());
|
| Function& func_from_index = Function::Handle();
|
| - func_from_index ^= closures.At(good_closure_index);
|
| -
|
| + func_from_index ^= cls.ClosureFunctionFromIndex(good_closure_index);
|
| // Same closure function.
|
| EXPECT_EQ(func_from_index.raw(), function.raw());
|
| }
|
|
|
|
|
| +TEST_CASE(FindInvocationDispatcherFunctionIndex) {
|
| + const String& class_name = String::Handle(Symbols::New("MyClass"));
|
| + const Script& script = Script::Handle();
|
| + const Class& cls = Class::Handle(CreateDummyClass(class_name, script));
|
| + ClassFinalizer::FinalizeTypesInClass(cls);
|
| +
|
| + const Array& functions = Array::Handle(Array::New(1));
|
| + Function& parent = Function::Handle();
|
| + const String& parent_name = String::Handle(Symbols::New("foo_papa"));
|
| + parent = Function::New(parent_name, RawFunction::kRegularFunction,
|
| + false, false, false, false, false, cls, 0);
|
| + functions.SetAt(0, parent);
|
| + cls.SetFunctions(functions);
|
| + cls.Finalize();
|
| +
|
| + // Add invocation dispatcher.
|
| + const String& invocation_dispatcher_name =
|
| + String::Handle(Symbols::New("myMethod"));
|
| + const Array& args_desc = Array::Handle(ArgumentsDescriptor::New(1));
|
| + Function& invocation_dispatcher = Function::Handle();
|
| + invocation_dispatcher ^=
|
| + cls.GetInvocationDispatcher(invocation_dispatcher_name, args_desc,
|
| + RawFunction::kNoSuchMethodDispatcher);
|
| + EXPECT(!invocation_dispatcher.IsNull());
|
| + // Get index to function.
|
| + intptr_t invocation_dispatcher_index =
|
| + cls.FindInvocationDispatcherFunctionIndex(invocation_dispatcher);
|
| + // Expect a valid index.
|
| + EXPECT_GE(invocation_dispatcher_index, 0);
|
| + // Retrieve function through index.
|
| + Function& invocation_dispatcher_from_index = Function::Handle();
|
| + invocation_dispatcher_from_index ^=
|
| + cls.InvocationDispatcherFunctionFromIndex(invocation_dispatcher_index);
|
| + // Same function.
|
| + EXPECT_EQ(invocation_dispatcher.raw(),
|
| + invocation_dispatcher_from_index.raw());
|
| + // Test function not found case.
|
| + const Function& bad_function = Function::Handle(Function::null());
|
| + intptr_t bad_invocation_dispatcher_index =
|
| + cls.FindInvocationDispatcherFunctionIndex(bad_function);
|
| + EXPECT_EQ(bad_invocation_dispatcher_index, -1);
|
| +}
|
| +
|
| +
|
| static void PrintMetadata(const char* name, const Object& data) {
|
| if (data.IsError()) {
|
| OS::Print("Error in metadata evaluation for %s: '%s'\n",
|
|
|