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 |