Commit 07dca4cd authored by jameslahm's avatar jameslahm Committed by V8 LUCI CQ

[test] Move cctest/test-modules to unittests

... /objects/modules-unittest.

Bug: v8:12781
Change-Id: Ie3d63ac470e435858dfd0e32b7fda2f78502aa17
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3607369Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: 王澳 <wangao.james@bytedance.com>
Cr-Commit-Position: refs/heads/main@{#80199}
parent 40605a3d
......@@ -235,7 +235,6 @@ v8_source_set("cctest_sources") {
"test-log.cc",
"test-managed.cc",
"test-mementos.cc",
"test-modules.cc",
"test-object.cc",
"test-orderedhashtable.cc",
"test-parsing.cc",
......
......@@ -384,6 +384,7 @@ v8_source_set("unittests_sources") {
"objects/concurrent-script-context-table-unittest.cc",
"objects/concurrent-string-unittest.cc",
"objects/concurrent-transition-array-unittest.cc",
"objects/modules-unittest.cc",
"objects/object-unittest.cc",
"objects/swiss-hash-table-helpers-unittest.cc",
"objects/value-serializer-unittest.cc",
......
// Copyright 2016 the V8 project authors. All rights reserved.
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "include/v8-function.h"
#include "src/flags/flags.h"
#include "test/cctest/cctest.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
using ModuleTest = v8::TestWithContext;
using v8::Context;
using v8::Data;
using v8::FixedArray;
......@@ -38,37 +41,39 @@ MaybeLocal<Module> ResolveCallback(Local<Context> context,
Local<FixedArray> import_assertions,
Local<Module> referrer) {
CHECK_EQ(0, import_assertions->Length());
Isolate* isolate = CcTest::isolate();
if (specifier->StrictEquals(v8_str("./dep1.js"))) {
Isolate* isolate = context->GetIsolate();
if (specifier->StrictEquals(
String::NewFromUtf8(isolate, "./dep1.js").ToLocalChecked())) {
return dep1;
} else if (specifier->StrictEquals(v8_str("./dep2.js"))) {
} else if (specifier->StrictEquals(
String::NewFromUtf8(isolate, "./dep2.js").ToLocalChecked())) {
return dep2;
} else {
isolate->ThrowException(v8_str("boom"));
isolate->ThrowException(
String::NewFromUtf8(isolate, "boom").ToLocalChecked());
return MaybeLocal<Module>();
}
}
TEST(ModuleInstantiationFailures1) {
Isolate* isolate = CcTest::isolate();
HandleScope scope(isolate);
LocalContext env;
v8::TryCatch try_catch(isolate);
TEST_F(ModuleTest, ModuleInstantiationFailures1) {
HandleScope scope(isolate());
v8::TryCatch try_catch(isolate());
Local<Module> module;
{
Local<String> source_text = v8_str(
Local<String> source_text = NewString(
"import './foo.js';\n"
"export {} from './bar.js';");
ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
ScriptOrigin origin = ModuleOrigin(NewString("file.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
module = ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
module = ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
CHECK_EQ(Module::kUninstantiated, module->GetStatus());
Local<FixedArray> module_requests = module->GetModuleRequests();
CHECK_EQ(2, module_requests->Length());
Local<ModuleRequest> module_request_0 =
module_requests->Get(env.local(), 0).As<ModuleRequest>();
CHECK(v8_str("./foo.js")->StrictEquals(module_request_0->GetSpecifier()));
module_requests->Get(context(), 0).As<ModuleRequest>();
CHECK(
NewString("./foo.js")->StrictEquals(module_request_0->GetSpecifier()));
int offset = module_request_0->GetSourceOffset();
CHECK_EQ(7, offset);
Location loc = module->SourceOffsetToLocation(offset);
......@@ -77,8 +82,9 @@ TEST(ModuleInstantiationFailures1) {
CHECK_EQ(0, module_request_0->GetImportAssertions()->Length());
Local<ModuleRequest> module_request_1 =
module_requests->Get(env.local(), 1).As<ModuleRequest>();
CHECK(v8_str("./bar.js")->StrictEquals(module_request_1->GetSpecifier()));
module_requests->Get(context(), 1).As<ModuleRequest>();
CHECK(
NewString("./bar.js")->StrictEquals(module_request_1->GetSpecifier()));
offset = module_request_1->GetSourceOffset();
CHECK_EQ(34, offset);
loc = module->SourceOffsetToLocation(offset);
......@@ -89,37 +95,37 @@ TEST(ModuleInstantiationFailures1) {
// Instantiation should fail.
{
v8::TryCatch inner_try_catch(isolate);
CHECK(module->InstantiateModule(env.local(), ResolveCallback).IsNothing());
v8::TryCatch inner_try_catch(isolate());
CHECK(module->InstantiateModule(context(), ResolveCallback).IsNothing());
CHECK(inner_try_catch.HasCaught());
CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom")));
CHECK(inner_try_catch.Exception()->StrictEquals(NewString("boom")));
CHECK_EQ(Module::kUninstantiated, module->GetStatus());
}
// Start over again...
{
Local<String> source_text = v8_str(
Local<String> source_text = NewString(
"import './dep1.js';\n"
"export {} from './bar.js';");
ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
ScriptOrigin origin = ModuleOrigin(NewString("file.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
module = ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
module = ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
}
// dep1.js
{
Local<String> source_text = v8_str("");
ScriptOrigin origin = ModuleOrigin(v8_str("dep1.js"), CcTest::isolate());
Local<String> source_text = NewString("");
ScriptOrigin origin = ModuleOrigin(NewString("dep1.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
dep1 = ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
dep1 = ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
}
// Instantiation should fail because a sub-module fails to resolve.
{
v8::TryCatch inner_try_catch(isolate);
CHECK(module->InstantiateModule(env.local(), ResolveCallback).IsNothing());
v8::TryCatch inner_try_catch(isolate());
CHECK(module->InstantiateModule(context(), ResolveCallback).IsNothing());
CHECK(inner_try_catch.HasCaught());
CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom")));
CHECK(inner_try_catch.Exception()->StrictEquals(NewString("boom")));
CHECK_EQ(Module::kUninstantiated, module->GetStatus());
}
......@@ -131,23 +137,27 @@ static Local<Module> barModule;
MaybeLocal<Module> ResolveCallbackWithImportAssertions(
Local<Context> context, Local<String> specifier,
Local<FixedArray> import_assertions, Local<Module> referrer) {
Isolate* isolate = CcTest::isolate();
LocalContext env;
if (specifier->StrictEquals(v8_str("./foo.js"))) {
Isolate* isolate = context->GetIsolate();
if (specifier->StrictEquals(
String::NewFromUtf8(isolate, "./foo.js").ToLocalChecked())) {
CHECK_EQ(0, import_assertions->Length());
return fooModule;
} else if (specifier->StrictEquals(v8_str("./bar.js"))) {
} else if (specifier->StrictEquals(
String::NewFromUtf8(isolate, "./bar.js").ToLocalChecked())) {
CHECK_EQ(3, import_assertions->Length());
Local<String> assertion_key =
import_assertions->Get(env.local(), 0).As<Value>().As<String>();
CHECK(v8_str("a")->StrictEquals(assertion_key));
import_assertions->Get(context, 0).As<Value>().As<String>();
CHECK(String::NewFromUtf8(isolate, "a")
.ToLocalChecked()
->StrictEquals(assertion_key));
Local<String> assertion_value =
import_assertions->Get(env.local(), 1).As<Value>().As<String>();
CHECK(v8_str("b")->StrictEquals(assertion_value));
import_assertions->Get(context, 1).As<Value>().As<String>();
CHECK(String::NewFromUtf8(isolate, "b")
.ToLocalChecked()
->StrictEquals(assertion_value));
Local<Data> assertion_source_offset_object =
import_assertions->Get(env.local(), 2);
import_assertions->Get(context, 2);
Local<Int32> assertion_source_offset_int32 =
assertion_source_offset_object.As<Value>()
->ToInt32(context)
......@@ -160,33 +170,33 @@ MaybeLocal<Module> ResolveCallbackWithImportAssertions(
return barModule;
} else {
isolate->ThrowException(v8_str("boom"));
isolate->ThrowException(
String::NewFromUtf8(isolate, "boom").ToLocalChecked());
return MaybeLocal<Module>();
}
}
TEST(ModuleInstantiationWithImportAssertions) {
TEST_F(ModuleTest, ModuleInstantiationWithImportAssertions) {
bool prev_import_assertions = i::FLAG_harmony_import_assertions;
i::FLAG_harmony_import_assertions = true;
Isolate* isolate = CcTest::isolate();
HandleScope scope(isolate);
LocalContext env;
v8::TryCatch try_catch(isolate);
HandleScope scope(isolate());
v8::TryCatch try_catch(isolate());
Local<Module> module;
{
Local<String> source_text = v8_str(
Local<String> source_text = NewString(
"import './foo.js' assert { };\n"
"export {} from './bar.js' assert { a: 'b' };");
ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
ScriptOrigin origin = ModuleOrigin(NewString("file.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
module = ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
module = ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
CHECK_EQ(Module::kUninstantiated, module->GetStatus());
Local<FixedArray> module_requests = module->GetModuleRequests();
CHECK_EQ(2, module_requests->Length());
Local<ModuleRequest> module_request_0 =
module_requests->Get(env.local(), 0).As<ModuleRequest>();
CHECK(v8_str("./foo.js")->StrictEquals(module_request_0->GetSpecifier()));
module_requests->Get(context(), 0).As<ModuleRequest>();
CHECK(
NewString("./foo.js")->StrictEquals(module_request_0->GetSpecifier()));
int offset = module_request_0->GetSourceOffset();
CHECK_EQ(7, offset);
Location loc = module->SourceOffsetToLocation(offset);
......@@ -195,8 +205,9 @@ TEST(ModuleInstantiationWithImportAssertions) {
CHECK_EQ(0, module_request_0->GetImportAssertions()->Length());
Local<ModuleRequest> module_request_1 =
module_requests->Get(env.local(), 1).As<ModuleRequest>();
CHECK(v8_str("./bar.js")->StrictEquals(module_request_1->GetSpecifier()));
module_requests->Get(context(), 1).As<ModuleRequest>();
CHECK(
NewString("./bar.js")->StrictEquals(module_request_1->GetSpecifier()));
offset = module_request_1->GetSourceOffset();
CHECK_EQ(45, offset);
loc = module->SourceOffsetToLocation(offset);
......@@ -207,90 +218,95 @@ TEST(ModuleInstantiationWithImportAssertions) {
module_request_1->GetImportAssertions();
CHECK_EQ(3, import_assertions_1->Length());
Local<String> assertion_key =
import_assertions_1->Get(env.local(), 0).As<String>();
CHECK(v8_str("a")->StrictEquals(assertion_key));
import_assertions_1->Get(context(), 0).As<String>();
CHECK(NewString("a")->StrictEquals(assertion_key));
Local<String> assertion_value =
import_assertions_1->Get(env.local(), 1).As<String>();
CHECK(v8_str("b")->StrictEquals(assertion_value));
import_assertions_1->Get(context(), 1).As<String>();
CHECK(NewString("b")->StrictEquals(assertion_value));
int32_t assertion_source_offset =
import_assertions_1->Get(env.local(), 2).As<Int32>()->Value();
import_assertions_1->Get(context(), 2).As<Int32>()->Value();
CHECK_EQ(65, assertion_source_offset);
loc = module->SourceOffsetToLocation(assertion_source_offset);
CHECK_EQ(1, loc.GetLineNumber());
CHECK_EQ(35, loc.GetColumnNumber());
}
// foo.js
{
Local<String> source_text = v8_str("Object.expando = 40");
ScriptOrigin origin = ModuleOrigin(v8_str("foo.js"), CcTest::isolate());
ScriptCompiler::Source source(source_text, origin);
fooModule =
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
}
// foo.js
{
Local<String> source_text = NewString("Object.expando = 40");
ScriptOrigin origin = ModuleOrigin(NewString("foo.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
fooModule =
ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
}
// bar.js
{
Local<String> source_text = v8_str("Object.expando += 2");
ScriptOrigin origin = ModuleOrigin(v8_str("bar.js"), CcTest::isolate());
ScriptCompiler::Source source(source_text, origin);
barModule =
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
}
// bar.js
{
Local<String> source_text = NewString("Object.expando += 2");
ScriptOrigin origin = ModuleOrigin(NewString("bar.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
barModule =
ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
}
CHECK(module
->InstantiateModule(env.local(),
ResolveCallbackWithImportAssertions)
.FromJust());
CHECK_EQ(Module::kInstantiated, module->GetStatus());
CHECK(
module->InstantiateModule(context(), ResolveCallbackWithImportAssertions)
.FromJust());
CHECK_EQ(Module::kInstantiated, module->GetStatus());
MaybeLocal<Value> result = module->Evaluate(env.local());
CHECK_EQ(Module::kEvaluated, module->GetStatus());
Local<Promise> promise = Local<Promise>::Cast(result.ToLocalChecked());
CHECK_EQ(promise->State(), v8::Promise::kFulfilled);
CHECK(promise->Result()->IsUndefined());
ExpectInt32("Object.expando", 42);
CHECK(!try_catch.HasCaught());
i::FLAG_harmony_import_assertions = prev_import_assertions;
MaybeLocal<Value> result = module->Evaluate(context());
CHECK_EQ(Module::kEvaluated, module->GetStatus());
Local<Promise> promise = Local<Promise>::Cast(result.ToLocalChecked());
CHECK_EQ(promise->State(), v8::Promise::kFulfilled);
CHECK(promise->Result()->IsUndefined());
// TODO(v8:12781): One IsInt32 matcher be added in
// gmock-support.h, we could use IsInt32 to replace
// this.
{
Local<Value> result = RunJS("Object.expando");
CHECK(result->IsInt32());
CHECK_EQ(42, result->Int32Value(context()).FromJust());
}
CHECK(!try_catch.HasCaught());
i::FLAG_harmony_import_assertions = prev_import_assertions;
}
TEST(ModuleInstantiationFailures2) {
Isolate* isolate = CcTest::isolate();
HandleScope scope(isolate);
LocalContext env;
v8::TryCatch try_catch(isolate);
TEST_F(ModuleTest, ModuleInstantiationFailures2) {
HandleScope scope(isolate());
v8::TryCatch try_catch(isolate());
// root1.js
Local<Module> root;
{
Local<String> source_text =
v8_str("import './dep1.js'; import './dep2.js'");
ScriptOrigin origin = ModuleOrigin(v8_str("root1.js"), CcTest::isolate());
NewString("import './dep1.js'; import './dep2.js'");
ScriptOrigin origin = ModuleOrigin(NewString("root1.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
root = ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
root = ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
}
// dep1.js
{
Local<String> source_text = v8_str("export let x = 42");
ScriptOrigin origin = ModuleOrigin(v8_str("dep1.js"), CcTest::isolate());
Local<String> source_text = NewString("export let x = 42");
ScriptOrigin origin = ModuleOrigin(NewString("dep1.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
dep1 = ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
dep1 = ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
}
// dep2.js
{
Local<String> source_text = v8_str("import {foo} from './dep3.js'");
ScriptOrigin origin = ModuleOrigin(v8_str("dep2.js"), CcTest::isolate());
Local<String> source_text = NewString("import {foo} from './dep3.js'");
ScriptOrigin origin = ModuleOrigin(NewString("dep2.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
dep2 = ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
dep2 = ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
}
{
v8::TryCatch inner_try_catch(isolate);
CHECK(root->InstantiateModule(env.local(), ResolveCallback).IsNothing());
v8::TryCatch inner_try_catch(isolate());
CHECK(root->InstantiateModule(context(), ResolveCallback).IsNothing());
CHECK(inner_try_catch.HasCaught());
CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom")));
CHECK(inner_try_catch.Exception()->StrictEquals(NewString("boom")));
CHECK_EQ(Module::kUninstantiated, root->GetStatus());
CHECK_EQ(Module::kUninstantiated, dep1->GetStatus());
CHECK_EQ(Module::kUninstantiated, dep2->GetStatus());
......@@ -298,17 +314,17 @@ TEST(ModuleInstantiationFailures2) {
// Change dep2.js
{
Local<String> source_text = v8_str("import {foo} from './dep2.js'");
ScriptOrigin origin = ModuleOrigin(v8_str("dep2.js"), CcTest::isolate());
Local<String> source_text = NewString("import {foo} from './dep2.js'");
ScriptOrigin origin = ModuleOrigin(NewString("dep2.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
dep2 = ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
dep2 = ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
}
{
v8::TryCatch inner_try_catch(isolate);
CHECK(root->InstantiateModule(env.local(), ResolveCallback).IsNothing());
v8::TryCatch inner_try_catch(isolate());
CHECK(root->InstantiateModule(context(), ResolveCallback).IsNothing());
CHECK(inner_try_catch.HasCaught());
CHECK(!inner_try_catch.Exception()->StrictEquals(v8_str("boom")));
CHECK(!inner_try_catch.Exception()->StrictEquals(NewString("boom")));
CHECK_EQ(Module::kUninstantiated, root->GetStatus());
CHECK_EQ(Module::kInstantiated, dep1->GetStatus());
CHECK_EQ(Module::kUninstantiated, dep2->GetStatus());
......@@ -316,17 +332,17 @@ TEST(ModuleInstantiationFailures2) {
// Change dep2.js again
{
Local<String> source_text = v8_str("import {foo} from './dep3.js'");
ScriptOrigin origin = ModuleOrigin(v8_str("dep2.js"), CcTest::isolate());
Local<String> source_text = NewString("import {foo} from './dep3.js'");
ScriptOrigin origin = ModuleOrigin(NewString("dep2.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
dep2 = ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
dep2 = ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
}
{
v8::TryCatch inner_try_catch(isolate);
CHECK(root->InstantiateModule(env.local(), ResolveCallback).IsNothing());
v8::TryCatch inner_try_catch(isolate());
CHECK(root->InstantiateModule(context(), ResolveCallback).IsNothing());
CHECK(inner_try_catch.HasCaught());
CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom")));
CHECK(inner_try_catch.Exception()->StrictEquals(NewString("boom")));
CHECK_EQ(Module::kUninstantiated, root->GetStatus());
CHECK_EQ(Module::kInstantiated, dep1->GetStatus());
CHECK_EQ(Module::kUninstantiated, dep2->GetStatus());
......@@ -337,68 +353,82 @@ static MaybeLocal<Module> CompileSpecifierAsModuleResolveCallback(
Local<Context> context, Local<String> specifier,
Local<FixedArray> import_assertions, Local<Module> referrer) {
CHECK_EQ(0, import_assertions->Length());
ScriptOrigin origin = ModuleOrigin(v8_str("module.js"), CcTest::isolate());
Isolate* isolate = context->GetIsolate();
ScriptOrigin origin = ModuleOrigin(
String::NewFromUtf8(isolate, "module.js").ToLocalChecked(), isolate);
ScriptCompiler::Source source(specifier, origin);
return ScriptCompiler::CompileModule(CcTest::isolate(), &source)
.ToLocalChecked();
return ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
}
TEST(ModuleEvaluation) {
Isolate* isolate = CcTest::isolate();
HandleScope scope(isolate);
LocalContext env;
v8::TryCatch try_catch(isolate);
TEST_F(ModuleTest, ModuleEvaluation) {
HandleScope scope(isolate());
v8::TryCatch try_catch(isolate());
Local<String> source_text = v8_str(
Local<String> source_text = NewString(
"import 'Object.expando = 5';"
"import 'Object.expando *= 2';");
ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
ScriptOrigin origin = ModuleOrigin(
String::NewFromUtf8(isolate(), "file.js").ToLocalChecked(), isolate());
ScriptCompiler::Source source(source_text, origin);
Local<Module> module =
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
CHECK_EQ(Module::kUninstantiated, module->GetStatus());
CHECK(module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
CompileSpecifierAsModuleResolveCallback)
.FromJust());
CHECK_EQ(Module::kInstantiated, module->GetStatus());
MaybeLocal<Value> result = module->Evaluate(env.local());
MaybeLocal<Value> result = module->Evaluate(context());
CHECK_EQ(Module::kEvaluated, module->GetStatus());
Local<Promise> promise = result.ToLocalChecked().As<Promise>();
CHECK_EQ(promise->State(), v8::Promise::kFulfilled);
CHECK(promise->Result()->IsUndefined());
ExpectInt32("Object.expando", 10);
// TODO(v8:12781): One IsInt32 matcher be added in
// gmock-support.h, we could use IsInt32 to replace
// this.
{
Local<Value> result = RunJS("Object.expando");
CHECK(result->IsInt32());
CHECK_EQ(10, result->Int32Value(context()).FromJust());
}
CHECK(!try_catch.HasCaught());
}
TEST(ModuleEvaluationError1) {
Isolate* isolate = CcTest::isolate();
HandleScope scope(isolate);
LocalContext env;
v8::TryCatch try_catch(isolate);
TEST_F(ModuleTest, ModuleEvaluationError1) {
HandleScope scope(isolate());
v8::TryCatch try_catch(isolate());
Local<String> source_text =
v8_str("Object.x = (Object.x || 0) + 1; throw 'boom';");
ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
NewString("Object.x = (Object.x || 0) + 1; throw 'boom';");
ScriptOrigin origin = ModuleOrigin(
String::NewFromUtf8(isolate(), "file.js").ToLocalChecked(), isolate());
ScriptCompiler::Source source(source_text, origin);
Local<Module> module =
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
CHECK_EQ(Module::kUninstantiated, module->GetStatus());
CHECK(module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
CompileSpecifierAsModuleResolveCallback)
.FromJust());
CHECK_EQ(Module::kInstantiated, module->GetStatus());
{
v8::TryCatch inner_try_catch(isolate);
MaybeLocal<Value> result = module->Evaluate(env.local());
v8::TryCatch inner_try_catch(isolate());
MaybeLocal<Value> result = module->Evaluate(context());
CHECK_EQ(Module::kErrored, module->GetStatus());
Local<Value> exception = module->GetException();
CHECK(exception->StrictEquals(v8_str("boom")));
ExpectInt32("Object.x", 1);
CHECK(exception->StrictEquals(NewString("boom")));
// TODO(v8:12781): One IsInt32 matcher be added in
// gmock-support.h, we could use IsInt32 to replace
// this.
{
Local<Value> result = RunJS("Object.x");
CHECK(result->IsInt32());
CHECK_EQ(1, result->Int32Value(context()).FromJust());
}
// With top level await, we do not throw and errored evaluation returns
// a rejected promise with the exception.
CHECK(!inner_try_catch.HasCaught());
......@@ -408,12 +438,19 @@ TEST(ModuleEvaluationError1) {
}
{
v8::TryCatch inner_try_catch(isolate);
MaybeLocal<Value> result = module->Evaluate(env.local());
v8::TryCatch inner_try_catch(isolate());
MaybeLocal<Value> result = module->Evaluate(context());
CHECK_EQ(Module::kErrored, module->GetStatus());
Local<Value> exception = module->GetException();
CHECK(exception->StrictEquals(v8_str("boom")));
ExpectInt32("Object.x", 1);
CHECK(exception->StrictEquals(NewString("boom")));
// TODO(v8:12781): One IsInt32 matcher be added in
// gmock-support.h, we could use IsInt32 to replace
// this.
{
Local<Value> result = RunJS("Object.x");
CHECK(result->IsInt32());
CHECK_EQ(1, result->Int32Value(context()).FromJust());
}
// With top level await, we do not throw and errored evaluation returns
// a rejected promise with the exception.
......@@ -432,39 +469,40 @@ MaybeLocal<Module> ResolveCallbackForModuleEvaluationError2(
Local<Context> context, Local<String> specifier,
Local<FixedArray> import_assertions, Local<Module> referrer) {
CHECK_EQ(0, import_assertions->Length());
if (specifier->StrictEquals(v8_str("./failure.js"))) {
Isolate* isolate = context->GetIsolate();
if (specifier->StrictEquals(
String::NewFromUtf8(isolate, "./failure.js").ToLocalChecked())) {
return failure_module;
} else {
CHECK(specifier->StrictEquals(v8_str("./dependent.js")));
CHECK(specifier->StrictEquals(
String::NewFromUtf8(isolate, "./dependent.js").ToLocalChecked()));
return dependent_module;
}
}
TEST(ModuleEvaluationError2) {
Isolate* isolate = CcTest::isolate();
HandleScope scope(isolate);
LocalContext env;
v8::TryCatch try_catch(isolate);
TEST_F(ModuleTest, ModuleEvaluationError2) {
HandleScope scope(isolate());
v8::TryCatch try_catch(isolate());
Local<String> failure_text = v8_str("throw 'boom';");
Local<String> failure_text = NewString("throw 'boom';");
ScriptOrigin failure_origin =
ModuleOrigin(v8_str("failure.js"), CcTest::isolate());
ModuleOrigin(NewString("failure.js"), isolate());
ScriptCompiler::Source failure_source(failure_text, failure_origin);
failure_module =
ScriptCompiler::CompileModule(isolate, &failure_source).ToLocalChecked();
failure_module = ScriptCompiler::CompileModule(isolate(), &failure_source)
.ToLocalChecked();
CHECK_EQ(Module::kUninstantiated, failure_module->GetStatus());
CHECK(failure_module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
ResolveCallbackForModuleEvaluationError2)
.FromJust());
CHECK_EQ(Module::kInstantiated, failure_module->GetStatus());
{
v8::TryCatch inner_try_catch(isolate);
MaybeLocal<Value> result = failure_module->Evaluate(env.local());
v8::TryCatch inner_try_catch(isolate());
MaybeLocal<Value> result = failure_module->Evaluate(context());
CHECK_EQ(Module::kErrored, failure_module->GetStatus());
Local<Value> exception = failure_module->GetException();
CHECK(exception->StrictEquals(v8_str("boom")));
CHECK(exception->StrictEquals(NewString("boom")));
// With top level await, we do not throw and errored evaluation returns
// a rejected promise with the exception.
......@@ -475,25 +513,25 @@ TEST(ModuleEvaluationError2) {
}
Local<String> dependent_text =
v8_str("import './failure.js'; export const c = 123;");
NewString("import './failure.js'; export const c = 123;");
ScriptOrigin dependent_origin =
ModuleOrigin(v8_str("dependent.js"), CcTest::isolate());
ModuleOrigin(NewString("dependent.js"), isolate());
ScriptCompiler::Source dependent_source(dependent_text, dependent_origin);
dependent_module = ScriptCompiler::CompileModule(isolate, &dependent_source)
dependent_module = ScriptCompiler::CompileModule(isolate(), &dependent_source)
.ToLocalChecked();
CHECK_EQ(Module::kUninstantiated, dependent_module->GetStatus());
CHECK(dependent_module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
ResolveCallbackForModuleEvaluationError2)
.FromJust());
CHECK_EQ(Module::kInstantiated, dependent_module->GetStatus());
{
v8::TryCatch inner_try_catch(isolate);
MaybeLocal<Value> result = dependent_module->Evaluate(env.local());
v8::TryCatch inner_try_catch(isolate());
MaybeLocal<Value> result = dependent_module->Evaluate(context());
CHECK_EQ(Module::kErrored, dependent_module->GetStatus());
Local<Value> exception = dependent_module->GetException();
CHECK(exception->StrictEquals(v8_str("boom")));
CHECK(exception->StrictEquals(NewString("boom")));
CHECK_EQ(exception, failure_module->GetException());
// With top level await, we do not throw and errored evaluation returns
......@@ -502,17 +540,15 @@ TEST(ModuleEvaluationError2) {
Local<Promise> promise = result.ToLocalChecked().As<Promise>();
CHECK_EQ(promise->State(), v8::Promise::kRejected);
CHECK_EQ(promise->Result(), failure_module->GetException());
CHECK(failure_module->GetException()->StrictEquals(v8_str("boom")));
CHECK(failure_module->GetException()->StrictEquals(NewString("boom")));
}
CHECK(!try_catch.HasCaught());
}
TEST(ModuleEvaluationCompletion1) {
Isolate* isolate = CcTest::isolate();
HandleScope scope(isolate);
LocalContext env;
v8::TryCatch try_catch(isolate);
TEST_F(ModuleTest, ModuleEvaluationCompletion1) {
HandleScope scope(isolate());
v8::TryCatch try_catch(isolate());
const char* sources[] = {
"",
......@@ -535,22 +571,22 @@ TEST(ModuleEvaluationCompletion1) {
};
for (auto src : sources) {
Local<String> source_text = v8_str(src);
ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
Local<String> source_text = NewString(src);
ScriptOrigin origin = ModuleOrigin(NewString("file.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
Local<Module> module =
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
CHECK_EQ(Module::kUninstantiated, module->GetStatus());
CHECK(module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
CompileSpecifierAsModuleResolveCallback)
.FromJust());
CHECK_EQ(Module::kInstantiated, module->GetStatus());
// Evaluate twice.
Local<Value> result_1 = module->Evaluate(env.local()).ToLocalChecked();
Local<Value> result_1 = module->Evaluate(context()).ToLocalChecked();
CHECK_EQ(Module::kEvaluated, module->GetStatus());
Local<Value> result_2 = module->Evaluate(env.local()).ToLocalChecked();
Local<Value> result_2 = module->Evaluate(context()).ToLocalChecked();
CHECK_EQ(Module::kEvaluated, module->GetStatus());
Local<Promise> promise = result_1.As<Promise>();
......@@ -566,11 +602,9 @@ TEST(ModuleEvaluationCompletion1) {
CHECK(!try_catch.HasCaught());
}
TEST(ModuleEvaluationCompletion2) {
Isolate* isolate = CcTest::isolate();
HandleScope scope(isolate);
LocalContext env;
v8::TryCatch try_catch(isolate);
TEST_F(ModuleTest, ModuleEvaluationCompletion2) {
HandleScope scope(isolate());
v8::TryCatch try_catch(isolate());
const char* sources[] = {
"'gaga'; ",
......@@ -592,22 +626,22 @@ TEST(ModuleEvaluationCompletion2) {
};
for (auto src : sources) {
Local<String> source_text = v8_str(src);
ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
Local<String> source_text = NewString(src);
ScriptOrigin origin = ModuleOrigin(NewString("file.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
Local<Module> module =
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
CHECK_EQ(Module::kUninstantiated, module->GetStatus());
CHECK(module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
CompileSpecifierAsModuleResolveCallback)
.FromJust());
CHECK_EQ(Module::kInstantiated, module->GetStatus());
Local<Value> result_1 = module->Evaluate(env.local()).ToLocalChecked();
Local<Value> result_1 = module->Evaluate(context()).ToLocalChecked();
CHECK_EQ(Module::kEvaluated, module->GetStatus());
Local<Value> result_2 = module->Evaluate(env.local()).ToLocalChecked();
Local<Value> result_2 = module->Evaluate(context()).ToLocalChecked();
CHECK_EQ(Module::kEvaluated, module->GetStatus());
Local<Promise> promise = result_1.As<Promise>();
CHECK_EQ(promise->State(), v8::Promise::kFulfilled);
......@@ -622,123 +656,118 @@ TEST(ModuleEvaluationCompletion2) {
CHECK(!try_catch.HasCaught());
}
TEST(ModuleNamespace) {
Isolate* isolate = CcTest::isolate();
HandleScope scope(isolate);
LocalContext env;
v8::TryCatch try_catch(isolate);
TEST_F(ModuleTest, ModuleNamespace) {
HandleScope scope(isolate());
v8::TryCatch try_catch(isolate());
Local<v8::Object> ReferenceError =
CompileRun("ReferenceError")->ToObject(env.local()).ToLocalChecked();
RunJS("ReferenceError")->ToObject(context()).ToLocalChecked();
Local<String> source_text = v8_str(
Local<String> source_text = NewString(
"import {a, b} from 'export var a = 1; export let b = 2';"
"export function geta() {return a};"
"export function getb() {return b};"
"export let radio = 3;"
"export var gaga = 4;");
ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
ScriptOrigin origin = ModuleOrigin(NewString("file.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
Local<Module> module =
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
CHECK_EQ(Module::kUninstantiated, module->GetStatus());
CHECK(module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
CompileSpecifierAsModuleResolveCallback)
.FromJust());
CHECK_EQ(Module::kInstantiated, module->GetStatus());
Local<Value> ns = module->GetModuleNamespace();
CHECK_EQ(Module::kInstantiated, module->GetStatus());
Local<v8::Object> nsobj = ns->ToObject(env.local()).ToLocalChecked();
CHECK_EQ(nsobj->GetCreationContext().ToLocalChecked(), env.local());
Local<v8::Object> nsobj = ns->ToObject(context()).ToLocalChecked();
CHECK_EQ(nsobj->GetCreationContext().ToLocalChecked(), context());
// a, b
CHECK(nsobj->Get(env.local(), v8_str("a")).ToLocalChecked()->IsUndefined());
CHECK(nsobj->Get(env.local(), v8_str("b")).ToLocalChecked()->IsUndefined());
CHECK(nsobj->Get(context(), NewString("a")).ToLocalChecked()->IsUndefined());
CHECK(nsobj->Get(context(), NewString("b")).ToLocalChecked()->IsUndefined());
// geta
{
auto geta = nsobj->Get(env.local(), v8_str("geta")).ToLocalChecked();
auto geta = nsobj->Get(context(), NewString("geta")).ToLocalChecked();
auto a = geta.As<v8::Function>()
->Call(env.local(), geta, 0, nullptr)
->Call(context(), geta, 0, nullptr)
.ToLocalChecked();
CHECK(a->IsUndefined());
}
// getb
{
v8::TryCatch inner_try_catch(isolate);
auto getb = nsobj->Get(env.local(), v8_str("getb")).ToLocalChecked();
CHECK(
getb.As<v8::Function>()->Call(env.local(), getb, 0, nullptr).IsEmpty());
v8::TryCatch inner_try_catch(isolate());
auto getb = nsobj->Get(context(), NewString("getb")).ToLocalChecked();
CHECK(getb.As<v8::Function>()->Call(context(), getb, 0, nullptr).IsEmpty());
CHECK(inner_try_catch.HasCaught());
CHECK(inner_try_catch.Exception()
->InstanceOf(env.local(), ReferenceError)
->InstanceOf(context(), ReferenceError)
.FromJust());
}
// radio
{
v8::TryCatch inner_try_catch(isolate);
v8::TryCatch inner_try_catch(isolate());
// https://bugs.chromium.org/p/v8/issues/detail?id=7235
// CHECK(nsobj->Get(env.local(), v8_str("radio")).IsEmpty());
CHECK(nsobj->Get(env.local(), v8_str("radio"))
// CHECK(nsobj->Get(context(), NewString("radio")).IsEmpty());
CHECK(nsobj->Get(context(), NewString("radio"))
.ToLocalChecked()
->IsUndefined());
CHECK(inner_try_catch.HasCaught());
CHECK(inner_try_catch.Exception()
->InstanceOf(env.local(), ReferenceError)
->InstanceOf(context(), ReferenceError)
.FromJust());
}
// gaga
{
auto gaga = nsobj->Get(env.local(), v8_str("gaga")).ToLocalChecked();
auto gaga = nsobj->Get(context(), NewString("gaga")).ToLocalChecked();
CHECK(gaga->IsUndefined());
}
CHECK(!try_catch.HasCaught());
CHECK_EQ(Module::kInstantiated, module->GetStatus());
module->Evaluate(env.local()).ToLocalChecked();
module->Evaluate(context()).ToLocalChecked();
CHECK_EQ(Module::kEvaluated, module->GetStatus());
// geta
{
auto geta = nsobj->Get(env.local(), v8_str("geta")).ToLocalChecked();
auto geta = nsobj->Get(context(), NewString("geta")).ToLocalChecked();
auto a = geta.As<v8::Function>()
->Call(env.local(), geta, 0, nullptr)
->Call(context(), geta, 0, nullptr)
.ToLocalChecked();
CHECK_EQ(1, a->Int32Value(env.local()).FromJust());
CHECK_EQ(1, a->Int32Value(context()).FromJust());
}
// getb
{
auto getb = nsobj->Get(env.local(), v8_str("getb")).ToLocalChecked();
auto getb = nsobj->Get(context(), NewString("getb")).ToLocalChecked();
auto b = getb.As<v8::Function>()
->Call(env.local(), getb, 0, nullptr)
->Call(context(), getb, 0, nullptr)
.ToLocalChecked();
CHECK_EQ(2, b->Int32Value(env.local()).FromJust());
CHECK_EQ(2, b->Int32Value(context()).FromJust());
}
// radio
{
auto radio = nsobj->Get(env.local(), v8_str("radio")).ToLocalChecked();
CHECK_EQ(3, radio->Int32Value(env.local()).FromJust());
auto radio = nsobj->Get(context(), NewString("radio")).ToLocalChecked();
CHECK_EQ(3, radio->Int32Value(context()).FromJust());
}
// gaga
{
auto gaga = nsobj->Get(env.local(), v8_str("gaga")).ToLocalChecked();
CHECK_EQ(4, gaga->Int32Value(env.local()).FromJust());
auto gaga = nsobj->Get(context(), NewString("gaga")).ToLocalChecked();
CHECK_EQ(4, gaga->Int32Value(context()).FromJust());
}
CHECK(!try_catch.HasCaught());
}
TEST(ModuleEvaluationTopLevelAwait) {
Isolate* isolate = CcTest::isolate();
HandleScope scope(isolate);
LocalContext env;
v8::TryCatch try_catch(isolate);
TEST_F(ModuleTest, ModuleEvaluationTopLevelAwait) {
HandleScope scope(isolate());
v8::TryCatch try_catch(isolate());
const char* sources[] = {
"await 42",
"import 'await 42';",
......@@ -746,19 +775,19 @@ TEST(ModuleEvaluationTopLevelAwait) {
};
for (auto src : sources) {
Local<String> source_text = v8_str(src);
ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
Local<String> source_text = NewString(src);
ScriptOrigin origin = ModuleOrigin(NewString("file.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
Local<Module> module =
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
CHECK_EQ(Module::kUninstantiated, module->GetStatus());
CHECK(module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
CompileSpecifierAsModuleResolveCallback)
.FromJust());
CHECK_EQ(Module::kInstantiated, module->GetStatus());
Local<Promise> promise =
Local<Promise>::Cast(module->Evaluate(env.local()).ToLocalChecked());
Local<Promise>::Cast(module->Evaluate(context()).ToLocalChecked());
CHECK_EQ(Module::kEvaluated, module->GetStatus());
CHECK_EQ(promise->State(), v8::Promise::kFulfilled);
CHECK(promise->Result()->IsUndefined());
......@@ -766,10 +795,8 @@ TEST(ModuleEvaluationTopLevelAwait) {
}
}
TEST(ModuleEvaluationTopLevelAwaitError) {
Isolate* isolate = CcTest::isolate();
HandleScope scope(isolate);
LocalContext env;
TEST_F(ModuleTest, ModuleEvaluationTopLevelAwaitError) {
HandleScope scope(isolate());
const char* sources[] = {
"await 42; throw 'boom';",
"import 'await 42; throw \"boom\";';",
......@@ -777,24 +804,24 @@ TEST(ModuleEvaluationTopLevelAwaitError) {
};
for (auto src : sources) {
v8::TryCatch try_catch(isolate);
Local<String> source_text = v8_str(src);
ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
v8::TryCatch try_catch(isolate());
Local<String> source_text = NewString(src);
ScriptOrigin origin = ModuleOrigin(NewString("file.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
Local<Module> module =
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
CHECK_EQ(Module::kUninstantiated, module->GetStatus());
CHECK(module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
CompileSpecifierAsModuleResolveCallback)
.FromJust());
CHECK_EQ(Module::kInstantiated, module->GetStatus());
Local<Promise> promise =
Local<Promise>::Cast(module->Evaluate(env.local()).ToLocalChecked());
Local<Promise>::Cast(module->Evaluate(context()).ToLocalChecked());
CHECK_EQ(Module::kErrored, module->GetStatus());
CHECK_EQ(promise->State(), v8::Promise::kRejected);
CHECK(promise->Result()->StrictEquals(v8_str("boom")));
CHECK(module->GetException()->StrictEquals(v8_str("boom")));
CHECK(promise->Result()->StrictEquals(NewString("boom")));
CHECK(module->GetException()->StrictEquals(NewString("boom")));
// TODO(cbruni) I am not sure, but this might not be supposed to throw
// because it is async.
......@@ -830,7 +857,9 @@ void DoHostImportModuleDynamically(void* import_data) {
if (import_data_->should_resolve) {
resolver->Resolve(realm, True(isolate)).ToChecked();
} else {
resolver->Reject(realm, v8_str("boom")).ToChecked();
resolver
->Reject(realm, String::NewFromUtf8(isolate, "boom").ToLocalChecked())
.ToChecked();
}
}
......@@ -862,14 +891,12 @@ v8::MaybeLocal<v8::Promise> HostImportModuleDynamicallyCallbackReject(
} // namespace
TEST(ModuleEvaluationTopLevelAwaitDynamicImport) {
Isolate* isolate = CcTest::isolate();
HandleScope scope(isolate);
isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
isolate->SetHostImportModuleDynamicallyCallback(
TEST_F(ModuleTest, ModuleEvaluationTopLevelAwaitDynamicImport) {
HandleScope scope(isolate());
isolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
isolate()->SetHostImportModuleDynamicallyCallback(
HostImportModuleDynamicallyCallbackResolve);
LocalContext env;
v8::TryCatch try_catch(isolate);
v8::TryCatch try_catch(isolate());
const char* sources[] = {
"await import('foo');",
"import 'await import(\"foo\");';",
......@@ -877,37 +904,35 @@ TEST(ModuleEvaluationTopLevelAwaitDynamicImport) {
};
for (auto src : sources) {
Local<String> source_text = v8_str(src);
ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
Local<String> source_text = NewString(src);
ScriptOrigin origin = ModuleOrigin(NewString("file.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
Local<Module> module =
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
CHECK_EQ(Module::kUninstantiated, module->GetStatus());
CHECK(module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
CompileSpecifierAsModuleResolveCallback)
.FromJust());
CHECK_EQ(Module::kInstantiated, module->GetStatus());
Local<Promise> promise =
Local<Promise>::Cast(module->Evaluate(env.local()).ToLocalChecked());
Local<Promise>::Cast(module->Evaluate(context()).ToLocalChecked());
CHECK_EQ(Module::kEvaluated, module->GetStatus());
CHECK_EQ(promise->State(), v8::Promise::kPending);
CHECK(!try_catch.HasCaught());
isolate->PerformMicrotaskCheckpoint();
isolate()->PerformMicrotaskCheckpoint();
CHECK_EQ(promise->State(), v8::Promise::kFulfilled);
}
}
TEST(ModuleEvaluationTopLevelAwaitDynamicImportError) {
Isolate* isolate = CcTest::isolate();
HandleScope scope(isolate);
isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
isolate->SetHostImportModuleDynamicallyCallback(
TEST_F(ModuleTest, ModuleEvaluationTopLevelAwaitDynamicImportError) {
HandleScope scope(isolate());
isolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
isolate()->SetHostImportModuleDynamicallyCallback(
HostImportModuleDynamicallyCallbackReject);
LocalContext env;
v8::TryCatch try_catch(isolate);
v8::TryCatch try_catch(isolate());
const char* sources[] = {
"await import('foo');",
"import 'await import(\"foo\");';",
......@@ -915,76 +940,72 @@ TEST(ModuleEvaluationTopLevelAwaitDynamicImportError) {
};
for (auto src : sources) {
Local<String> source_text = v8_str(src);
ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
Local<String> source_text = NewString(src);
ScriptOrigin origin = ModuleOrigin(NewString("file.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
Local<Module> module =
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
CHECK_EQ(Module::kUninstantiated, module->GetStatus());
CHECK(module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
CompileSpecifierAsModuleResolveCallback)
.FromJust());
CHECK_EQ(Module::kInstantiated, module->GetStatus());
Local<Promise> promise =
Local<Promise>::Cast(module->Evaluate(env.local()).ToLocalChecked());
Local<Promise>::Cast(module->Evaluate(context()).ToLocalChecked());
CHECK_EQ(Module::kEvaluated, module->GetStatus());
CHECK_EQ(promise->State(), v8::Promise::kPending);
CHECK(!try_catch.HasCaught());
isolate->PerformMicrotaskCheckpoint();
isolate()->PerformMicrotaskCheckpoint();
CHECK_EQ(Module::kErrored, module->GetStatus());
CHECK_EQ(promise->State(), v8::Promise::kRejected);
CHECK(promise->Result()->StrictEquals(v8_str("boom")));
CHECK(module->GetException()->StrictEquals(v8_str("boom")));
CHECK(promise->Result()->StrictEquals(NewString("boom")));
CHECK(module->GetException()->StrictEquals(NewString("boom")));
CHECK(!try_catch.HasCaught());
}
}
TEST(TerminateExecutionTopLevelAwaitSync) {
Isolate* isolate = CcTest::isolate();
HandleScope scope(isolate);
LocalContext env;
v8::TryCatch try_catch(isolate);
TEST_F(ModuleTest, TerminateExecutionTopLevelAwaitSync) {
HandleScope scope(isolate());
v8::TryCatch try_catch(isolate());
env.local()
context()
->Global()
->Set(env.local(), v8_str("terminate"),
v8::Function::New(env.local(),
->Set(context(), NewString("terminate"),
v8::Function::New(context(),
[](const v8::FunctionCallbackInfo<Value>& info) {
info.GetIsolate()->TerminateExecution();
})
.ToLocalChecked())
.ToChecked();
Local<String> source_text = v8_str("terminate(); while (true) {}");
ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
Local<String> source_text = NewString("terminate(); while (true) {}");
ScriptOrigin origin = ModuleOrigin(NewString("file.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
Local<Module> module =
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
CHECK(module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
CompileSpecifierAsModuleResolveCallback)
.FromJust());
CHECK(module->Evaluate(env.local()).IsEmpty());
CHECK(module->Evaluate(context()).IsEmpty());
CHECK(try_catch.HasCaught());
CHECK(try_catch.HasTerminated());
CHECK_EQ(module->GetStatus(), Module::kErrored);
CHECK_EQ(module->GetException(), v8::Null(isolate));
CHECK_EQ(module->GetException(), v8::Null(isolate()));
}
TEST(TerminateExecutionTopLevelAwaitAsync) {
Isolate* isolate = CcTest::isolate();
HandleScope scope(isolate);
LocalContext env;
v8::TryCatch try_catch(isolate);
TEST_F(ModuleTest, TerminateExecutionTopLevelAwaitAsync) {
HandleScope scope(isolate());
v8::TryCatch try_catch(isolate());
env.local()
context()
->Global()
->Set(env.local(), v8_str("terminate"),
v8::Function::New(env.local(),
->Set(context(), NewString("terminate"),
v8::Function::New(context(),
[](const v8::FunctionCallbackInfo<Value>& info) {
info.GetIsolate()->TerminateExecution();
})
......@@ -992,31 +1013,31 @@ TEST(TerminateExecutionTopLevelAwaitAsync) {
.ToChecked();
Local<Promise::Resolver> eval_promise =
Promise::Resolver::New(env.local()).ToLocalChecked();
env.local()
Promise::Resolver::New(context()).ToLocalChecked();
context()
->Global()
->Set(env.local(), v8_str("evalPromise"), eval_promise)
->Set(context(), NewString("evalPromise"), eval_promise)
.ToChecked();
Local<String> source_text =
v8_str("await evalPromise; terminate(); while (true) {}");
ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
NewString("await evalPromise; terminate(); while (true) {}");
ScriptOrigin origin = ModuleOrigin(NewString("file.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
Local<Module> module =
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
CHECK(module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
CompileSpecifierAsModuleResolveCallback)
.FromJust());
Local<Promise> promise =
Local<Promise>::Cast(module->Evaluate(env.local()).ToLocalChecked());
Local<Promise>::Cast(module->Evaluate(context()).ToLocalChecked());
CHECK_EQ(module->GetStatus(), Module::kEvaluated);
CHECK_EQ(promise->State(), Promise::PromiseState::kPending);
CHECK(!try_catch.HasCaught());
CHECK(!try_catch.HasTerminated());
eval_promise->Resolve(env.local(), v8::Undefined(isolate)).ToChecked();
eval_promise->Resolve(context(), v8::Undefined(isolate())).ToChecked();
CHECK(try_catch.HasCaught());
CHECK(try_catch.HasTerminated());
......@@ -1036,114 +1057,118 @@ MaybeLocal<Module> ResolveCallbackForIsGraphAsyncTopLevelAwait(
Local<Context> context, Local<String> specifier,
Local<FixedArray> import_assertions, Local<Module> referrer) {
CHECK_EQ(0, import_assertions->Length());
if (specifier->StrictEquals(v8_str("./async_leaf.js"))) {
Isolate* isolate = context->GetIsolate();
if (specifier->StrictEquals(
String::NewFromUtf8(isolate, "./async_leaf.js").ToLocalChecked())) {
return async_leaf_module;
} else if (specifier->StrictEquals(v8_str("./sync_leaf.js"))) {
} else if (specifier->StrictEquals(
String::NewFromUtf8(isolate, "./sync_leaf.js")
.ToLocalChecked())) {
return sync_leaf_module;
} else if (specifier->StrictEquals(v8_str("./cycle_self.js"))) {
} else if (specifier->StrictEquals(
String::NewFromUtf8(isolate, "./cycle_self.js")
.ToLocalChecked())) {
return cycle_self_module;
} else if (specifier->StrictEquals(v8_str("./cycle_one.js"))) {
} else if (specifier->StrictEquals(
String::NewFromUtf8(isolate, "./cycle_one.js")
.ToLocalChecked())) {
return cycle_one_module;
} else {
CHECK(specifier->StrictEquals(v8_str("./cycle_two.js")));
CHECK(specifier->StrictEquals(
String::NewFromUtf8(isolate, "./cycle_two.js").ToLocalChecked()));
return cycle_two_module;
}
}
TEST(IsGraphAsyncTopLevelAwait) {
Isolate* isolate = CcTest::isolate();
HandleScope scope(isolate);
LocalContext env;
TEST_F(ModuleTest, IsGraphAsyncTopLevelAwait) {
HandleScope scope(isolate());
{
Local<String> source_text = v8_str("await notExecuted();");
ScriptOrigin origin =
ModuleOrigin(v8_str("async_leaf.js"), CcTest::isolate());
Local<String> source_text = NewString("await notExecuted();");
ScriptOrigin origin = ModuleOrigin(NewString("async_leaf.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
async_leaf_module =
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
CHECK(async_leaf_module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
ResolveCallbackForIsGraphAsyncTopLevelAwait)
.FromJust());
CHECK(async_leaf_module->IsGraphAsync());
}
{
Local<String> source_text = v8_str("notExecuted();");
ScriptOrigin origin =
ModuleOrigin(v8_str("sync_leaf.js"), CcTest::isolate());
Local<String> source_text = NewString("notExecuted();");
ScriptOrigin origin = ModuleOrigin(NewString("sync_leaf.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
sync_leaf_module =
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
CHECK(sync_leaf_module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
ResolveCallbackForIsGraphAsyncTopLevelAwait)
.FromJust());
CHECK(!sync_leaf_module->IsGraphAsync());
}
{
Local<String> source_text = v8_str("import './async_leaf.js'");
ScriptOrigin origin =
ModuleOrigin(v8_str("import_async.js"), CcTest::isolate());
Local<String> source_text = NewString("import './async_leaf.js'");
ScriptOrigin origin = ModuleOrigin(NewString("import_async.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
Local<Module> module =
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
CHECK(module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
ResolveCallbackForIsGraphAsyncTopLevelAwait)
.FromJust());
CHECK(module->IsGraphAsync());
}
{
Local<String> source_text = v8_str("import './sync_leaf.js'");
ScriptOrigin origin =
ModuleOrigin(v8_str("import_sync.js"), CcTest::isolate());
Local<String> source_text = NewString("import './sync_leaf.js'");
ScriptOrigin origin = ModuleOrigin(NewString("import_sync.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
Local<Module> module =
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
CHECK(module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
ResolveCallbackForIsGraphAsyncTopLevelAwait)
.FromJust());
CHECK(!module->IsGraphAsync());
}
{
Local<String> source_text = v8_str(
Local<String> source_text = NewString(
"import './cycle_self.js'\n"
"import './async_leaf.js'");
ScriptOrigin origin =
ModuleOrigin(v8_str("cycle_self.js"), CcTest::isolate());
ScriptOrigin origin = ModuleOrigin(NewString("cycle_self.js"), isolate());
ScriptCompiler::Source source(source_text, origin);
cycle_self_module =
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
CHECK(cycle_self_module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
ResolveCallbackForIsGraphAsyncTopLevelAwait)
.FromJust());
CHECK(cycle_self_module->IsGraphAsync());
}
{
Local<String> source_text1 = v8_str("import './cycle_two.js'");
ScriptOrigin origin1 =
ModuleOrigin(v8_str("cycle_one.js"), CcTest::isolate());
Local<String> source_text1 = NewString("import './cycle_two.js'");
ScriptOrigin origin1 = ModuleOrigin(NewString("cycle_one.js"), isolate());
ScriptCompiler::Source source1(source_text1, origin1);
cycle_one_module =
ScriptCompiler::CompileModule(isolate, &source1).ToLocalChecked();
Local<String> source_text2 = v8_str(
ScriptCompiler::CompileModule(isolate(), &source1).ToLocalChecked();
Local<String> source_text2 = NewString(
"import './cycle_one.js'\n"
"import './async_leaf.js'");
ScriptOrigin origin2 =
ModuleOrigin(v8_str("cycle_two.js"), CcTest::isolate());
ScriptOrigin origin2 = ModuleOrigin(NewString("cycle_two.js"), isolate());
ScriptCompiler::Source source2(source_text2, origin2);
cycle_two_module =
ScriptCompiler::CompileModule(isolate, &source2).ToLocalChecked();
ScriptCompiler::CompileModule(isolate(), &source2).ToLocalChecked();
CHECK(cycle_one_module
->InstantiateModule(env.local(),
->InstantiateModule(context(),
ResolveCallbackForIsGraphAsyncTopLevelAwait)
.FromJust());
CHECK(cycle_one_module->IsGraphAsync());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment