| OLD | NEW |
| 1 // Copyright 2017 the V8 project authors. All rights reserved. | 1 // Copyright 2017 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "include/v8.h" | 5 #include "include/v8.h" |
| 6 #include "src/api.h" | |
| 7 #include "src/objects-inl.h" | |
| 8 #include "test/unittests/test-utils.h" | 6 #include "test/unittests/test-utils.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" | 7 #include "testing/gtest/include/gtest/gtest.h" |
| 10 | 8 |
| 11 namespace v8 { | 9 namespace v8 { |
| 12 namespace { | 10 namespace { |
| 13 | 11 |
| 14 using ObjectTest = TestWithContext; | 12 using ObjectTest = TestWithContext; |
| 15 | 13 |
| 16 void accessor_name_getter_callback(Local<Name>, | 14 void accessor_name_getter_callback(Local<Name>, |
| 17 const PropertyCallbackInfo<Value>&) {} | 15 const PropertyCallbackInfo<Value>&) {} |
| (...skipping 10 matching lines...) Expand all Loading... |
| 28 prop_desc.set_configurable(false); | 26 prop_desc.set_configurable(false); |
| 29 global->DefineProperty(context(), property_name, prop_desc).ToChecked(); | 27 global->DefineProperty(context(), property_name, prop_desc).ToChecked(); |
| 30 | 28 |
| 31 Maybe<bool> result = global->SetAccessor(context(), property_name, | 29 Maybe<bool> result = global->SetAccessor(context(), property_name, |
| 32 accessor_name_getter_callback); | 30 accessor_name_getter_callback); |
| 33 ASSERT_TRUE(result.IsJust()); | 31 ASSERT_TRUE(result.IsJust()); |
| 34 ASSERT_FALSE(result.FromJust()); | 32 ASSERT_FALSE(result.FromJust()); |
| 35 ASSERT_FALSE(try_catch.HasCaught()); | 33 ASSERT_FALSE(try_catch.HasCaught()); |
| 36 } | 34 } |
| 37 | 35 |
| 38 using LapContextTest = TestWithIsolate; | |
| 39 | |
| 40 TEST_F(LapContextTest, CurrentContextMustBeFunctionContext) { | |
| 41 // The receiver object is created in |receiver_context|, but its prototype | |
| 42 // object is created in |prototype_context|, and the property is accessed | |
| 43 // from |caller_context|. | |
| 44 Local<Context> receiver_context = Context::New(isolate()); | |
| 45 Local<Context> prototype_context = Context::New(isolate()); | |
| 46 Local<Context> caller_context = Context::New(isolate()); | |
| 47 | |
| 48 Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate()); | |
| 49 Local<Signature> signature = Signature::New(isolate(), function_template); | |
| 50 Local<String> property_key = | |
| 51 String::NewFromUtf8(isolate(), "property", NewStringType::kNormal) | |
| 52 .ToLocalChecked(); | |
| 53 Local<FunctionTemplate> get_or_set = FunctionTemplate::New( | |
| 54 isolate(), | |
| 55 [](const FunctionCallbackInfo<Value>& info) { | |
| 56 Local<Context> prototype_context = *reinterpret_cast<Local<Context>*>( | |
| 57 info.Data().As<External>()->Value()); | |
| 58 EXPECT_EQ(prototype_context, info.GetIsolate()->GetCurrentContext()); | |
| 59 }, | |
| 60 External::New(isolate(), &prototype_context), signature); | |
| 61 function_template->PrototypeTemplate()->SetAccessorProperty( | |
| 62 property_key, get_or_set, get_or_set); | |
| 63 | |
| 64 // |object| is created in |receiver_context|, and |prototype| is created | |
| 65 // in |prototype_context|. And then, object.__proto__ = prototype. | |
| 66 Local<Function> interface_for_receiver = | |
| 67 function_template->GetFunction(receiver_context).ToLocalChecked(); | |
| 68 Local<Function> interface_for_prototype = | |
| 69 function_template->GetFunction(prototype_context).ToLocalChecked(); | |
| 70 Local<String> prototype_key = | |
| 71 String::NewFromUtf8(isolate(), "prototype", NewStringType::kNormal) | |
| 72 .ToLocalChecked(); | |
| 73 Local<Object> prototype = | |
| 74 interface_for_prototype->Get(caller_context, prototype_key) | |
| 75 .ToLocalChecked() | |
| 76 .As<Object>(); | |
| 77 Local<Object> object = | |
| 78 interface_for_receiver->NewInstance(receiver_context).ToLocalChecked(); | |
| 79 object->SetPrototype(caller_context, prototype).ToChecked(); | |
| 80 EXPECT_EQ(receiver_context, object->CreationContext()); | |
| 81 EXPECT_EQ(prototype_context, prototype->CreationContext()); | |
| 82 | |
| 83 object->Get(caller_context, property_key).ToLocalChecked(); | |
| 84 object->Set(caller_context, property_key, Null(isolate())).ToChecked(); | |
| 85 | |
| 86 // Test with a compiled version. | |
| 87 Local<String> object_key = | |
| 88 String::NewFromUtf8(isolate(), "object", NewStringType::kNormal) | |
| 89 .ToLocalChecked(); | |
| 90 caller_context->Global()->Set(caller_context, object_key, object).ToChecked(); | |
| 91 const char script[] = | |
| 92 "function f() { object.property; object.property = 0; } " | |
| 93 "f(); f(); " | |
| 94 "%OptimizeFunctionOnNextCall(f); " | |
| 95 "f();"; | |
| 96 Context::Scope scope(caller_context); | |
| 97 internal::FLAG_allow_natives_syntax = true; | |
| 98 Script::Compile( | |
| 99 caller_context, | |
| 100 String::NewFromUtf8(isolate(), script, v8::NewStringType::kNormal) | |
| 101 .ToLocalChecked()) | |
| 102 .ToLocalChecked() | |
| 103 ->Run(caller_context) | |
| 104 .ToLocalChecked(); | |
| 105 } | |
| 106 | |
| 107 } // namespace | 36 } // namespace |
| 108 } // namespace v8 | 37 } // namespace v8 |
| OLD | NEW |