diff options
author | Myles Borins <mylesborins@google.com> | 2019-09-24 11:56:38 -0400 |
---|---|---|
committer | Myles Borins <myles.borins@gmail.com> | 2019-10-07 03:19:23 -0400 |
commit | f7f6c928c1c9c136b7926f892b8a2fda11d8b4b2 (patch) | |
tree | f5edbccb3ffda2573d70a6e291e7157f290e0ae0 /deps/v8/test/unittests/api/access-check-unittest.cc | |
parent | ffd22e81983056d09c064c59343a0e488236272d (diff) | |
download | android-node-v8-f7f6c928c1c9c136b7926f892b8a2fda11d8b4b2.tar.gz android-node-v8-f7f6c928c1c9c136b7926f892b8a2fda11d8b4b2.tar.bz2 android-node-v8-f7f6c928c1c9c136b7926f892b8a2fda11d8b4b2.zip |
deps: update V8 to 7.8.279.9
PR-URL: https://github.com/nodejs/node/pull/29694
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Diffstat (limited to 'deps/v8/test/unittests/api/access-check-unittest.cc')
-rw-r--r-- | deps/v8/test/unittests/api/access-check-unittest.cc | 132 |
1 files changed, 118 insertions, 14 deletions
diff --git a/deps/v8/test/unittests/api/access-check-unittest.cc b/deps/v8/test/unittests/api/access-check-unittest.cc index 65e20d2510..3b63666f4b 100644 --- a/deps/v8/test/unittests/api/access-check-unittest.cc +++ b/deps/v8/test/unittests/api/access-check-unittest.cc @@ -27,6 +27,12 @@ MaybeLocal<Value> CompileRun(Isolate* isolate, const char* source) { return script->Run(context); } +v8::Local<v8::String> v8_str(const char* x) { + return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), x, + v8::NewStringType::kNormal) + .ToLocalChecked(); +} + } // namespace TEST_F(AccessCheckTest, GetOwnPropertyDescriptor) { @@ -42,10 +48,8 @@ TEST_F(AccessCheckTest, GetOwnPropertyDescriptor) { Local<FunctionTemplate> setter_template = FunctionTemplate::New( isolate(), [](const FunctionCallbackInfo<v8::Value>& info) { FAIL(); }); setter_template->SetAcceptAnyReceiver(false); - global_template->SetAccessorProperty( - String::NewFromUtf8(isolate(), "property", NewStringType::kNormal) - .ToLocalChecked(), - getter_template, setter_template); + global_template->SetAccessorProperty(v8_str("property"), getter_template, + setter_template); Local<Context> target_context = Context::New(isolate(), nullptr, global_template); @@ -53,10 +57,7 @@ TEST_F(AccessCheckTest, GetOwnPropertyDescriptor) { Context::New(isolate(), nullptr, global_template); accessing_context->Global() - ->Set(accessing_context, - String::NewFromUtf8(isolate(), "other", NewStringType::kNormal) - .ToLocalChecked(), - target_context->Global()) + ->Set(accessing_context, v8_str("other"), target_context->Global()) .FromJust(); Context::Scope context_scope(accessing_context); @@ -71,15 +72,118 @@ TEST_F(AccessCheckTest, GetOwnPropertyDescriptor) { " .set.call(other, 42);"); } -namespace { -bool failed_access_check_callback_called; +class AccessRegressionTest : public AccessCheckTest { + protected: + i::Handle<i::JSFunction> RetrieveFunctionFrom(Local<Context> context, + const char* script) { + Context::Scope context_scope(context); + Local<Value> getter = CompileRun(isolate(), script).ToLocalChecked(); + EXPECT_TRUE(getter->IsFunction()); + + i::Handle<i::JSReceiver> r = + Utils::OpenHandle(*Local<Function>::Cast(getter)); + EXPECT_TRUE(r->IsJSFunction()); + return i::Handle<i::JSFunction>::cast(r); + } +}; -v8::Local<v8::String> v8_str(const char* x) { - return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), x, - v8::NewStringType::kNormal) - .ToLocalChecked(); +TEST_F(AccessRegressionTest, + InstantiatedLazyAccessorPairsHaveCorrectNativeContext) { + // The setup creates two contexts and sets an object created + // in context 1 on the global of context 2. + // The object has an accessor pair {property}. Accessing the + // property descriptor of {property} causes instantiation of the + // accessor pair. The test checks that the access pair has the + // correct native context. + Local<FunctionTemplate> getter_template = FunctionTemplate::New( + isolate(), [](const FunctionCallbackInfo<Value>&) { FAIL(); }); + Local<FunctionTemplate> setter_template = FunctionTemplate::New( + isolate(), [](const FunctionCallbackInfo<v8::Value>&) { FAIL(); }); + + Local<ObjectTemplate> object_template = ObjectTemplate::New(isolate()); + object_template->SetAccessorProperty(v8_str("property"), getter_template, + setter_template); + + Local<Context> context1 = Context::New(isolate(), nullptr); + Local<Context> context2 = Context::New(isolate(), nullptr); + + Local<Object> object = + object_template->NewInstance(context1).ToLocalChecked(); + context2->Global() + ->Set(context2, v8_str("object_from_context1"), object) + .Check(); + + i::Handle<i::JSFunction> getter = RetrieveFunctionFrom( + context2, + "Object.getOwnPropertyDescriptor(object_from_context1, 'property').get"); + + ASSERT_EQ(getter->native_context(), *Utils::OpenHandle(*context1)); +} + +// Regression test for https://crbug.com/986063. +TEST_F(AccessRegressionTest, + InstantiatedLazyAccessorPairsHaveCorrectNativeContextDebug) { + // The setup creates two contexts and installs an object "object" + // on the global this for each context. + // The object consists of: + // - an accessor pair "property". + // - a normal function "breakfn". + // + // The test sets a break point on {object.breakfn} in the first context. + // This forces instantation of the JSFunction for the {object.property} + // accessor pair. The test verifies afterwards that the respective + // JSFunction of the getter have the correct native context. + + Local<FunctionTemplate> getter_template = FunctionTemplate::New( + isolate(), [](const FunctionCallbackInfo<Value>&) { FAIL(); }); + Local<FunctionTemplate> setter_template = FunctionTemplate::New( + isolate(), [](const FunctionCallbackInfo<v8::Value>&) { FAIL(); }); + Local<FunctionTemplate> break_template = FunctionTemplate::New( + isolate(), [](const FunctionCallbackInfo<v8::Value>&) { FAIL(); }); + + Local<Context> context1 = Context::New(isolate(), nullptr); + Local<Context> context2 = Context::New(isolate(), nullptr); + + Local<ObjectTemplate> object_template = ObjectTemplate::New(isolate()); + object_template->Set(isolate(), "breakfn", break_template); + object_template->SetAccessorProperty(v8_str("property"), getter_template, + setter_template); + + Local<Object> object1 = + object_template->NewInstance(context1).ToLocalChecked(); + EXPECT_TRUE( + context1->Global()->Set(context1, v8_str("object"), object1).IsJust()); + + Local<Object> object2 = + object_template->NewInstance(context2).ToLocalChecked(); + EXPECT_TRUE( + context2->Global()->Set(context2, v8_str("object"), object2).IsJust()); + + // Force instantiation of the JSFunction for the getter and setter + // of {object.property} by setting a break point on {object.breakfn} + { + Context::Scope context_scope(context1); + i::Isolate* iso = reinterpret_cast<i::Isolate*>(isolate()); + i::Handle<i::JSFunction> break_fn = + RetrieveFunctionFrom(context1, "object.breakfn"); + + int id; + iso->debug()->SetBreakpointForFunction(i::handle(break_fn->shared(), iso), + iso->factory()->empty_string(), &id); + } + + i::Handle<i::JSFunction> getter_c1 = RetrieveFunctionFrom( + context1, "Object.getOwnPropertyDescriptor(object, 'property').get"); + i::Handle<i::JSFunction> getter_c2 = RetrieveFunctionFrom( + context2, "Object.getOwnPropertyDescriptor(object, 'property').get"); + + ASSERT_EQ(getter_c1->native_context(), *Utils::OpenHandle(*context1)); + ASSERT_EQ(getter_c2->native_context(), *Utils::OpenHandle(*context2)); } +namespace { +bool failed_access_check_callback_called; + class AccessCheckTestConsoleDelegate : public debug::ConsoleDelegate { public: void Log(const debug::ConsoleCallArguments& args, |