Merge V8 5.2.361.47 DO NOT MERGE
https://chromium.googlesource.com/v8/v8/+/5.2.361.47
FPIIM-449
Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
(cherry picked from commit bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8)
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 220b0cd..da72ecd 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -2142,6 +2142,95 @@
Constructor_GetFunction_New);
}
+THREADED_TEST(TestObjectTemplateClassInheritance) {
+ LocalContext env;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+
+ Local<v8::FunctionTemplate> fun_A = v8::FunctionTemplate::New(isolate);
+ fun_A->SetClassName(v8_str("A"));
+
+ Local<ObjectTemplate> templ_A = fun_A->InstanceTemplate();
+ templ_A->SetNativeDataProperty(v8_str("nirk"), GetNirk);
+ templ_A->SetNativeDataProperty(v8_str("rino"), GetRino);
+
+ Local<v8::FunctionTemplate> fun_B = v8::FunctionTemplate::New(isolate);
+ v8::Local<v8::String> class_name = v8_str("B");
+ fun_B->SetClassName(class_name);
+ fun_B->Inherit(fun_A);
+
+ v8::Local<v8::String> subclass_name = v8_str("C");
+ v8::Local<v8::Object> b_proto;
+ v8::Local<v8::Object> c_proto;
+ // Perform several iterations to make sure the cache doesn't break
+ // subclassing.
+ for (int i = 0; i < 3; i++) {
+ Local<v8::Function> function_B =
+ fun_B->GetFunction(env.local()).ToLocalChecked();
+ if (i == 0) {
+ CHECK(env->Global()->Set(env.local(), class_name, function_B).FromJust());
+ CompileRun("class C extends B {}");
+ b_proto =
+ CompileRun("B.prototype")->ToObject(env.local()).ToLocalChecked();
+ c_proto =
+ CompileRun("C.prototype")->ToObject(env.local()).ToLocalChecked();
+ CHECK(b_proto->Equals(env.local(), c_proto->GetPrototype()).FromJust());
+ }
+ Local<v8::Object> instance =
+ CompileRun("new C()")->ToObject(env.local()).ToLocalChecked();
+ CHECK(c_proto->Equals(env.local(), instance->GetPrototype()).FromJust());
+
+ CHECK(subclass_name->StrictEquals(instance->GetConstructorName()));
+ CHECK(env->Global()->Set(env.local(), v8_str("o"), instance).FromJust());
+
+ CHECK_EQ(900, CompileRun("o.nirk")->IntegerValue(env.local()).FromJust());
+ CHECK_EQ(560, CompileRun("o.rino")->IntegerValue(env.local()).FromJust());
+ }
+}
+
+static void NamedPropertyGetterWhichReturns42(
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
+ info.GetReturnValue().Set(v8_num(42));
+}
+
+THREADED_TEST(TestObjectTemplateReflectConstruct) {
+ LocalContext env;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+
+ Local<v8::FunctionTemplate> fun_B = v8::FunctionTemplate::New(isolate);
+ fun_B->InstanceTemplate()->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(NamedPropertyGetterWhichReturns42));
+ v8::Local<v8::String> class_name = v8_str("B");
+ fun_B->SetClassName(class_name);
+
+ v8::Local<v8::String> subclass_name = v8_str("C");
+ v8::Local<v8::Object> b_proto;
+ v8::Local<v8::Object> c_proto;
+ // Perform several iterations to make sure the cache doesn't break
+ // subclassing.
+ for (int i = 0; i < 3; i++) {
+ Local<v8::Function> function_B =
+ fun_B->GetFunction(env.local()).ToLocalChecked();
+ if (i == 0) {
+ CHECK(env->Global()->Set(env.local(), class_name, function_B).FromJust());
+ CompileRun("function C() {}");
+ c_proto =
+ CompileRun("C.prototype")->ToObject(env.local()).ToLocalChecked();
+ }
+ Local<v8::Object> instance = CompileRun("Reflect.construct(B, [], C)")
+ ->ToObject(env.local())
+ .ToLocalChecked();
+ CHECK(c_proto->Equals(env.local(), instance->GetPrototype()).FromJust());
+
+ CHECK(subclass_name->StrictEquals(instance->GetConstructorName()));
+ CHECK(env->Global()->Set(env.local(), v8_str("o"), instance).FromJust());
+
+ CHECK_EQ(42, CompileRun("o.nirk")->IntegerValue(env.local()).FromJust());
+ CHECK_EQ(42, CompileRun("o.rino")->IntegerValue(env.local()).FromJust());
+ }
+}
+
static void GetFlabby(const v8::FunctionCallbackInfo<v8::Value>& args) {
ApiTestFuzzer::Fuzz();
args.GetReturnValue().Set(v8_num(17.2));
@@ -4687,126 +4776,6 @@
}
-// TODO(mstarzinger): This should be a THREADED_TEST but causes failures
-// on the buildbots, so was made non-threaded for the time being.
-TEST(ApiObjectGroupsCycleForScavenger) {
- i::FLAG_stress_compaction = false;
- i::FLAG_gc_global = false;
- LocalContext env;
- v8::Isolate* iso = env->GetIsolate();
- HandleScope scope(iso);
-
- WeakCallCounter counter(1234);
-
- WeakCallCounterAndPersistent<Value> g1s1(&counter);
- WeakCallCounterAndPersistent<Value> g1s2(&counter);
- WeakCallCounterAndPersistent<Value> g2s1(&counter);
- WeakCallCounterAndPersistent<Value> g2s2(&counter);
- WeakCallCounterAndPersistent<Value> g3s1(&counter);
- WeakCallCounterAndPersistent<Value> g3s2(&counter);
-
- {
- HandleScope scope(iso);
- g1s1.handle.Reset(iso, Object::New(iso));
- g1s2.handle.Reset(iso, Object::New(iso));
- g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
-
- g2s1.handle.Reset(iso, Object::New(iso));
- g2s2.handle.Reset(iso, Object::New(iso));
- g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
-
- g3s1.handle.Reset(iso, Object::New(iso));
- g3s2.handle.Reset(iso, Object::New(iso));
- g3s1.handle.SetWeak(&g3s1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- g3s2.handle.SetWeak(&g3s2, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- }
-
- // Make a root.
- WeakCallCounterAndPersistent<Value> root(&counter);
- root.handle.Reset(iso, g1s1.handle);
- root.handle.MarkPartiallyDependent();
-
- // Connect groups. We're building the following cycle:
- // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
- // groups.
- {
- HandleScope handle_scope(iso);
- g1s1.handle.MarkPartiallyDependent();
- g1s2.handle.MarkPartiallyDependent();
- g2s1.handle.MarkPartiallyDependent();
- g2s2.handle.MarkPartiallyDependent();
- g3s1.handle.MarkPartiallyDependent();
- g3s2.handle.MarkPartiallyDependent();
- iso->SetObjectGroupId(g1s1.handle, UniqueId(1));
- iso->SetObjectGroupId(g1s2.handle, UniqueId(1));
- Local<Object>::New(iso, g1s1.handle.As<Object>())
- ->Set(env.local(), v8_str("x"), Local<Value>::New(iso, g2s1.handle))
- .FromJust();
- iso->SetObjectGroupId(g2s1.handle, UniqueId(2));
- iso->SetObjectGroupId(g2s2.handle, UniqueId(2));
- Local<Object>::New(iso, g2s1.handle.As<Object>())
- ->Set(env.local(), v8_str("x"), Local<Value>::New(iso, g3s1.handle))
- .FromJust();
- iso->SetObjectGroupId(g3s1.handle, UniqueId(3));
- iso->SetObjectGroupId(g3s2.handle, UniqueId(3));
- Local<Object>::New(iso, g3s1.handle.As<Object>())
- ->Set(env.local(), v8_str("x"), Local<Value>::New(iso, g1s1.handle))
- .FromJust();
- }
-
- v8::internal::Heap* heap =
- reinterpret_cast<v8::internal::Isolate*>(iso)->heap();
- heap->CollectAllGarbage();
-
- // All objects should be alive.
- CHECK_EQ(0, counter.NumberOfWeakCalls());
-
- // Weaken the root.
- root.handle.SetWeak(&root, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- root.handle.MarkPartiallyDependent();
-
- // Groups are deleted, rebuild groups.
- {
- HandleScope handle_scope(iso);
- g1s1.handle.MarkPartiallyDependent();
- g1s2.handle.MarkPartiallyDependent();
- g2s1.handle.MarkPartiallyDependent();
- g2s2.handle.MarkPartiallyDependent();
- g3s1.handle.MarkPartiallyDependent();
- g3s2.handle.MarkPartiallyDependent();
- iso->SetObjectGroupId(g1s1.handle, UniqueId(1));
- iso->SetObjectGroupId(g1s2.handle, UniqueId(1));
- Local<Object>::New(iso, g1s1.handle.As<Object>())
- ->Set(env.local(), v8_str("x"), Local<Value>::New(iso, g2s1.handle))
- .FromJust();
- iso->SetObjectGroupId(g2s1.handle, UniqueId(2));
- iso->SetObjectGroupId(g2s2.handle, UniqueId(2));
- Local<Object>::New(iso, g2s1.handle.As<Object>())
- ->Set(env.local(), v8_str("x"), Local<Value>::New(iso, g3s1.handle))
- .FromJust();
- iso->SetObjectGroupId(g3s1.handle, UniqueId(3));
- iso->SetObjectGroupId(g3s2.handle, UniqueId(3));
- Local<Object>::New(iso, g3s1.handle.As<Object>())
- ->Set(env.local(), v8_str("x"), Local<Value>::New(iso, g1s1.handle))
- .FromJust();
- }
-
- heap->CollectAllGarbage();
-
- // All objects should be gone. 7 global handles in total.
- CHECK_EQ(7, counter.NumberOfWeakCalls());
-}
-
-
THREADED_TEST(ScriptException) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -6511,6 +6480,46 @@
CHECK(!v8::False(isolate)->SameValue(v8::Undefined(isolate)));
}
+THREADED_TEST(TypeOf) {
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(context->GetIsolate());
+
+ Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate);
+ Local<v8::Function> fun = t1->GetFunction(context.local()).ToLocalChecked();
+
+ CHECK(v8::Undefined(isolate)
+ ->TypeOf(isolate)
+ ->Equals(context.local(), v8_str("undefined"))
+ .FromJust());
+ CHECK(v8::Null(isolate)
+ ->TypeOf(isolate)
+ ->Equals(context.local(), v8_str("object"))
+ .FromJust());
+ CHECK(v8_str("str")
+ ->TypeOf(isolate)
+ ->Equals(context.local(), v8_str("string"))
+ .FromJust());
+ CHECK(v8_num(0.0)
+ ->TypeOf(isolate)
+ ->Equals(context.local(), v8_str("number"))
+ .FromJust());
+ CHECK(v8_num(1)
+ ->TypeOf(isolate)
+ ->Equals(context.local(), v8_str("number"))
+ .FromJust());
+ CHECK(v8::Object::New(isolate)
+ ->TypeOf(isolate)
+ ->Equals(context.local(), v8_str("object"))
+ .FromJust());
+ CHECK(v8::Boolean::New(isolate, true)
+ ->TypeOf(isolate)
+ ->Equals(context.local(), v8_str("boolean"))
+ .FromJust());
+ CHECK(fun->TypeOf(isolate)
+ ->Equals(context.local(), v8_str("function"))
+ .FromJust());
+}
THREADED_TEST(MultiRun) {
LocalContext context;
@@ -9046,33 +9055,6 @@
}
-TEST(ApiUncaughtExceptionInObjectObserve) {
- v8::internal::FLAG_harmony_object_observe = true;
- v8::internal::FLAG_stack_size = 150;
- report_count = 0;
- LocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope scope(isolate);
- isolate->AddMessageListener(ApiUncaughtExceptionTestListener);
- CompileRun(
- "var obj = {};"
- "var observe_count = 0;"
- "function observer1() { ++observe_count; };"
- "function observer2() { ++observe_count; };"
- "function observer_throws() { throw new Error(); };"
- "function stack_overflow() { return (function f(x) { f(x+1); })(0); };"
- "Object.observe(obj, observer_throws.bind());"
- "Object.observe(obj, observer1);"
- "Object.observe(obj, stack_overflow);"
- "Object.observe(obj, observer2);"
- "Object.observe(obj, observer_throws.bind());"
- "obj.foo = 'bar';");
- CHECK_EQ(3, report_count);
- ExpectInt32("observe_count", 2);
- isolate->RemoveMessageListeners(ApiUncaughtExceptionTestListener);
-}
-
-
static const char* script_resource_name = "ExceptionInNativeScript.js";
static void ExceptionInNativeScriptTestListener(v8::Local<v8::Message> message,
v8::Local<Value>) {
@@ -10541,6 +10523,69 @@
}
}
+THREADED_TEST(ObjectGetOwnPropertyNames) {
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ v8::Local<v8::Object> value =
+ v8::Local<v8::Object>::Cast(v8::StringObject::New(v8_str("test")));
+ v8::Local<v8::Array> properties;
+
+ CHECK(value
+ ->GetOwnPropertyNames(context.local(),
+ static_cast<v8::PropertyFilter>(
+ v8::PropertyFilter::ALL_PROPERTIES |
+ v8::PropertyFilter::SKIP_SYMBOLS))
+ .ToLocal(&properties));
+ CHECK_EQ(5, properties->Length());
+ v8::Local<v8::Value> property;
+ CHECK(properties->Get(context.local(), 4).ToLocal(&property) &&
+ property->IsString());
+ CHECK(property.As<v8::String>()
+ ->Equals(context.local(), v8_str("length"))
+ .FromMaybe(false));
+ for (int i = 0; i < 4; ++i) {
+ v8::Local<v8::Value> property;
+ CHECK(properties->Get(context.local(), i).ToLocal(&property) &&
+ property->IsInt32());
+ CHECK_EQ(property.As<v8::Int32>()->Value(), i);
+ }
+
+ CHECK(value->GetOwnPropertyNames(context.local(), v8::ONLY_ENUMERABLE)
+ .ToLocal(&properties));
+ CHECK_EQ(4, properties->Length());
+ for (int i = 0; i < 4; ++i) {
+ v8::Local<v8::Value> property;
+ CHECK(properties->Get(context.local(), i).ToLocal(&property) &&
+ property->IsInt32());
+ CHECK_EQ(property.As<v8::Int32>()->Value(), i);
+ }
+
+ value = value->GetPrototype().As<v8::Object>();
+ CHECK(value
+ ->GetOwnPropertyNames(context.local(),
+ static_cast<v8::PropertyFilter>(
+ v8::PropertyFilter::ALL_PROPERTIES |
+ v8::PropertyFilter::SKIP_SYMBOLS))
+ .ToLocal(&properties));
+ bool concat_found = false;
+ bool starts_with_found = false;
+ for (uint32_t i = 0; i < properties->Length(); ++i) {
+ v8::Local<v8::Value> property;
+ CHECK(properties->Get(context.local(), i).ToLocal(&property));
+ if (!property->IsString()) continue;
+ if (!concat_found)
+ concat_found = property.As<v8::String>()
+ ->Equals(context.local(), v8_str("concat"))
+ .FromMaybe(false);
+ if (!starts_with_found)
+ starts_with_found = property.As<v8::String>()
+ ->Equals(context.local(), v8_str("startsWith"))
+ .FromMaybe(false);
+ }
+ CHECK(concat_found && starts_with_found);
+}
THREADED_TEST(CallKnownGlobalReceiver) {
v8::Isolate* isolate = CcTest::isolate();
@@ -11185,6 +11230,7 @@
Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate);
t1->RemovePrototype();
Local<v8::Function> fun = t1->GetFunction(context.local()).ToLocalChecked();
+ CHECK(!fun->IsConstructor());
CHECK(context->Global()->Set(context.local(), v8_str("fun"), fun).FromJust());
CHECK(!CompileRun("'prototype' in fun")
->BooleanValue(context.local())
@@ -13261,6 +13307,43 @@
CHECK(value->BooleanValue(context.local()).FromJust());
}
+static void NewTargetHandler(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ ApiTestFuzzer::Fuzz();
+ args.GetReturnValue().Set(args.NewTarget());
+}
+
+THREADED_TEST(NewTargetHandler) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+
+ // Function template with call handler.
+ Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
+ templ->SetCallHandler(NewTargetHandler);
+
+ LocalContext context;
+
+ Local<Function> function =
+ templ->GetFunction(context.local()).ToLocalChecked();
+ CHECK(context->Global()
+ ->Set(context.local(), v8_str("f"), function)
+ .FromJust());
+ Local<Value> value = CompileRun("f()");
+ CHECK(value->IsUndefined());
+ value = CompileRun("new f()");
+ CHECK(value->IsFunction());
+ CHECK(value == function);
+ Local<Value> subclass = CompileRun("var g = class extends f { }; g");
+ CHECK(subclass->IsFunction());
+ value = CompileRun("new g()");
+ CHECK(value->IsFunction());
+ CHECK(value == subclass);
+ value = CompileRun("Reflect.construct(f, [], Array)");
+ CHECK(value->IsFunction());
+ CHECK(value ==
+ context->Global()
+ ->Get(context.local(), v8_str("Array"))
+ .ToLocalChecked());
+}
THREADED_TEST(ObjectProtoToString) {
v8::Isolate* isolate = CcTest::isolate();
@@ -14416,7 +14499,6 @@
return invocations;
}
-
void SetFunctionEntryHookTest::RunLoopInNewEnv(v8::Isolate* isolate) {
v8::HandleScope outer(isolate);
v8::Local<Context> env = Context::New(isolate);
@@ -14474,10 +14556,19 @@
RunLoopInNewEnv(isolate);
- // Check the exepected invocation counts.
- CHECK_EQ(2, CountInvocations(NULL, "bar"));
- CHECK_EQ(200, CountInvocations("bar", "foo"));
- CHECK_EQ(200, CountInvocations(NULL, "foo"));
+ // Check the expected invocation counts.
+ if (!i::FLAG_ignition) {
+ CHECK_EQ(2, CountInvocations(NULL, "bar"));
+ CHECK_EQ(200, CountInvocations("bar", "foo"));
+ CHECK_EQ(200, CountInvocations(NULL, "foo"));
+ } else {
+ // For ignition we don't see the actual functions being called, instead
+ // we see the IterpreterEntryTrampoline at least 102 times
+ // (100 unoptimized calls to foo, and 2 calls to bar).
+ CHECK_LE(102, CountInvocations(NULL, "InterpreterEntryTrampoline"));
+ // We should also see the calls to the optimized function foo.
+ CHECK_EQ(100, CountInvocations(NULL, "foo"));
+ }
// Verify that we have an entry hook on some specific stubs.
CHECK_NE(0, CountInvocations(NULL, "CEntryStub"));
@@ -18728,12 +18819,6 @@
}
-static void NamedPropertyGetterWhichReturns42(
- Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
- info.GetReturnValue().Set(v8_num(42));
-}
-
-
static void NamedPropertySetterWhichSetsYOnThisTo23(
Local<Name> name, Local<Value> value,
const v8::PropertyCallbackInfo<v8::Value>& info) {
@@ -20313,6 +20398,7 @@
HasOwnPropertyNamedPropertyGetter));
Local<Object> instance = templ->NewInstance(env.local()).ToLocalChecked();
CHECK(!instance->HasOwnProperty(env.local(), v8_str("42")).FromJust());
+ CHECK(!instance->HasOwnProperty(env.local(), 42).FromJust());
CHECK(instance->HasOwnProperty(env.local(), v8_str("foo")).FromJust());
CHECK(!instance->HasOwnProperty(env.local(), v8_str("bar")).FromJust());
}
@@ -20322,7 +20408,9 @@
HasOwnPropertyIndexedPropertyGetter));
Local<Object> instance = templ->NewInstance(env.local()).ToLocalChecked();
CHECK(instance->HasOwnProperty(env.local(), v8_str("42")).FromJust());
+ CHECK(instance->HasOwnProperty(env.local(), 42).FromJust());
CHECK(!instance->HasOwnProperty(env.local(), v8_str("43")).FromJust());
+ CHECK(!instance->HasOwnProperty(env.local(), 43).FromJust());
CHECK(!instance->HasOwnProperty(env.local(), v8_str("foo")).FromJust());
}
{ // Check named query interceptors.
@@ -20339,7 +20427,9 @@
0, 0, HasOwnPropertyIndexedPropertyQuery));
Local<Object> instance = templ->NewInstance(env.local()).ToLocalChecked();
CHECK(instance->HasOwnProperty(env.local(), v8_str("42")).FromJust());
+ CHECK(instance->HasOwnProperty(env.local(), 42).FromJust());
CHECK(!instance->HasOwnProperty(env.local(), v8_str("41")).FromJust());
+ CHECK(!instance->HasOwnProperty(env.local(), 41).FromJust());
}
{ // Check callbacks.
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
@@ -20917,6 +21007,7 @@
static void MicrotaskOne(const v8::FunctionCallbackInfo<Value>& info) {
+ CHECK(v8::MicrotasksScope::IsRunningMicrotasks(info.GetIsolate()));
v8::HandleScope scope(info.GetIsolate());
v8::MicrotasksScope microtasks(info.GetIsolate(),
v8::MicrotasksScope::kDoNotRunMicrotasks);
@@ -20925,6 +21016,7 @@
static void MicrotaskTwo(const v8::FunctionCallbackInfo<Value>& info) {
+ CHECK(v8::MicrotasksScope::IsRunningMicrotasks(info.GetIsolate()));
v8::HandleScope scope(info.GetIsolate());
v8::MicrotasksScope microtasks(info.GetIsolate(),
v8::MicrotasksScope::kDoNotRunMicrotasks);
@@ -20943,6 +21035,7 @@
TEST(EnqueueMicrotask) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
+ CHECK(!v8::MicrotasksScope::IsRunningMicrotasks(env->GetIsolate()));
CompileRun(
"var ext1Calls = 0;"
"var ext2Calls = 0;");
@@ -21283,40 +21376,6 @@
}
-static void DebugEventInObserver(const v8::Debug::EventDetails& event_details) {
- v8::DebugEvent event = event_details.GetEvent();
- if (event != v8::Break) return;
- Local<Object> exec_state = event_details.GetExecutionState();
- Local<Context> context = CcTest::isolate()->GetCurrentContext();
- Local<Value> break_id =
- exec_state->Get(context, v8_str("break_id")).ToLocalChecked();
- CompileRun("function f(id) { new FrameDetails(id, 0); }");
- Local<Function> fun = Local<Function>::Cast(
- CcTest::global()->Get(context, v8_str("f")).ToLocalChecked());
- fun->Call(context, CcTest::global(), 1, &break_id).ToLocalChecked();
-}
-
-
-TEST(Regress385349) {
- i::FLAG_harmony_object_observe = true;
- i::FLAG_allow_natives_syntax = true;
- v8::Isolate* isolate = CcTest::isolate();
- HandleScope handle_scope(isolate);
- isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
- Local<Context> context = Context::New(isolate);
- v8::Debug::SetDebugEventListener(isolate, DebugEventInObserver);
- {
- Context::Scope context_scope(context);
- CompileRun("var obj = {};"
- "Object.observe(obj, function(changes) { debugger; });"
- "obj.a = 0;");
- }
- isolate->RunMicrotasks();
- isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto);
- v8::Debug::SetDebugEventListener(isolate, nullptr);
-}
-
-
#ifdef ENABLE_DISASSEMBLER
static int probes_counter = 0;
static int misses_counter = 0;
@@ -21960,29 +22019,39 @@
CHECK(function->IsFunction());
}
-
THREADED_TEST(JSONParseObject) {
LocalContext context;
HandleScope scope(context->GetIsolate());
Local<Value> obj =
- v8::JSON::Parse(context->GetIsolate(), v8_str("{\"x\":42}"))
- .ToLocalChecked();
+ v8::JSON::Parse(context.local(), v8_str("{\"x\":42}")).ToLocalChecked();
Local<Object> global = context->Global();
global->Set(context.local(), v8_str("obj"), obj).FromJust();
ExpectString("JSON.stringify(obj)", "{\"x\":42}");
}
-
THREADED_TEST(JSONParseNumber) {
LocalContext context;
HandleScope scope(context->GetIsolate());
Local<Value> obj =
- v8::JSON::Parse(context->GetIsolate(), v8_str("42")).ToLocalChecked();
+ v8::JSON::Parse(context.local(), v8_str("42")).ToLocalChecked();
Local<Object> global = context->Global();
global->Set(context.local(), v8_str("obj"), obj).FromJust();
ExpectString("JSON.stringify(obj)", "42");
}
+THREADED_TEST(JSONStringifyObject) {
+ LocalContext context;
+ HandleScope scope(context->GetIsolate());
+ Local<Value> value =
+ v8::JSON::Parse(context.local(), v8_str("{\"x\":42}")).ToLocalChecked();
+ Local<Object> obj = value->ToObject(context.local()).ToLocalChecked();
+ Local<Object> global = context->Global();
+ global->Set(context.local(), v8_str("obj"), obj).FromJust();
+ Local<String> json =
+ v8::JSON::Stringify(context.local(), obj).ToLocalChecked();
+ v8::String::Utf8Value utf8(json);
+ ExpectString("JSON.stringify(obj)", *utf8);
+}
#if V8_OS_POSIX && !V8_OS_NACL
class ThreadInterruptTest {
@@ -24077,8 +24146,7 @@
script->Run(context).ToLocalChecked()->Int32Value(context).FromJust());
}
-
-TEST(InvalidCacheData) {
+TEST(InvalidParserCacheData) {
v8::V8::Initialize();
v8::HandleScope scope(CcTest::isolate());
LocalContext context;
@@ -24086,6 +24154,12 @@
// Cached parser data is not consumed while parsing eagerly.
TestInvalidCacheData(v8::ScriptCompiler::kConsumeParserCache);
}
+}
+
+TEST(InvalidCodeCacheData) {
+ v8::V8::Initialize();
+ v8::HandleScope scope(CcTest::isolate());
+ LocalContext context;
TestInvalidCacheData(v8::ScriptCompiler::kConsumeCodeCache);
}
@@ -24168,6 +24242,7 @@
TEST(TurboAsmDisablesNeuter) {
+ i::FLAG_allow_natives_syntax = true;
v8::V8::Initialize();
v8::HandleScope scope(CcTest::isolate());
LocalContext context;
@@ -24180,10 +24255,11 @@
" return { load: load };"
"}"
"var buffer = new ArrayBuffer(4);"
- "Module(this, {}, buffer).load();"
+ "var module = Module(this, {}, buffer);"
+ "%OptimizeFunctionOnNextCall(module.load);"
+ "module.load();"
"buffer";
- i::FLAG_turbo_osr = false; // TODO(titzer): test requires eager TF.
v8::Local<v8::ArrayBuffer> result = CompileRun(load).As<v8::ArrayBuffer>();
CHECK_EQ(should_be_neuterable, result->IsNeuterable());
@@ -24195,10 +24271,11 @@
" return { store: store };"
"}"
"var buffer = new ArrayBuffer(4);"
- "Module(this, {}, buffer).store();"
+ "var module = Module(this, {}, buffer);"
+ "%OptimizeFunctionOnNextCall(module.store);"
+ "module.store();"
"buffer";
- i::FLAG_turbo_osr = false; // TODO(titzer): test requires eager TF.
result = CompileRun(store).As<v8::ArrayBuffer>();
CHECK_EQ(should_be_neuterable, result->IsNeuterable());
}
@@ -24629,6 +24706,60 @@
CHECK_EQ(0U, set->Size());
}
+TEST(SetDeleteThenAsArray) {
+ // https://bugs.chromium.org/p/v8/issues/detail?id=4946
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ LocalContext env;
+
+ // make a Set
+ v8::Local<v8::Value> val = CompileRun("new Set([1, 2, 3])");
+ v8::Local<v8::Set> set = v8::Local<v8::Set>::Cast(val);
+ CHECK_EQ(3U, set->Size());
+
+ // delete the "middle" element (using AsArray to
+ // determine which element is the "middle" element)
+ v8::Local<v8::Array> array1 = set->AsArray();
+ CHECK_EQ(3U, array1->Length());
+ CHECK(set->Delete(env.local(), array1->Get(env.local(), 1).ToLocalChecked())
+ .FromJust());
+
+ // make sure there are no undefined values when we convert to an array again.
+ v8::Local<v8::Array> array2 = set->AsArray();
+ uint32_t length = array2->Length();
+ CHECK_EQ(2U, length);
+ for (uint32_t i = 0; i < length; i++) {
+ CHECK(!array2->Get(env.local(), i).ToLocalChecked()->IsUndefined());
+ }
+}
+
+TEST(MapDeleteThenAsArray) {
+ // https://bugs.chromium.org/p/v8/issues/detail?id=4946
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ LocalContext env;
+
+ // make a Map
+ v8::Local<v8::Value> val = CompileRun("new Map([[1, 2], [3, 4], [5, 6]])");
+ v8::Local<v8::Map> map = v8::Local<v8::Map>::Cast(val);
+ CHECK_EQ(3U, map->Size());
+
+ // delete the "middle" element (using AsArray to
+ // determine which element is the "middle" element)
+ v8::Local<v8::Array> array1 = map->AsArray();
+ CHECK_EQ(6U, array1->Length());
+ // Map::AsArray returns a flat array, so the second key is at index 2.
+ v8::Local<v8::Value> key = array1->Get(env.local(), 2).ToLocalChecked();
+ CHECK(map->Delete(env.local(), key).FromJust());
+
+ // make sure there are no undefined values when we convert to an array again.
+ v8::Local<v8::Array> array2 = map->AsArray();
+ uint32_t length = array2->Length();
+ CHECK_EQ(4U, length);
+ for (uint32_t i = 0; i < length; i++) {
+ CHECK(!array2->Get(env.local(), i).ToLocalChecked()->IsUndefined());
+ }
+}
TEST(CompatibleReceiverCheckOnCachedICHandler) {
v8::Isolate* isolate = CcTest::isolate();