Index: test/cctest/test-debug.cc |
=================================================================== |
--- test/cctest/test-debug.cc (revision 1124) |
+++ test/cctest/test-debug.cc (working copy) |
@@ -2749,6 +2749,101 @@ |
} |
+TEST(HiddenPrototypePropertyMirror) { |
+ // Create a V8 environment with debug access. |
+ v8::HandleScope scope; |
+ DebugLocalContext env; |
+ env.ExposeDebug(); |
+ |
+ v8::Handle<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(); |
+ t0->InstanceTemplate()->Set(v8::String::New("x"), v8::Number::New(0)); |
+ v8::Handle<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(); |
+ t1->SetHiddenPrototype(true); |
+ t1->InstanceTemplate()->Set(v8::String::New("y"), v8::Number::New(1)); |
+ v8::Handle<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(); |
+ t2->SetHiddenPrototype(true); |
+ t2->InstanceTemplate()->Set(v8::String::New("z"), v8::Number::New(2)); |
+ v8::Handle<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(); |
+ t3->InstanceTemplate()->Set(v8::String::New("u"), v8::Number::New(3)); |
+ |
+ // Create object and set them on the global object. |
+ v8::Handle<v8::Object> o0 = t0->GetFunction()->NewInstance(); |
+ env->Global()->Set(v8::String::New("o0"), o0); |
+ v8::Handle<v8::Object> o1 = t1->GetFunction()->NewInstance(); |
+ env->Global()->Set(v8::String::New("o1"), o1); |
+ v8::Handle<v8::Object> o2 = t2->GetFunction()->NewInstance(); |
+ env->Global()->Set(v8::String::New("o2"), o2); |
+ v8::Handle<v8::Object> o3 = t3->GetFunction()->NewInstance(); |
+ env->Global()->Set(v8::String::New("o3"), o3); |
+ |
+ // Get mirrors for the four objects. |
+ CompileRun( |
+ "o0_mirror = debug.MakeMirror(o0);" |
+ "o1_mirror = debug.MakeMirror(o1);" |
+ "o2_mirror = debug.MakeMirror(o2);" |
+ "o3_mirror = debug.MakeMirror(o3)"); |
+ CHECK(CompileRun("o0_mirror instanceof debug.ObjectMirror")->BooleanValue()); |
+ CHECK(CompileRun("o1_mirror instanceof debug.ObjectMirror")->BooleanValue()); |
+ CHECK(CompileRun("o2_mirror instanceof debug.ObjectMirror")->BooleanValue()); |
+ CHECK(CompileRun("o3_mirror instanceof debug.ObjectMirror")->BooleanValue()); |
+ |
+ // Check that each object has one property. |
+ CHECK_EQ(1, CompileRun( |
+ "o0_mirror.propertyNames().length")->Int32Value()); |
+ CHECK_EQ(1, CompileRun( |
+ "o1_mirror.propertyNames().length")->Int32Value()); |
+ CHECK_EQ(1, CompileRun( |
+ "o2_mirror.propertyNames().length")->Int32Value()); |
+ CHECK_EQ(1, CompileRun( |
+ "o3_mirror.propertyNames().length")->Int32Value()); |
+ |
+ // Set o1 as prototype for o0. o1 has the hidden prototype flag so all |
+ // properties on o1 should be seen on o0. |
+ o0->Set(v8::String::New("__proto__"), o1); |
+ CHECK_EQ(2, CompileRun( |
+ "o0_mirror.propertyNames().length")->Int32Value()); |
+ CHECK_EQ(0, CompileRun( |
+ "o0_mirror.property('x').value().value()")->Int32Value()); |
+ CHECK_EQ(1, CompileRun( |
+ "o0_mirror.property('y').value().value()")->Int32Value()); |
+ |
+ // Set o2 as prototype for o0 (it will end up after o1 as o1 has the hidden |
+ // prototype flag. o2 also has the hidden prototype flag so all properties |
+ // on o2 should be seen on o0 as well as properties on o1. |
+ o0->Set(v8::String::New("__proto__"), o2); |
+ CHECK_EQ(3, CompileRun( |
+ "o0_mirror.propertyNames().length")->Int32Value()); |
+ CHECK_EQ(0, CompileRun( |
+ "o0_mirror.property('x').value().value()")->Int32Value()); |
+ CHECK_EQ(1, CompileRun( |
+ "o0_mirror.property('y').value().value()")->Int32Value()); |
+ CHECK_EQ(2, CompileRun( |
+ "o0_mirror.property('z').value().value()")->Int32Value()); |
+ |
+ // Set o3 as prototype for o0 (it will end up after o1 and o2 as both o1 and |
+ // o2 has the hidden prototype flag. o3 does not have the hidden prototype |
+ // flag so properties on o3 should not be seen on o0 whereas the properties |
+ // from o1 and o2 should still be seen on o0. |
+ // Final prototype chain: o0 -> o1 -> o2 -> o3 |
+ // Hidden prototypes: ^^ ^^ |
+ o0->Set(v8::String::New("__proto__"), o3); |
+ CHECK_EQ(3, CompileRun( |
+ "o0_mirror.propertyNames().length")->Int32Value()); |
+ CHECK_EQ(1, CompileRun( |
+ "o3_mirror.propertyNames().length")->Int32Value()); |
+ CHECK_EQ(0, CompileRun( |
+ "o0_mirror.property('x').value().value()")->Int32Value()); |
+ CHECK_EQ(1, CompileRun( |
+ "o0_mirror.property('y').value().value()")->Int32Value()); |
+ CHECK_EQ(2, CompileRun( |
+ "o0_mirror.property('z').value().value()")->Int32Value()); |
+ CHECK(CompileRun("o0_mirror.property('u').isUndefined()")->BooleanValue()); |
+ |
+ // The prototype (__proto__) for o0 should be o3 as o1 and o2 are hidden. |
+ CHECK(CompileRun("o0_mirror.protoObject() == o3_mirror")->BooleanValue()); |
+} |
+ |
+ |
// Multithreaded tests of JSON debugger protocol |
// Support classes |