@@ -24649,6 +24649,122 @@ TEST(ImportFromSyntheticModuleThrow) {
24649
24649
CHECK(try_catch.HasCaught());
24650
24650
}
24651
24651
24652
+ namespace {
24653
+
24654
+ v8::MaybeLocal<Module> ModuleEvaluateTerminateExecutionResolveCallback(
24655
+ Local<Context> context, Local<String> specifier,
24656
+ Local<FixedArray> import_assertions, Local<Module> referrer) {
24657
+ v8::Isolate* isolate = context->GetIsolate();
24658
+
24659
+ Local<String> url = v8_str("www.test.com");
24660
+ Local<String> source_text = v8_str("await Promise.resolve();");
24661
+ v8::ScriptOrigin origin(isolate, url, 0, 0, false, -1, Local<v8::Value>(),
24662
+ false, false, true);
24663
+ v8::ScriptCompiler::Source source(source_text, origin);
24664
+ Local<Module> module =
24665
+ v8::ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
24666
+ module
24667
+ ->InstantiateModule(context,
24668
+ ModuleEvaluateTerminateExecutionResolveCallback)
24669
+ .ToChecked();
24670
+
24671
+ CHECK_EQ(module->GetStatus(), Module::kInstantiated);
24672
+ return module;
24673
+ }
24674
+
24675
+ void ModuleEvaluateTerminateExecution(
24676
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
24677
+ v8::Isolate::GetCurrent()->TerminateExecution();
24678
+ }
24679
+ } // namespace
24680
+
24681
+ TEST(ModuleEvaluateTerminateExecution) {
24682
+ LocalContext env;
24683
+ v8::Isolate* isolate = env->GetIsolate();
24684
+ v8::Isolate::Scope iscope(isolate);
24685
+ v8::HandleScope scope(isolate);
24686
+ v8::Local<v8::Context> context = v8::Context::New(isolate);
24687
+ v8::Context::Scope cscope(context);
24688
+
24689
+ v8::Local<v8::Function> terminate_execution =
24690
+ v8::Function::New(context, ModuleEvaluateTerminateExecution,
24691
+ v8_str("terminate_execution"))
24692
+ .ToLocalChecked();
24693
+ context->Global()
24694
+ ->Set(context, v8_str("terminate_execution"), terminate_execution)
24695
+ .FromJust();
24696
+
24697
+ Local<String> url = v8_str("www.test.com");
24698
+ Local<String> source_text = v8_str(
24699
+ "terminate_execution();"
24700
+ "await Promise.resolve();");
24701
+ v8::ScriptOrigin origin(isolate, url, 0, 0, false, -1, Local<v8::Value>(),
24702
+ false, false, true);
24703
+ v8::ScriptCompiler::Source source(source_text, origin);
24704
+ Local<Module> module =
24705
+ v8::ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
24706
+ module
24707
+ ->InstantiateModule(context,
24708
+ ModuleEvaluateTerminateExecutionResolveCallback)
24709
+ .ToChecked();
24710
+
24711
+ CHECK_EQ(module->GetStatus(), Module::kInstantiated);
24712
+ TryCatch try_catch(isolate);
24713
+ v8::MaybeLocal<Value> completion_value = module->Evaluate(context);
24714
+ CHECK(completion_value.IsEmpty());
24715
+
24716
+ CHECK_EQ(module->GetStatus(), Module::kErrored);
24717
+ CHECK(try_catch.HasCaught());
24718
+ CHECK(try_catch.HasTerminated());
24719
+ }
24720
+
24721
+ TEST(ModuleEvaluateImportTerminateExecution) {
24722
+ LocalContext env;
24723
+ v8::Isolate* isolate = env->GetIsolate();
24724
+ v8::Isolate::Scope iscope(isolate);
24725
+ v8::HandleScope scope(isolate);
24726
+ v8::Local<v8::Context> context = v8::Context::New(isolate);
24727
+ v8::Context::Scope cscope(context);
24728
+
24729
+ v8::Local<v8::Function> terminate_execution =
24730
+ v8::Function::New(context, ModuleEvaluateTerminateExecution,
24731
+ v8_str("terminate_execution"))
24732
+ .ToLocalChecked();
24733
+ context->Global()
24734
+ ->Set(context, v8_str("terminate_execution"), terminate_execution)
24735
+ .FromJust();
24736
+
24737
+ Local<String> url = v8_str("www.test.com");
24738
+ Local<String> source_text = v8_str(
24739
+ "import './synthetic.module';"
24740
+ "terminate_execution();"
24741
+ "await Promise.resolve();");
24742
+ v8::ScriptOrigin origin(isolate, url, 0, 0, false, -1, Local<v8::Value>(),
24743
+ false, false, true);
24744
+ v8::ScriptCompiler::Source source(source_text, origin);
24745
+ Local<Module> module =
24746
+ v8::ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
24747
+ module
24748
+ ->InstantiateModule(context,
24749
+ ModuleEvaluateTerminateExecutionResolveCallback)
24750
+ .ToChecked();
24751
+
24752
+ CHECK_EQ(module->GetStatus(), Module::kInstantiated);
24753
+ TryCatch try_catch(isolate);
24754
+ v8::MaybeLocal<Value> completion_value = module->Evaluate(context);
24755
+ Local<v8::Promise> promise(
24756
+ Local<v8::Promise>::Cast(completion_value.ToLocalChecked()));
24757
+ CHECK_EQ(promise->State(), v8::Promise::kPending);
24758
+ isolate->PerformMicrotaskCheckpoint();
24759
+
24760
+ // The exception thrown by terminate execution is not catchable by JavaScript
24761
+ // so the promise can not be settled.
24762
+ CHECK_EQ(promise->State(), v8::Promise::kPending);
24763
+ CHECK_EQ(module->GetStatus(), Module::kEvaluated);
24764
+ CHECK(try_catch.HasCaught());
24765
+ CHECK(try_catch.HasTerminated());
24766
+ }
24767
+
24652
24768
// Tests that the code cache does not confuse the same source code compiled as a
24653
24769
// script and as a module.
24654
24770
TEST(CodeCacheModuleScriptMismatch) {
0 commit comments