Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/assembler.h" | 5 #include "vm/assembler.h" |
| 6 #include "vm/bigint_operations.h" | 6 #include "vm/bigint_operations.h" |
| 7 #include "vm/class_finalizer.h" | 7 #include "vm/class_finalizer.h" |
| 8 #include "vm/dart_api_impl.h" | 8 #include "vm/dart_api_impl.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/debugger.h" | 10 #include "vm/debugger.h" |
| (...skipping 3450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3461 EXPECT_EQ(field_a.raw(), field_a_from_index.raw()); | 3461 EXPECT_EQ(field_a.raw(), field_a_from_index.raw()); |
| 3462 Field& field_b_from_index = Field::Handle(); | 3462 Field& field_b_from_index = Field::Handle(); |
| 3463 field_b_from_index ^= class_a_fields.At(field_b_index); | 3463 field_b_from_index ^= class_a_fields.At(field_b_index); |
| 3464 ASSERT(!field_b_from_index.IsNull()); | 3464 ASSERT(!field_b_from_index.IsNull()); |
| 3465 // Same field. | 3465 // Same field. |
| 3466 EXPECT_EQ(field_b.raw(), field_b_from_index.raw()); | 3466 EXPECT_EQ(field_b.raw(), field_b_from_index.raw()); |
| 3467 } | 3467 } |
| 3468 | 3468 |
| 3469 | 3469 |
| 3470 TEST_CASE(FindFunctionIndex) { | 3470 TEST_CASE(FindFunctionIndex) { |
| 3471 // Tests both FindFunctionIndex and FindImplicitClosureFunctionIndex. | |
|
Ivan Posva
2014/01/03 01:52:17
Can you add the dispatcher lookups to the tests as
Cutch
2014/01/03 16:01:56
Done.
| |
| 3471 const char* kScriptChars = | 3472 const char* kScriptChars = |
| 3472 "class A {\n" | 3473 "class A {\n" |
| 3473 " void a() {}\n" | 3474 " void a() {}\n" |
| 3474 " void b() {}\n" | 3475 " void b() { return a; }\n" |
| 3475 "}\n" | 3476 "}\n" |
| 3476 "class B {\n" | 3477 "class B {\n" |
| 3477 " dynamic d() {}\n" | 3478 " dynamic d() {}\n" |
| 3478 "}\n" | 3479 "}\n" |
| 3480 "var x;\n" | |
| 3479 "test() {\n" | 3481 "test() {\n" |
| 3480 " new A();\n" | 3482 " x = new A().b();\n" |
| 3483 " x();\n" | |
| 3481 " new B();\n" | 3484 " new B();\n" |
| 3485 " return x;\n" | |
| 3482 "}"; | 3486 "}"; |
| 3483 Dart_Handle h_lib = TestCase::LoadTestScript(kScriptChars, NULL); | 3487 Dart_Handle h_lib = TestCase::LoadTestScript(kScriptChars, NULL); |
| 3484 EXPECT_VALID(h_lib); | 3488 EXPECT_VALID(h_lib); |
| 3485 Dart_Handle result = Dart_Invoke(h_lib, NewString("test"), 0, NULL); | 3489 Dart_Handle result = Dart_Invoke(h_lib, NewString("test"), 0, NULL); |
| 3486 EXPECT_VALID(result); | 3490 EXPECT_VALID(result); |
| 3487 Library& lib = Library::Handle(); | 3491 Library& lib = Library::Handle(); |
| 3488 lib ^= Api::UnwrapHandle(h_lib); | 3492 lib ^= Api::UnwrapHandle(h_lib); |
| 3489 EXPECT(!lib.IsNull()); | 3493 EXPECT(!lib.IsNull()); |
| 3490 const Class& class_a = Class::Handle(GetClass(lib, "A")); | 3494 const Class& class_a = Class::Handle(GetClass(lib, "A")); |
| 3491 const Array& class_a_funcs = Array::Handle(class_a.functions()); | 3495 const Array& class_a_funcs = Array::Handle(class_a.functions()); |
| 3492 const Class& class_b = Class::Handle(GetClass(lib, "B")); | 3496 const Class& class_b = Class::Handle(GetClass(lib, "B")); |
| 3493 const Function& func_a = Function::Handle(GetFunction(class_a, "a")); | 3497 const Function& func_a = Function::Handle(GetFunction(class_a, "a")); |
| 3494 const Function& func_b = Function::Handle(GetFunction(class_a, "b")); | 3498 const Function& func_b = Function::Handle(GetFunction(class_a, "b")); |
| 3495 const Function& func_d = Function::Handle(GetFunction(class_b, "d")); | 3499 const Function& func_d = Function::Handle(GetFunction(class_b, "d")); |
| 3500 EXPECT(func_a.HasImplicitClosureFunction()); | |
| 3501 const Function& func_x = Function::Handle(func_a.ImplicitClosureFunction()); | |
| 3496 intptr_t func_a_index = class_a.FindFunctionIndex(func_a); | 3502 intptr_t func_a_index = class_a.FindFunctionIndex(func_a); |
| 3497 intptr_t func_b_index = class_a.FindFunctionIndex(func_b); | 3503 intptr_t func_b_index = class_a.FindFunctionIndex(func_b); |
| 3498 intptr_t func_d_index = class_a.FindFunctionIndex(func_d); | 3504 intptr_t func_d_index = class_a.FindFunctionIndex(func_d); |
| 3505 intptr_t func_x_index = class_a.FindImplicitClosureFunctionIndex(func_x); | |
| 3499 // Valid index. | 3506 // Valid index. |
| 3500 EXPECT_GE(func_a_index, 0); | 3507 EXPECT_GE(func_a_index, 0); |
| 3501 // Valid index. | 3508 // Valid index. |
| 3502 EXPECT_GE(func_b_index, 0); | 3509 EXPECT_GE(func_b_index, 0); |
| 3503 // Invalid index. | 3510 // Invalid index. |
| 3504 EXPECT_EQ(func_d_index, -1); | 3511 EXPECT_EQ(func_d_index, -1); |
| 3512 // Valid index. | |
| 3513 EXPECT_GE(func_x_index, 0); | |
| 3505 Function& func_a_from_index = Function::Handle(); | 3514 Function& func_a_from_index = Function::Handle(); |
| 3506 func_a_from_index ^= class_a_funcs.At(func_a_index); | 3515 func_a_from_index ^= class_a_funcs.At(func_a_index); |
| 3507 ASSERT(!func_a_from_index.IsNull()); | 3516 EXPECT(!func_a_from_index.IsNull()); |
| 3508 // Same function. | 3517 // Same function. |
| 3509 EXPECT_EQ(func_a.raw(), func_a_from_index.raw()); | 3518 EXPECT_EQ(func_a.raw(), func_a_from_index.raw()); |
| 3510 Function& func_b_from_index = Function::Handle(); | 3519 Function& func_b_from_index = Function::Handle(); |
| 3511 func_b_from_index ^= class_a_funcs.At(func_b_index); | 3520 func_b_from_index ^= class_a_funcs.At(func_b_index); |
| 3512 ASSERT(!func_b_from_index.IsNull()); | 3521 EXPECT(!func_b_from_index.IsNull()); |
| 3513 // Same function. | 3522 // Same function. |
| 3514 EXPECT_EQ(func_b.raw(), func_b_from_index.raw()); | 3523 EXPECT_EQ(func_b.raw(), func_b_from_index.raw()); |
| 3524 // Retrieve function a from x's index. | |
| 3525 func_a_from_index ^= class_a_funcs.At(func_x_index); | |
| 3526 EXPECT_EQ(func_a.raw(), func_a_from_index.raw()); | |
| 3527 EXPECT(func_a.HasImplicitClosureFunction()); | |
| 3528 Function& func_x_from_index = Function::Handle(); | |
| 3529 func_x_from_index ^= func_a_from_index.ImplicitClosureFunction(); | |
| 3530 EXPECT_EQ(func_x.raw(), func_x_from_index.raw()); | |
| 3515 } | 3531 } |
| 3516 | 3532 |
| 3517 | 3533 |
| 3518 TEST_CASE(FindClosureIndex) { | 3534 TEST_CASE(FindClosureIndex) { |
| 3519 // Allocate the class first. | 3535 // Allocate the class first. |
| 3520 const String& class_name = String::Handle(Symbols::New("MyClass")); | 3536 const String& class_name = String::Handle(Symbols::New("MyClass")); |
| 3521 const Script& script = Script::Handle(); | 3537 const Script& script = Script::Handle(); |
| 3522 const Class& cls = Class::Handle(CreateDummyClass(class_name, script)); | 3538 const Class& cls = Class::Handle(CreateDummyClass(class_name, script)); |
| 3523 const Array& functions = Array::Handle(Array::New(1)); | 3539 const Array& functions = Array::Handle(Array::New(1)); |
| 3524 | 3540 |
| 3525 Function& parent = Function::Handle(); | 3541 Function& parent = Function::Handle(); |
| 3526 const String& parent_name = String::Handle(Symbols::New("foo_papa")); | 3542 const String& parent_name = String::Handle(Symbols::New("foo_papa")); |
| 3527 parent = Function::New(parent_name, RawFunction::kRegularFunction, | 3543 parent = Function::New(parent_name, RawFunction::kRegularFunction, |
| 3528 false, false, false, false, false, cls, 0); | 3544 false, false, false, false, false, cls, 0); |
| 3529 functions.SetAt(0, parent); | 3545 functions.SetAt(0, parent); |
| 3530 cls.SetFunctions(functions); | 3546 cls.SetFunctions(functions); |
| 3531 | 3547 |
| 3532 Function& function = Function::Handle(); | 3548 Function& function = Function::Handle(); |
| 3533 const String& function_name = String::Handle(Symbols::New("foo")); | 3549 const String& function_name = String::Handle(Symbols::New("foo")); |
| 3534 function = Function::NewClosureFunction(function_name, parent, 0); | 3550 function = Function::NewClosureFunction(function_name, parent, 0); |
| 3535 // Add closure function to class. | 3551 // Add closure function to class. |
| 3536 cls.AddClosureFunction(function); | 3552 cls.AddClosureFunction(function); |
| 3537 | 3553 |
| 3538 // Token position 0 should return a valid index. | 3554 // The closure should return a valid index. |
| 3539 intptr_t good_closure_index = cls.FindClosureIndex(0); | 3555 intptr_t good_closure_index = cls.FindClosureIndex(function); |
| 3540 EXPECT_GE(good_closure_index, 0); | 3556 EXPECT_GE(good_closure_index, 0); |
| 3541 // Token position 1 should return an invalid index. | 3557 // The parent function should return an invalid index. |
| 3542 intptr_t bad_closure_index = cls.FindClosureIndex(1); | 3558 intptr_t bad_closure_index = cls.FindClosureIndex(parent); |
| 3543 EXPECT_EQ(bad_closure_index, -1); | 3559 EXPECT_EQ(bad_closure_index, -1); |
| 3544 | 3560 |
| 3545 // Retrieve closure function via index. | 3561 // Retrieve closure function via index. |
| 3546 const GrowableObjectArray& closures = GrowableObjectArray::Handle( | 3562 const GrowableObjectArray& closures = GrowableObjectArray::Handle( |
| 3547 cls.closures()); | 3563 cls.closures()); |
| 3548 Function& func_from_index = Function::Handle(); | 3564 Function& func_from_index = Function::Handle(); |
| 3549 func_from_index ^= closures.At(good_closure_index); | 3565 func_from_index ^= closures.At(good_closure_index); |
| 3550 | 3566 |
| 3551 // Same closure function. | 3567 // Same closure function. |
| 3552 EXPECT_EQ(func_from_index.raw(), function.raw()); | 3568 EXPECT_EQ(func_from_index.raw(), function.raw()); |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3929 // Simple map. | 3945 // Simple map. |
| 3930 // | 3946 // |
| 3931 // TODO(turnidge): Consider showing something like: {1: 2, 2: 'otter'} | 3947 // TODO(turnidge): Consider showing something like: {1: 2, 2: 'otter'} |
| 3932 result = Dart_GetField(lib, NewString("simple_map")); | 3948 result = Dart_GetField(lib, NewString("simple_map")); |
| 3933 EXPECT_VALID(result); | 3949 EXPECT_VALID(result); |
| 3934 obj ^= Api::UnwrapHandle(result); | 3950 obj ^= Api::UnwrapHandle(result); |
| 3935 EXPECT_STREQ("Instance of '_LinkedHashMap'", obj.ToUserCString()); | 3951 EXPECT_STREQ("Instance of '_LinkedHashMap'", obj.ToUserCString()); |
| 3936 } | 3952 } |
| 3937 | 3953 |
| 3938 } // namespace dart | 3954 } // namespace dart |
| OLD | NEW |