Upgrade V8 to 5.1.281.57 DO NOT MERGE
FPIIM-449
Change-Id: Id981b686b4d587ac31697662eb98bb34be42ad90
(cherry picked from commit 3b9bc31999c9787eb726ecdbfd5796bfdec32a18)
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index f4e8fe8..220b0cd 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -2989,7 +2989,6 @@
THREADED_TEST(PrivatePropertiesOnProxies) {
- i::FLAG_harmony_proxies = true;
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
@@ -12898,6 +12897,19 @@
CHECK(try_catch.HasCaught());
try_catch.Reset();
CHECK(result.IsEmpty());
+
+ Local<Object> target = CompileRun("({})").As<Object>();
+ Local<Object> handler = CompileRun("({})").As<Object>();
+ Local<v8::Proxy> proxy =
+ v8::Proxy::New(context.local(), target, handler).ToLocalChecked();
+
+ result = target->GetRealNamedProperty(context.local(), v8_str("f"));
+ CHECK(!try_catch.HasCaught());
+ CHECK(result.IsEmpty());
+
+ result = proxy->GetRealNamedProperty(context.local(), v8_str("f"));
+ CHECK(!try_catch.HasCaught());
+ CHECK(result.IsEmpty());
}
@@ -13076,7 +13088,6 @@
THREADED_TEST(AccessorShouldThrowOnError) {
- i::FLAG_strong_mode = true;
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
@@ -13109,14 +13120,6 @@
value = global->Get(context.local(), v8_str("should_throw_setter"))
.ToLocalChecked();
CHECK(value->IsTrue());
-
- // STRONG mode
- value = v8_compile("'use strong';o.f")->Run(context.local()).ToLocalChecked();
- CHECK(value->IsFalse());
- v8_compile("'use strong'; o.f = 153")->Run(context.local()).ToLocalChecked();
- value = global->Get(context.local(), v8_str("should_throw_setter"))
- .ToLocalChecked();
- CHECK(value->IsTrue());
}
@@ -13172,7 +13175,6 @@
THREADED_TEST(InterceptorShouldThrowOnError) {
- i::FLAG_strong_mode = true;
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
@@ -13229,21 +13231,6 @@
value = global->Get(context.local(), v8_str("should_throw_enumerator"))
.ToLocalChecked();
CHECK(value->IsFalse());
-
- // STRONG mode
- value = v8_compile("'use strong';o.f")->Run(context.local()).ToLocalChecked();
- CHECK(value->IsFalse());
- v8_compile("'use strong'; o.f = 153")->Run(context.local()).ToLocalChecked();
- value = global->Get(context.local(), v8_str("should_throw_setter"))
- .ToLocalChecked();
- CHECK(value->IsTrue());
-
- v8_compile("'use strong'; Object.getOwnPropertyNames(o)")
- ->Run(context.local())
- .ToLocalChecked();
- value = global->Get(context.local(), v8_str("should_throw_enumerator"))
- .ToLocalChecked();
- CHECK(value->IsFalse());
}
@@ -13325,8 +13312,6 @@
TEST(ObjectProtoToStringES6) {
- // TODO(dslomov, caitp): merge into ObjectProtoToString test once shipped.
- i::FLAG_harmony_tostring = true;
LocalContext context;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
@@ -13521,7 +13506,7 @@
"function Child() {};"
"Child.prototype = new Parent();"
"Child.prototype.constructor = Child;"
- "var outer = { inner: function() { } };"
+ "var outer = { inner: (0, function() { }) };"
"var p = new Parent();"
"var c = new Child();"
"var x = new outer.inner();"
@@ -14544,12 +14529,17 @@
static bool FunctionNameIs(const char* expected,
const v8::JitCodeEvent* event) {
// Log lines for functions are of the general form:
- // "LazyCompile:<type><function_name>", where the type is one of
- // "*", "~" or "".
- static const char kPreamble[] = "LazyCompile:";
- static size_t kPreambleLen = sizeof(kPreamble) - 1;
+ // "LazyCompile:<type><function_name>" or Function:<type><function_name>,
+ // where the type is one of "*", "~" or "".
+ static const char* kPreamble;
+ if (!i::FLAG_lazy || (i::FLAG_ignition && i::FLAG_ignition_eager)) {
+ kPreamble = "Function:";
+ } else {
+ kPreamble = "LazyCompile:";
+ }
+ static size_t kPreambleLen = strlen(kPreamble);
- if (event->name.len < sizeof(kPreamble) - 1 ||
+ if (event->name.len < kPreambleLen ||
strncmp(kPreamble, event->name.str, kPreambleLen) != 0) {
return false;
}
@@ -14717,7 +14707,8 @@
for (int i = 0; i < kIterations; ++i) {
LocalContext env(isolate);
i::AlwaysAllocateScope always_allocate(i_isolate);
- SimulateFullSpace(heap->code_space());
+ SimulateFullSpace(i::FLAG_ignition ? heap->old_space()
+ : heap->code_space());
CompileRun(script);
// Keep a strong reference to the code object in the handle scope.
@@ -15158,6 +15149,9 @@
// Tests that ScriptData can be serialized and deserialized.
TEST(PreCompileSerialization) {
+ // Producing cached parser data while parsing eagerly is not supported.
+ if (!i::FLAG_lazy || (i::FLAG_ignition && i::FLAG_ignition_eager)) return;
+
v8::V8::Initialize();
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@@ -18377,6 +18371,7 @@
THREADED_TEST(FunctionGetDebugName) {
+ i::FLAG_harmony_function_name = true;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
const char* code =
@@ -18420,7 +18415,8 @@
"Object.defineProperty(i, 'name', { value: 'function.name' });"
"var j = function() {};"
"Object.defineProperty(j, 'name', { value: 'function.name' });"
- "var foo = { bar : { baz : function() {}}}; var k = foo.bar.baz;";
+ "var foo = { bar : { baz : (0, function() {})}}; var k = foo.bar.baz;"
+ "var foo = { bar : { baz : function() {} }}; var l = foo.bar.baz;";
v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str("test"));
v8::Script::Compile(env.local(), v8_str(code), &origin)
.ToLocalChecked()
@@ -18439,7 +18435,8 @@
"h", "displayName",
"i", "function.name",
"j", "function.name",
- "k", "foo.bar.baz"};
+ "k", "foo.bar.baz",
+ "l", "baz"};
for (size_t i = 0; i < sizeof(functions) / sizeof(functions[0]) / 2; ++i) {
v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
env->Global()
@@ -19915,7 +19912,6 @@
TEST(RegExp) {
- i::FLAG_harmony_regexps = true;
i::FLAG_harmony_unicode_regexps = true;
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
@@ -20571,7 +20567,8 @@
int elements = CountLiveMapsInMapCache(CcTest::i_isolate()->context());
CHECK_LE(1, elements);
- CcTest::heap()->CollectAllGarbage();
+ // We have to abort incremental marking here to abandon black pages.
+ CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
CHECK_GT(elements, CountLiveMapsInMapCache(CcTest::i_isolate()->context()));
}
@@ -20921,12 +20918,16 @@
static void MicrotaskOne(const v8::FunctionCallbackInfo<Value>& info) {
v8::HandleScope scope(info.GetIsolate());
+ v8::MicrotasksScope microtasks(info.GetIsolate(),
+ v8::MicrotasksScope::kDoNotRunMicrotasks);
CompileRun("ext1Calls++;");
}
static void MicrotaskTwo(const v8::FunctionCallbackInfo<Value>& info) {
v8::HandleScope scope(info.GetIsolate());
+ v8::MicrotasksScope microtasks(info.GetIsolate(),
+ v8::MicrotasksScope::kDoNotRunMicrotasks);
CompileRun("ext2Calls++;");
}
@@ -21033,23 +21034,35 @@
}
+uint8_t microtasks_completed_callback_count = 0;
+
+
+static void MicrotasksCompletedCallback(v8::Isolate* isolate) {
+ ++microtasks_completed_callback_count;
+}
+
+
TEST(SetAutorunMicrotasks) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
+ env->GetIsolate()->AddMicrotasksCompletedCallback(
+ &MicrotasksCompletedCallback);
CompileRun(
"var ext1Calls = 0;"
"var ext2Calls = 0;");
CompileRun("1+1;");
CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(0u, microtasks_completed_callback_count);
env->GetIsolate()->EnqueueMicrotask(
Function::New(env.local(), MicrotaskOne).ToLocalChecked());
CompileRun("1+1;");
CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(1u, microtasks_completed_callback_count);
- env->GetIsolate()->SetAutorunMicrotasks(false);
+ env->GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
env->GetIsolate()->EnqueueMicrotask(
Function::New(env.local(), MicrotaskOne).ToLocalChecked());
env->GetIsolate()->EnqueueMicrotask(
@@ -21057,27 +21070,32 @@
CompileRun("1+1;");
CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(1u, microtasks_completed_callback_count);
env->GetIsolate()->RunMicrotasks();
CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(2u, microtasks_completed_callback_count);
env->GetIsolate()->EnqueueMicrotask(
Function::New(env.local(), MicrotaskTwo).ToLocalChecked());
CompileRun("1+1;");
CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(2u, microtasks_completed_callback_count);
env->GetIsolate()->RunMicrotasks();
CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(3u, microtasks_completed_callback_count);
- env->GetIsolate()->SetAutorunMicrotasks(true);
+ env->GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto);
env->GetIsolate()->EnqueueMicrotask(
Function::New(env.local(), MicrotaskTwo).ToLocalChecked());
CompileRun("1+1;");
CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(4u, microtasks_completed_callback_count);
env->GetIsolate()->EnqueueMicrotask(
Function::New(env.local(), MicrotaskTwo).ToLocalChecked());
@@ -21086,18 +21104,29 @@
CompileRun("1+1;");
CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(4u, microtasks_completed_callback_count);
}
CompileRun("1+1;");
CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(4, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(5u, microtasks_completed_callback_count);
+
+ env->GetIsolate()->RemoveMicrotasksCompletedCallback(
+ &MicrotasksCompletedCallback);
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env.local(), MicrotaskOne).ToLocalChecked());
+ CompileRun("1+1;");
+ CHECK_EQ(3, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(4, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(5u, microtasks_completed_callback_count);
}
TEST(RunMicrotasksWithoutEnteringContext) {
v8::Isolate* isolate = CcTest::isolate();
HandleScope handle_scope(isolate);
- isolate->SetAutorunMicrotasks(false);
+ isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
Local<Context> context = Context::New(isolate);
{
Context::Scope context_scope(context);
@@ -21110,7 +21139,147 @@
Context::Scope context_scope(context);
CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(context).FromJust());
}
- isolate->SetAutorunMicrotasks(true);
+ isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto);
+}
+
+
+TEST(ScopedMicrotasks) {
+ LocalContext env;
+ v8::HandleScope handles(env->GetIsolate());
+ env->GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kScoped);
+ {
+ v8::MicrotasksScope scope1(env->GetIsolate(),
+ v8::MicrotasksScope::kDoNotRunMicrotasks);
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env.local(), MicrotaskOne).ToLocalChecked());
+ CompileRun(
+ "var ext1Calls = 0;"
+ "var ext2Calls = 0;");
+ CompileRun("1+1;");
+ CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ {
+ v8::MicrotasksScope scope2(env->GetIsolate(),
+ v8::MicrotasksScope::kRunMicrotasks);
+ CompileRun("1+1;");
+ CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ {
+ v8::MicrotasksScope scope3(env->GetIsolate(),
+ v8::MicrotasksScope::kRunMicrotasks);
+ CompileRun("1+1;");
+ CHECK_EQ(0,
+ CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(0,
+ CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ }
+ CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ }
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env.local(), MicrotaskTwo).ToLocalChecked());
+ }
+
+ {
+ v8::MicrotasksScope scope(env->GetIsolate(),
+ v8::MicrotasksScope::kDoNotRunMicrotasks);
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ }
+
+ {
+ v8::MicrotasksScope scope1(env->GetIsolate(),
+ v8::MicrotasksScope::kRunMicrotasks);
+ CompileRun("1+1;");
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ {
+ v8::MicrotasksScope scope2(env->GetIsolate(),
+ v8::MicrotasksScope::kDoNotRunMicrotasks);
+ }
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ }
+
+ {
+ v8::MicrotasksScope scope(env->GetIsolate(),
+ v8::MicrotasksScope::kDoNotRunMicrotasks);
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env.local(), MicrotaskTwo).ToLocalChecked());
+ }
+
+ {
+ v8::Isolate::SuppressMicrotaskExecutionScope scope1(env->GetIsolate());
+ {
+ v8::MicrotasksScope scope2(env->GetIsolate(),
+ v8::MicrotasksScope::kRunMicrotasks);
+ }
+ v8::MicrotasksScope scope3(env->GetIsolate(),
+ v8::MicrotasksScope::kDoNotRunMicrotasks);
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ }
+
+ {
+ v8::MicrotasksScope scope1(env->GetIsolate(),
+ v8::MicrotasksScope::kRunMicrotasks);
+ v8::MicrotasksScope::PerformCheckpoint(env->GetIsolate());
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ }
+
+ {
+ v8::MicrotasksScope scope(env->GetIsolate(),
+ v8::MicrotasksScope::kDoNotRunMicrotasks);
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ }
+
+ v8::MicrotasksScope::PerformCheckpoint(env->GetIsolate());
+
+ {
+ v8::MicrotasksScope scope(env->GetIsolate(),
+ v8::MicrotasksScope::kDoNotRunMicrotasks);
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env.local(), MicrotaskTwo).ToLocalChecked());
+ }
+
+ v8::MicrotasksScope::PerformCheckpoint(env->GetIsolate());
+
+ {
+ v8::MicrotasksScope scope(env->GetIsolate(),
+ v8::MicrotasksScope::kDoNotRunMicrotasks);
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ }
+
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env.local(), MicrotaskOne).ToLocalChecked());
+ {
+ v8::Isolate::SuppressMicrotaskExecutionScope scope1(env->GetIsolate());
+ v8::MicrotasksScope::PerformCheckpoint(env->GetIsolate());
+ v8::MicrotasksScope scope2(env->GetIsolate(),
+ v8::MicrotasksScope::kDoNotRunMicrotasks);
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ }
+
+ v8::MicrotasksScope::PerformCheckpoint(env->GetIsolate());
+
+ {
+ v8::MicrotasksScope scope(env->GetIsolate(),
+ v8::MicrotasksScope::kDoNotRunMicrotasks);
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
+ CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
+ }
+
+ env->GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto);
}
@@ -21133,7 +21302,7 @@
i::FLAG_allow_natives_syntax = true;
v8::Isolate* isolate = CcTest::isolate();
HandleScope handle_scope(isolate);
- isolate->SetAutorunMicrotasks(false);
+ isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
Local<Context> context = Context::New(isolate);
v8::Debug::SetDebugEventListener(isolate, DebugEventInObserver);
{
@@ -21143,7 +21312,7 @@
"obj.a = 0;");
}
isolate->RunMicrotasks();
- isolate->SetAutorunMicrotasks(true);
+ isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto);
v8::Debug::SetDebugEventListener(isolate, nullptr);
}
@@ -22037,7 +22206,7 @@
CheckCorrectThrow("%DeleteProperty_Strict(other, 'x')");
CheckCorrectThrow("%DeleteProperty_Sloppy(other, '1')");
CheckCorrectThrow("%DeleteProperty_Strict(other, '1')");
- CheckCorrectThrow("%HasOwnProperty(other, 'x')");
+ CheckCorrectThrow("Object.prototype.hasOwnProperty.call(other, 'x')");
CheckCorrectThrow("%HasProperty('x', other)");
CheckCorrectThrow("%PropertyIsEnumerable(other, 'x')");
// PROPERTY_ATTRIBUTES_NONE = 0
@@ -22447,7 +22616,8 @@
->serial_number()),
i_isolate);
auto cache = i_isolate->template_instantiations_cache();
- CHECK(cache->Lookup(serial_number)->IsTheHole());
+ CHECK(cache->FindEntry(static_cast<uint32_t>(serial_number->value())) ==
+ i::UnseededNumberDictionary::kNotFound);
// Verify that each Function::New creates a new function instance
Local<Object> data2 = v8::Object::New(isolate);
function_new_expected_env = data2;
@@ -23912,12 +24082,18 @@
v8::V8::Initialize();
v8::HandleScope scope(CcTest::isolate());
LocalContext context;
- TestInvalidCacheData(v8::ScriptCompiler::kConsumeParserCache);
+ if (i::FLAG_lazy && !(i::FLAG_ignition && i::FLAG_ignition_eager)) {
+ // Cached parser data is not consumed while parsing eagerly.
+ TestInvalidCacheData(v8::ScriptCompiler::kConsumeParserCache);
+ }
TestInvalidCacheData(v8::ScriptCompiler::kConsumeCodeCache);
}
TEST(ParserCacheRejectedGracefully) {
+ // Producing cached parser data while parsing eagerly is not supported.
+ if (!i::FLAG_lazy || (i::FLAG_ignition && i::FLAG_ignition_eager)) return;
+
i::FLAG_min_preparse_length = 0;
v8::V8::Initialize();
v8::HandleScope scope(CcTest::isolate());
@@ -24184,271 +24360,6 @@
}
-static bool access_was_called = false;
-
-static bool AccessAlwaysAllowedWithFlag(Local<v8::Context> accessing_context,
- Local<v8::Object> accessed_object,
- Local<v8::Value> data) {
- access_was_called = true;
- return true;
-}
-
-static bool AccessAlwaysBlockedWithFlag(Local<v8::Context> accessing_context,
- Local<v8::Object> accessed_object,
- Local<v8::Value> data) {
- access_was_called = true;
- return false;
-}
-
-
-TEST(StrongModeAccessCheckAllowed) {
- i::FLAG_strong_mode = true;
- v8::Isolate* isolate = CcTest::isolate();
- v8::HandleScope handle_scope(isolate);
- v8::Local<Value> value;
- access_was_called = false;
-
- v8::Local<v8::ObjectTemplate> obj_template = v8::ObjectTemplate::New(isolate);
-
- obj_template->Set(v8_str("x"), v8::Integer::New(isolate, 42));
- obj_template->SetAccessCheckCallback(AccessAlwaysAllowedWithFlag);
-
- // Create an environment
- v8::Local<Context> context0 = Context::New(isolate, NULL, obj_template);
- context0->Enter();
- v8::Local<v8::Object> global0 = context0->Global();
- global0->Set(context0, v8_str("object"),
- obj_template->NewInstance(context0).ToLocalChecked())
- .FromJust();
- {
- v8::TryCatch try_catch(isolate);
- value = CompileRun("'use strong'; object.x");
- CHECK(!try_catch.HasCaught());
- CHECK(!access_was_called);
- CHECK_EQ(42, value->Int32Value(context0).FromJust());
- }
- {
- v8::TryCatch try_catch(isolate);
- value = CompileRun("'use strong'; object.foo");
- CHECK(try_catch.HasCaught());
- CHECK(!access_was_called);
- }
- {
- v8::TryCatch try_catch(isolate);
- value = CompileRun("'use strong'; object[10]");
- CHECK(try_catch.HasCaught());
- CHECK(!access_was_called);
- }
-
- // Create an environment
- v8::Local<Context> context1 = Context::New(isolate);
- context1->Enter();
- v8::Local<v8::Object> global1 = context1->Global();
- global1->Set(context1, v8_str("object"),
- obj_template->NewInstance(context1).ToLocalChecked())
- .FromJust();
- {
- v8::TryCatch try_catch(isolate);
- value = CompileRun("'use strong'; object.x");
- CHECK(!try_catch.HasCaught());
- CHECK(access_was_called);
- CHECK_EQ(42, value->Int32Value(context1).FromJust());
- }
- access_was_called = false;
- {
- v8::TryCatch try_catch(isolate);
- value = CompileRun("'use strong'; object.foo");
- CHECK(try_catch.HasCaught());
- CHECK(access_was_called);
- }
- access_was_called = false;
- {
- v8::TryCatch try_catch(isolate);
- value = CompileRun("'use strong'; object[10]");
- CHECK(try_catch.HasCaught());
- CHECK(access_was_called);
- }
-
- context1->Exit();
- context0->Exit();
-}
-
-
-TEST(StrongModeAccessCheckBlocked) {
- i::FLAG_strong_mode = true;
- v8::Isolate* isolate = CcTest::isolate();
- v8::HandleScope handle_scope(isolate);
- v8::Local<Value> value;
- access_was_called = false;
-
- v8::Local<v8::ObjectTemplate> obj_template = v8::ObjectTemplate::New(isolate);
-
- obj_template->Set(v8_str("x"), v8::Integer::New(isolate, 42));
- obj_template->SetAccessCheckCallback(AccessAlwaysBlockedWithFlag);
-
- // Create an environment
- v8::Local<Context> context0 = Context::New(isolate, NULL, obj_template);
- context0->Enter();
- v8::Local<v8::Object> global0 = context0->Global();
- global0->Set(context0, v8_str("object"),
- obj_template->NewInstance(context0).ToLocalChecked())
- .FromJust();
- {
- v8::TryCatch try_catch(isolate);
- value = CompileRun("'use strong'; object.x");
- CHECK(!try_catch.HasCaught());
- CHECK(!access_was_called);
- CHECK_EQ(42, value->Int32Value(context0).FromJust());
- }
- {
- v8::TryCatch try_catch(isolate);
- value = CompileRun("'use strong'; object.foo");
- CHECK(try_catch.HasCaught());
- CHECK(!access_was_called);
- }
- {
- v8::TryCatch try_catch(isolate);
- value = CompileRun("'use strong'; object[10]");
- CHECK(try_catch.HasCaught());
- CHECK(!access_was_called);
- }
-
- // Create an environment
- v8::Local<Context> context1 = Context::New(isolate);
- context1->Enter();
- v8::Local<v8::Object> global1 = context1->Global();
- global1->Set(context1, v8_str("object"),
- obj_template->NewInstance(context1).ToLocalChecked())
- .FromJust();
- {
- v8::TryCatch try_catch(isolate);
- value = CompileRun("'use strong'; object.x");
- CHECK(try_catch.HasCaught());
- CHECK(access_was_called);
- }
- access_was_called = false;
- {
- v8::TryCatch try_catch(isolate);
- value = CompileRun("'use strong'; object.foo");
- CHECK(try_catch.HasCaught());
- CHECK(access_was_called);
- }
- access_was_called = false;
- {
- v8::TryCatch try_catch(isolate);
- value = CompileRun("'use strong'; object[10]");
- CHECK(try_catch.HasCaught());
- CHECK(access_was_called);
- }
-
- context1->Exit();
- context0->Exit();
-}
-
-
-TEST(StrongModeArityCallFromApi) {
- i::FLAG_strong_mode = true;
- LocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope scope(isolate);
- Local<Function> fun;
- {
- v8::TryCatch try_catch(isolate);
- fun = Local<Function>::Cast(CompileRun(
- "function f(x) { 'use strong'; }"
- "f"));
-
- CHECK(!try_catch.HasCaught());
- }
-
- {
- v8::TryCatch try_catch(isolate);
- CHECK(fun->Call(env.local(), v8::Undefined(isolate), 0, nullptr).IsEmpty());
- CHECK(try_catch.HasCaught());
- }
-
- {
- v8::TryCatch try_catch(isolate);
- v8::Local<Value> args[] = {v8_num(42)};
- fun->Call(env.local(), v8::Undefined(isolate), arraysize(args), args)
- .ToLocalChecked();
- CHECK(!try_catch.HasCaught());
- }
-
- {
- v8::TryCatch try_catch(isolate);
- v8::Local<Value> args[] = {v8_num(42), v8_num(555)};
- fun->Call(env.local(), v8::Undefined(isolate), arraysize(args), args)
- .ToLocalChecked();
- CHECK(!try_catch.HasCaught());
- }
-}
-
-
-TEST(StrongModeArityCallFromApi2) {
- i::FLAG_strong_mode = true;
- LocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope scope(isolate);
- Local<Function> fun;
- {
- v8::TryCatch try_catch(isolate);
- fun = Local<Function>::Cast(CompileRun(
- "'use strong';"
- "function f(x) {}"
- "f"));
-
- CHECK(!try_catch.HasCaught());
- }
-
- {
- v8::TryCatch try_catch(isolate);
- CHECK(fun->Call(env.local(), v8::Undefined(isolate), 0, nullptr).IsEmpty());
- CHECK(try_catch.HasCaught());
- }
-
- {
- v8::TryCatch try_catch(isolate);
- v8::Local<Value> args[] = {v8_num(42)};
- fun->Call(env.local(), v8::Undefined(isolate), arraysize(args), args)
- .ToLocalChecked();
- CHECK(!try_catch.HasCaught());
- }
-
- {
- v8::TryCatch try_catch(isolate);
- v8::Local<Value> args[] = {v8_num(42), v8_num(555)};
- fun->Call(env.local(), v8::Undefined(isolate), arraysize(args), args)
- .ToLocalChecked();
- CHECK(!try_catch.HasCaught());
- }
-}
-
-
-TEST(StrongObjectDelete) {
- i::FLAG_strong_mode = true;
- LocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope scope(isolate);
- Local<Object> obj;
- {
- v8::TryCatch try_catch(isolate);
- obj = Local<Object>::Cast(CompileRun(
- "'use strong';"
- "({});"));
- CHECK(!try_catch.HasCaught());
- }
- obj->DefineOwnProperty(env.local(), v8_str("foo"), v8_num(1), v8::None)
- .FromJust();
- obj->DefineOwnProperty(env.local(), v8_str("2"), v8_num(1), v8::None)
- .FromJust();
- CHECK(obj->HasOwnProperty(env.local(), v8_str("foo")).FromJust());
- CHECK(obj->HasOwnProperty(env.local(), v8_str("2")).FromJust());
- CHECK(!obj->Delete(env.local(), v8_str("foo")).FromJust());
- CHECK(!obj->Delete(env.local(), 2).FromJust());
-}
-
-
static void ExtrasBindingTestRuntimeFunction(
const v8::FunctionCallbackInfo<v8::Value>& args) {
CHECK_EQ(
@@ -24760,6 +24671,53 @@
0);
}
+THREADED_TEST(ReceiverConversionForAccessors) {
+ LocalContext env;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<v8::FunctionTemplate> acc =
+ v8::FunctionTemplate::New(isolate, Returns42);
+ CHECK(env->Global()
+ ->Set(env.local(), v8_str("acc"),
+ acc->GetFunction(env.local()).ToLocalChecked())
+ .FromJust());
+
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
+ templ->SetAccessorProperty(v8_str("acc"), acc, acc);
+ Local<v8::Object> instance = templ->NewInstance(env.local()).ToLocalChecked();
+
+ CHECK(env->Global()->Set(env.local(), v8_str("p"), instance).FromJust());
+ CHECK(CompileRun("(p.acc == 42)")->BooleanValue(env.local()).FromJust());
+ CHECK(CompileRun("(p.acc = 7) == 7")->BooleanValue(env.local()).FromJust());
+
+ CHECK(!CompileRun("Number.prototype.__proto__ = p;"
+ "var a = 1;")
+ .IsEmpty());
+ CHECK(CompileRun("(a.acc == 42)")->BooleanValue(env.local()).FromJust());
+ CHECK(CompileRun("(a.acc = 7) == 7")->BooleanValue(env.local()).FromJust());
+
+ CHECK(!CompileRun("Boolean.prototype.__proto__ = p;"
+ "var a = true;")
+ .IsEmpty());
+ CHECK(CompileRun("(a.acc == 42)")->BooleanValue(env.local()).FromJust());
+ CHECK(CompileRun("(a.acc = 7) == 7")->BooleanValue(env.local()).FromJust());
+
+ CHECK(!CompileRun("String.prototype.__proto__ = p;"
+ "var a = 'foo';")
+ .IsEmpty());
+ CHECK(CompileRun("(a.acc == 42)")->BooleanValue(env.local()).FromJust());
+ CHECK(CompileRun("(a.acc = 7) == 7")->BooleanValue(env.local()).FromJust());
+
+ CHECK(CompileRun("acc.call(1) == 42")->BooleanValue(env.local()).FromJust());
+ CHECK(CompileRun("acc.call(true)==42")->BooleanValue(env.local()).FromJust());
+ CHECK(CompileRun("acc.call('aa')==42")->BooleanValue(env.local()).FromJust());
+ CHECK(
+ CompileRun("acc.call(null) == 42")->BooleanValue(env.local()).FromJust());
+ CHECK(CompileRun("acc.call(undefined) == 42")
+ ->BooleanValue(env.local())
+ .FromJust());
+}
+
class FutexInterruptionThread : public v8::base::Thread {
public:
explicit FutexInterruptionThread(v8::Isolate* isolate)
@@ -24873,7 +24831,6 @@
TEST(AccessCheckedToStringTag) {
- i::FLAG_harmony_tostring = true;
v8::Isolate* isolate = CcTest::isolate();
HandleScope scope(isolate);
LocalContext env;
@@ -24952,7 +24909,6 @@
TEST(Proxy) {
- i::FLAG_harmony_proxies = true;
LocalContext context;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
@@ -24974,3 +24930,98 @@
CHECK(proxy->GetTarget()->SameValue(target));
CHECK(proxy->GetHandler()->IsNull());
}
+
+WeakCallCounterAndPersistent<Value>* CreateGarbageWithWeakCallCounter(
+ v8::Isolate* isolate, WeakCallCounter* counter) {
+ v8::Locker locker(isolate);
+ LocalContext env;
+ HandleScope scope(isolate);
+ WeakCallCounterAndPersistent<Value>* val =
+ new WeakCallCounterAndPersistent<Value>(counter);
+ val->handle.Reset(isolate, Object::New(isolate));
+ val->handle.SetWeak(val, &WeakPointerCallback,
+ v8::WeakCallbackType::kParameter);
+ return val;
+}
+
+class MemoryPressureThread : public v8::base::Thread {
+ public:
+ explicit MemoryPressureThread(v8::Isolate* isolate,
+ v8::MemoryPressureLevel level)
+ : Thread(Options("MemoryPressureThread")),
+ isolate_(isolate),
+ level_(level) {}
+
+ virtual void Run() { isolate_->MemoryPressureNotification(level_); }
+
+ private:
+ v8::Isolate* isolate_;
+ v8::MemoryPressureLevel level_;
+};
+
+TEST(MemoryPressure) {
+ v8::Isolate* isolate = CcTest::isolate();
+ WeakCallCounter counter(1234);
+
+ // Check that critical memory pressure notification sets GC interrupt.
+ auto garbage = CreateGarbageWithWeakCallCounter(isolate, &counter);
+ CHECK(!v8::Locker::IsLocked(isolate));
+ {
+ v8::Locker locker(isolate);
+ v8::HandleScope scope(isolate);
+ LocalContext env;
+ MemoryPressureThread memory_pressure_thread(
+ isolate, v8::MemoryPressureLevel::kCritical);
+ memory_pressure_thread.Start();
+ memory_pressure_thread.Join();
+ // This should trigger GC.
+ CHECK_EQ(0, counter.NumberOfWeakCalls());
+ CompileRun("(function noop() { return 0; })()");
+ CHECK_EQ(1, counter.NumberOfWeakCalls());
+ }
+ delete garbage;
+ // Check that critical memory pressure notification triggers GC.
+ garbage = CreateGarbageWithWeakCallCounter(isolate, &counter);
+ {
+ v8::Locker locker(isolate);
+ // If isolate is locked, memory pressure notification should trigger GC.
+ CHECK_EQ(1, counter.NumberOfWeakCalls());
+ isolate->MemoryPressureNotification(v8::MemoryPressureLevel::kCritical);
+ CHECK_EQ(2, counter.NumberOfWeakCalls());
+ }
+ delete garbage;
+ // Check that moderate memory pressure notification sets GC into memory
+ // optimizing mode.
+ isolate->MemoryPressureNotification(v8::MemoryPressureLevel::kModerate);
+ CHECK(CcTest::i_isolate()->heap()->ShouldOptimizeForMemoryUsage());
+ // Check that disabling memory pressure returns GC into normal mode.
+ isolate->MemoryPressureNotification(v8::MemoryPressureLevel::kNone);
+ CHECK(!CcTest::i_isolate()->heap()->ShouldOptimizeForMemoryUsage());
+}
+
+TEST(SetIntegrityLevel) {
+ LocalContext context;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+
+ v8::Local<v8::Object> obj = v8::Object::New(isolate);
+ CHECK(context->Global()->Set(context.local(), v8_str("o"), obj).FromJust());
+
+ v8::Local<v8::Value> is_frozen = CompileRun("Object.isFrozen(o)");
+ CHECK(!is_frozen->BooleanValue(context.local()).FromJust());
+
+ CHECK(obj->SetIntegrityLevel(context.local(), v8::IntegrityLevel::kFrozen)
+ .FromJust());
+
+ is_frozen = CompileRun("Object.isFrozen(o)");
+ CHECK(is_frozen->BooleanValue(context.local()).FromJust());
+}
+
+TEST(PrivateForApiIsNumber) {
+ LocalContext context;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+
+ // Shouldn't crash.
+ v8::Private::ForApi(isolate, v8_str("42"));
+}