| // Copyright 2016 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 "src/flags.h" |
| |
| #include "test/cctest/cctest.h" |
| |
| using v8::Context; |
| using v8::HandleScope; |
| using v8::Isolate; |
| using v8::Local; |
| using v8::MaybeLocal; |
| using v8::Module; |
| using v8::ScriptCompiler; |
| using v8::ScriptOrigin; |
| using v8::String; |
| using v8::Value; |
| |
| static MaybeLocal<Module> AlwaysEmptyResolveCallback(Local<Context> context, |
| Local<String> specifier, |
| Local<Module> referrer, |
| Local<Value> data) { |
| return MaybeLocal<Module>(); |
| } |
| |
| static int g_count = 0; |
| static MaybeLocal<Module> FailOnSecondCallResolveCallback( |
| Local<Context> context, Local<String> specifier, Local<Module> referrer, |
| Local<Value> data) { |
| if (g_count++ > 0) return MaybeLocal<Module>(); |
| Local<String> source_text = v8_str(""); |
| ScriptOrigin origin(v8_str("module.js")); |
| ScriptCompiler::Source source(source_text, origin); |
| return ScriptCompiler::CompileModule(CcTest::isolate(), &source) |
| .ToLocalChecked(); |
| } |
| |
| TEST(ModuleInstantiationFailures) { |
| Isolate* isolate = CcTest::isolate(); |
| HandleScope scope(isolate); |
| LocalContext env; |
| |
| Local<String> source_text = v8_str( |
| "import './foo.js';" |
| "export {} from './bar.js';"); |
| ScriptOrigin origin(v8_str("file.js")); |
| ScriptCompiler::Source source(source_text, origin); |
| Local<Module> module = |
| ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); |
| CHECK_EQ(2, module->GetModuleRequestsLength()); |
| CHECK(v8_str("./foo.js")->StrictEquals(module->GetModuleRequest(0))); |
| CHECK(v8_str("./bar.js")->StrictEquals(module->GetModuleRequest(1))); |
| |
| // Instantiation should fail. |
| CHECK(!module->Instantiate(env.local(), AlwaysEmptyResolveCallback)); |
| |
| // Start over again... |
| module = ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); |
| |
| // Instantiation should fail if a sub-module fails to resolve. |
| g_count = 0; |
| CHECK(!module->Instantiate(env.local(), FailOnSecondCallResolveCallback)); |
| } |
| |
| static MaybeLocal<Module> CompileSpecifierAsModuleResolveCallback( |
| Local<Context> context, Local<String> specifier, Local<Module> referrer, |
| Local<Value> data) { |
| ScriptOrigin origin(v8_str("module.js")); |
| ScriptCompiler::Source source(specifier, origin); |
| return ScriptCompiler::CompileModule(CcTest::isolate(), &source) |
| .ToLocalChecked(); |
| } |
| |
| TEST(ModuleEvaluation) { |
| Isolate* isolate = CcTest::isolate(); |
| HandleScope scope(isolate); |
| LocalContext env; |
| |
| Local<String> source_text = v8_str( |
| "import 'Object.expando = 5';" |
| "import 'Object.expando *= 2';"); |
| ScriptOrigin origin(v8_str("file.js")); |
| ScriptCompiler::Source source(source_text, origin); |
| Local<Module> module = |
| ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); |
| CHECK(module->Instantiate(env.local(), |
| CompileSpecifierAsModuleResolveCallback)); |
| CHECK(!module->Evaluate(env.local()).IsEmpty()); |
| ExpectInt32("Object.expando", 10); |
| } |