diff --git a/Libraries/LibJS/Bytecode/Interpreter.cpp b/Libraries/LibJS/Bytecode/Interpreter.cpp index 9e22a199a7b..ec718ebb27d 100644 --- a/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -208,8 +208,41 @@ ThrowCompletionOr Interpreter::run(Script& script_record, GC::Ptr executable; + if (result.type() == Completion::Type::Normal) { + auto executable_result = JS::Bytecode::Generator::generate_from_ast_node(vm, script, {}); + + if (executable_result.is_error()) { + if (auto error_string = executable_result.error().to_string(); error_string.is_error()) + result = vm.template throw_completion(vm.error_message(JS::VM::ErrorMessage::OutOfMemory)); + else if (error_string = String::formatted("TODO({})", error_string.value()); error_string.is_error()) + result = vm.template throw_completion(vm.error_message(JS::VM::ErrorMessage::OutOfMemory)); + else + result = vm.template throw_completion(error_string.release_value()); + } else { + executable = executable_result.release_value(); + + if (g_dump_bytecode) + executable->dump(); + } + } + + u32 registers_and_constants_and_locals_count = 0; + if (executable) { + registers_and_constants_and_locals_count = executable->number_of_registers + executable->constants.size() + executable->local_variable_names.size(); + } + // 2. Let scriptContext be a new ECMAScript code execution context. - auto script_context = ExecutionContext::create(); + auto script_context = ExecutionContext::create(registers_and_constants_and_locals_count); // 3. Set the Function of scriptContext to null. // NOTE: This was done during execution context construction. @@ -239,38 +272,14 @@ ThrowCompletionOr Interpreter::run(Script& script_record, GC::Ptr(vm.error_message(JS::VM::ErrorMessage::OutOfMemory)); - else if (error_string = String::formatted("TODO({})", error_string.value()); error_string.is_error()) - result = vm.template throw_completion(vm.error_message(JS::VM::ErrorMessage::OutOfMemory)); - else - result = vm.template throw_completion(error_string.release_value()); - } else { - auto executable = executable_result.release_value(); - - if (g_dump_bytecode) - executable->dump(); - - // a. Set result to the result of evaluating script. - auto result_or_error = run_executable(*executable, {}, {}); - if (result_or_error.value.is_error()) - result = result_or_error.value.release_error(); - else { - result = result_or_error.return_register_value.is_special_empty_value() ? normal_completion(js_undefined()) : result_or_error.return_register_value; - } + auto result_or_error = run_executable(*executable, {}, {}); + if (result_or_error.value.is_error()) + result = result_or_error.value.release_error(); + else { + result = result_or_error.return_register_value.is_special_empty_value() ? normal_completion(js_undefined()) : result_or_error.return_register_value; } // b. If result is a normal completion and result.[[Value]] is empty, then @@ -732,8 +741,7 @@ Interpreter::ResultAndReturnRegister Interpreter::run_executable(Executable& exe auto& running_execution_context = vm().running_execution_context(); u32 registers_and_constants_and_locals_count = executable.number_of_registers + executable.constants.size() + executable.local_variable_names.size(); - if (running_execution_context.registers_and_constants_and_locals.size() < registers_and_constants_and_locals_count) - running_execution_context.registers_and_constants_and_locals.resize_with_default_value(registers_and_constants_and_locals_count, js_special_empty_value()); + VERIFY(registers_and_constants_and_locals_count <= running_execution_context.registers_and_constants_and_locals.size()); TemporaryChange restore_running_execution_context { m_running_execution_context, &running_execution_context }; TemporaryChange restore_arguments { m_arguments, running_execution_context.arguments.span() }; diff --git a/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Libraries/LibJS/Runtime/AbstractOperations.cpp index 306fda013fc..f5af52226c7 100644 --- a/Libraries/LibJS/Runtime/AbstractOperations.cpp +++ b/Libraries/LibJS/Runtime/AbstractOperations.cpp @@ -646,8 +646,23 @@ ThrowCompletionOr perform_eval(VM& vm, Value x, CallerMode strict_caller, // 19. If runningContext is not already suspended, suspend runningContext. // NOTE: Done by the push on step 27. + // NOTE: Spec steps are rearranged in order to compute number of registers+constants+locals before construction of the execution context. + + // 28. Let result be Completion(EvalDeclarationInstantiation(body, varEnv, lexEnv, privateEnv, strictEval)). + TRY(eval_declaration_instantiation(vm, program, variable_environment, lexical_environment, private_environment, strict_eval)); + + // 29. If result.[[Type]] is normal, then + // a. Set result to the result of evaluating body. + auto executable_result = Bytecode::Generator::generate_from_ast_node(vm, program, {}); + if (executable_result.is_error()) + return vm.throw_completion(ErrorType::NotImplemented, TRY_OR_THROW_OOM(vm, executable_result.error().to_string())); + auto executable = executable_result.release_value(); + executable->name = "eval"_fly_string; + if (Bytecode::g_dump_bytecode) + executable->dump(); + // 20. Let evalContext be a new ECMAScript code execution context. - auto eval_context = ExecutionContext::create(); + auto eval_context = ExecutionContext::create(executable->number_of_registers + executable->constants.size() + executable->local_variable_names.size()); // 21. Set evalContext's Function to null. // NOTE: This was done in the construction of eval_context. @@ -680,21 +695,8 @@ ThrowCompletionOr perform_eval(VM& vm, Value x, CallerMode strict_caller, vm.pop_execution_context(); }; - // 28. Let result be Completion(EvalDeclarationInstantiation(body, varEnv, lexEnv, privateEnv, strictEval)). - TRY(eval_declaration_instantiation(vm, program, variable_environment, lexical_environment, private_environment, strict_eval)); - Optional eval_result; - // 29. If result.[[Type]] is normal, then - // a. Set result to the result of evaluating body. - auto executable_result = Bytecode::Generator::generate_from_ast_node(vm, program, {}); - if (executable_result.is_error()) - return vm.throw_completion(ErrorType::NotImplemented, TRY_OR_THROW_OOM(vm, executable_result.error().to_string())); - - auto executable = executable_result.release_value(); - executable->name = "eval"_fly_string; - if (Bytecode::g_dump_bytecode) - executable->dump(); auto result_or_error = vm.bytecode_interpreter().run_executable(*executable, {}); if (result_or_error.value.is_error()) return result_or_error.value.release_error(); diff --git a/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp b/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp index 4acb9be3b9d..d818ce09edc 100644 --- a/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp +++ b/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp @@ -489,7 +489,18 @@ ThrowCompletionOr ECMAScriptFunctionObject::internal_call(Value this_argu // 1. Let callerContext be the running execution context. // NOTE: No-op, kept by the VM in its execution context stack. - auto callee_context = ExecutionContext::create(); + if (!m_bytecode_executable) { + if (!ecmascript_code().bytecode_executable()) { + if (is_module_wrapper()) { + const_cast(ecmascript_code()).set_bytecode_executable(TRY(Bytecode::compile(vm, ecmascript_code(), kind(), name()))); + } else { + const_cast(ecmascript_code()).set_bytecode_executable(TRY(Bytecode::compile(vm, *this))); + } + } + m_bytecode_executable = ecmascript_code().bytecode_executable(); + } + + auto callee_context = ExecutionContext::create(m_bytecode_executable->number_of_registers + m_bytecode_executable->constants.size() + m_bytecode_executable->local_variable_names.size()); // Non-standard callee_context->arguments.ensure_capacity(max(arguments_list.size(), formal_parameters().size())); @@ -546,7 +557,18 @@ ThrowCompletionOr> ECMAScriptFunctionObject::internal_construct( { auto& vm = this->vm(); - auto callee_context = ExecutionContext::create(); + if (!m_bytecode_executable) { + if (!ecmascript_code().bytecode_executable()) { + if (is_module_wrapper()) { + const_cast(ecmascript_code()).set_bytecode_executable(TRY(Bytecode::compile(vm, ecmascript_code(), kind(), name()))); + } else { + const_cast(ecmascript_code()).set_bytecode_executable(TRY(Bytecode::compile(vm, *this))); + } + } + m_bytecode_executable = ecmascript_code().bytecode_executable(); + } + + auto callee_context = ExecutionContext::create(m_bytecode_executable->number_of_registers + m_bytecode_executable->constants.size() + m_bytecode_executable->local_variable_names.size()); // Non-standard callee_context->arguments.ensure_capacity(max(arguments_list.size(), formal_parameters().size())); @@ -890,19 +912,6 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body() auto& vm = this->vm(); auto& realm = *vm.current_realm(); - if (!m_bytecode_executable) { - if (!ecmascript_code().bytecode_executable()) { - if (is_module_wrapper()) { - const_cast(ecmascript_code()).set_bytecode_executable(TRY(Bytecode::compile(vm, ecmascript_code(), kind(), name()))); - } else { - const_cast(ecmascript_code()).set_bytecode_executable(TRY(Bytecode::compile(vm, *this))); - } - } - m_bytecode_executable = ecmascript_code().bytecode_executable(); - } - - vm.running_execution_context().registers_and_constants_and_locals.resize_with_default_value(local_variables_names().size() + m_bytecode_executable->number_of_registers + m_bytecode_executable->constants.size(), js_special_empty_value()); - auto result_and_frame = vm.bytecode_interpreter().run_executable(*m_bytecode_executable, {}); if (result_and_frame.value.is_error()) diff --git a/Libraries/LibJS/Runtime/ExecutionContext.cpp b/Libraries/LibJS/Runtime/ExecutionContext.cpp index 57af2c2c5e3..7e37bb203c8 100644 --- a/Libraries/LibJS/Runtime/ExecutionContext.cpp +++ b/Libraries/LibJS/Runtime/ExecutionContext.cpp @@ -33,9 +33,11 @@ private: static NeverDestroyed s_execution_context_allocator; -NonnullOwnPtr ExecutionContext::create() +NonnullOwnPtr ExecutionContext::create(u32 count) { - return s_execution_context_allocator->allocate(); + auto execution_context = s_execution_context_allocator->allocate(); + execution_context->registers_and_constants_and_locals.resize_with_default_value(count, js_special_empty_value()); + return execution_context; } void ExecutionContext::operator delete(void* ptr) @@ -53,7 +55,7 @@ ExecutionContext::~ExecutionContext() NonnullOwnPtr ExecutionContext::copy() const { - auto copy = create(); + auto copy = create(registers_and_constants_and_locals.size()); copy->function = function; copy->realm = realm; copy->script_or_module = script_or_module; diff --git a/Libraries/LibJS/Runtime/ExecutionContext.h b/Libraries/LibJS/Runtime/ExecutionContext.h index 79643cdd614..fd62748a725 100644 --- a/Libraries/LibJS/Runtime/ExecutionContext.h +++ b/Libraries/LibJS/Runtime/ExecutionContext.h @@ -32,7 +32,7 @@ struct CachedSourceRange : public RefCounted { // 9.4 Execution Contexts, https://tc39.es/ecma262/#sec-execution-contexts struct ExecutionContext { - static NonnullOwnPtr create(); + static NonnullOwnPtr create(u32); [[nodiscard]] NonnullOwnPtr copy() const; ~ExecutionContext(); @@ -86,7 +86,12 @@ public: bool is_strict_mode { false }; Vector arguments; + +private: + friend class Bytecode::Interpreter; Vector registers_and_constants_and_locals; + +public: Vector unwind_contexts; Vector> previously_scheduled_jumps; Vector> saved_lexical_environments; diff --git a/Libraries/LibJS/Runtime/NativeFunction.cpp b/Libraries/LibJS/Runtime/NativeFunction.cpp index 6ff303cb446..65aca384e87 100644 --- a/Libraries/LibJS/Runtime/NativeFunction.cpp +++ b/Libraries/LibJS/Runtime/NativeFunction.cpp @@ -119,7 +119,7 @@ ThrowCompletionOr NativeFunction::internal_call(Value this_argument, Read // 2. If callerContext is not already suspended, suspend callerContext. // 3. Let calleeContext be a new execution context. - auto callee_context = ExecutionContext::create(); + auto callee_context = ExecutionContext::create(0); // 4. Set the Function of calleeContext to F. callee_context->function = this; @@ -180,7 +180,7 @@ ThrowCompletionOr> NativeFunction::internal_construct(ReadonlySp // 2. If callerContext is not already suspended, suspend callerContext. // 3. Let calleeContext be a new execution context. - auto callee_context = ExecutionContext::create(); + auto callee_context = ExecutionContext::create(0); // 4. Set the Function of calleeContext to F. callee_context->function = this; diff --git a/Libraries/LibJS/Runtime/Realm.cpp b/Libraries/LibJS/Runtime/Realm.cpp index 283dba344c9..e63946719c5 100644 --- a/Libraries/LibJS/Runtime/Realm.cpp +++ b/Libraries/LibJS/Runtime/Realm.cpp @@ -36,7 +36,7 @@ ThrowCompletionOr> Realm::initialize_host_define // FIXME: 6. Set realm.[[TemplateMap]] to a new empty List. // 7. Let newContext be a new execution context. - auto new_context = ExecutionContext::create(); + auto new_context = ExecutionContext::create(0); // 8. Set the Function of newContext to null. new_context->function = nullptr; diff --git a/Libraries/LibJS/Runtime/ShadowRealm.cpp b/Libraries/LibJS/Runtime/ShadowRealm.cpp index f52868a1acc..cde4c9fbd0b 100644 --- a/Libraries/LibJS/Runtime/ShadowRealm.cpp +++ b/Libraries/LibJS/Runtime/ShadowRealm.cpp @@ -127,8 +127,14 @@ ThrowCompletionOr perform_shadow_realm_eval(VM& vm, StringView source_tex // 5. If runningContext is not already suspended, suspend runningContext. // NOTE: This would be unused due to step 9 and is omitted for that reason. + auto maybe_executable = Bytecode::compile(vm, program, FunctionKind::Normal, "ShadowRealmEval"_fly_string); + if (maybe_executable.is_error()) + return vm.throw_completion(ErrorType::ShadowRealmEvaluateAbruptCompletion); + auto executable = maybe_executable.release_value(); + // 6. Let evalContext be GetShadowRealmContext(evalRealm, strictEval). - auto eval_context = get_shadow_realm_context(eval_realm, strict_eval); + u32 registers_and_constants_and_locals_count = executable->number_of_registers + executable->constants.size() + executable->local_variable_names.size(); + auto eval_context = get_shadow_realm_context(eval_realm, strict_eval, registers_and_constants_and_locals_count); // 7. Let lexEnv be evalContext's LexicalEnvironment. auto lexical_environment = eval_context->lexical_environment; @@ -147,19 +153,12 @@ ThrowCompletionOr perform_shadow_realm_eval(VM& vm, StringView source_tex // 11. If result.[[Type]] is normal, then if (!eval_result.is_throw_completion()) { // a. Set result to the result of evaluating body. - auto maybe_executable = Bytecode::compile(vm, program, FunctionKind::Normal, "ShadowRealmEval"_fly_string); - if (maybe_executable.is_error()) { - result = maybe_executable.release_error(); + auto result_and_return_register = vm.bytecode_interpreter().run_executable(*executable, {}); + if (result_and_return_register.value.is_error()) { + result = result_and_return_register.value.release_error(); } else { - auto executable = maybe_executable.release_value(); - - auto result_and_return_register = vm.bytecode_interpreter().run_executable(*executable, {}); - if (result_and_return_register.value.is_error()) { - result = result_and_return_register.value.release_error(); - } else { - // Resulting value is in the accumulator. - result = result_and_return_register.return_register_value.is_special_empty_value() ? js_undefined() : result_and_return_register.return_register_value; - } + // Resulting value is in the accumulator. + result = result_and_return_register.return_register_value.is_special_empty_value() ? js_undefined() : result_and_return_register.return_register_value; } } @@ -195,7 +194,7 @@ ThrowCompletionOr shadow_realm_import_value(VM& vm, String specifier_stri auto& realm = *vm.current_realm(); // 1. Let evalContext be GetShadowRealmContext(evalRealm, true). - auto eval_context = get_shadow_realm_context(eval_realm, true); + auto eval_context = get_shadow_realm_context(eval_realm, true, 0); // 2. Let innerCapability be ! NewPromiseCapability(%Promise%). auto inner_capability = MUST(new_promise_capability(vm, realm.intrinsics().promise_constructor())); @@ -288,7 +287,7 @@ ThrowCompletionOr get_wrapped_value(VM& vm, Realm& caller_realm, Value va } // 3.1.7 GetShadowRealmContext ( shadowRealmRecord, strictEval ), https://tc39.es/proposal-shadowrealm/#sec-getshadowrealmcontext -NonnullOwnPtr get_shadow_realm_context(Realm& shadow_realm, bool strict_eval) +NonnullOwnPtr get_shadow_realm_context(Realm& shadow_realm, bool strict_eval, u32 registers_and_constants_and_locals_count) { // 1. Let lexEnv be NewDeclarativeEnvironment(shadowRealmRecord.[[GlobalEnv]]). Environment* lexical_environment = new_declarative_environment(shadow_realm.global_environment()).ptr(); @@ -301,7 +300,7 @@ NonnullOwnPtr get_shadow_realm_context(Realm& shadow_realm, bo variable_environment = lexical_environment; // 4. Let context be a new ECMAScript code execution context. - auto context = ExecutionContext::create(); + auto context = ExecutionContext::create(registers_and_constants_and_locals_count); // 5. Set context's Function to null. context->function = nullptr; diff --git a/Libraries/LibJS/Runtime/ShadowRealm.h b/Libraries/LibJS/Runtime/ShadowRealm.h index c3a8b85ee3f..6c178094dd8 100644 --- a/Libraries/LibJS/Runtime/ShadowRealm.h +++ b/Libraries/LibJS/Runtime/ShadowRealm.h @@ -37,6 +37,6 @@ ThrowCompletionOr copy_name_and_length(VM&, FunctionObject& function, Func ThrowCompletionOr perform_shadow_realm_eval(VM&, StringView source_text, Realm& caller_realm, Realm& eval_realm); ThrowCompletionOr shadow_realm_import_value(VM&, String specifier_string, String export_name_string, Realm& caller_realm, Realm& eval_realm); ThrowCompletionOr get_wrapped_value(VM&, Realm& caller_realm, Value); -NonnullOwnPtr get_shadow_realm_context(Realm& shadow_realm, bool strict_eval); +NonnullOwnPtr get_shadow_realm_context(Realm& shadow_realm, bool strict_eval, u32 registers_and_constants_and_locals_count); } diff --git a/Libraries/LibJS/Runtime/WrappedFunction.cpp b/Libraries/LibJS/Runtime/WrappedFunction.cpp index 19a2260b3ba..0625525d26d 100644 --- a/Libraries/LibJS/Runtime/WrappedFunction.cpp +++ b/Libraries/LibJS/Runtime/WrappedFunction.cpp @@ -62,7 +62,7 @@ ThrowCompletionOr WrappedFunction::internal_call(Value this_argument, Rea // NOTE: No-op, kept by the VM in its execution context stack. // 2. Let calleeContext be PrepareForWrappedFunctionCall(F). - auto callee_context = ExecutionContext::create(); + auto callee_context = ExecutionContext::create(0); prepare_for_wrapped_function_call(*this, *callee_context); // 3. Assert: calleeContext is now the running execution context. diff --git a/Libraries/LibJS/SourceTextModule.cpp b/Libraries/LibJS/SourceTextModule.cpp index 855271fd945..fe24c9bd27a 100644 --- a/Libraries/LibJS/SourceTextModule.cpp +++ b/Libraries/LibJS/SourceTextModule.cpp @@ -107,7 +107,7 @@ SourceTextModule::SourceTextModule(Realm& realm, StringView filename, Script::Ho RefPtr default_export) : CyclicModule(realm, filename, has_top_level_await, move(requested_modules), host_defined) , m_ecmascript_code(move(body)) - , m_execution_context(ExecutionContext::create()) + , m_execution_context(ExecutionContext::create(0)) , m_import_entries(move(import_entries)) , m_local_export_entries(move(local_export_entries)) , m_indirect_export_entries(move(indirect_export_entries)) @@ -680,8 +680,28 @@ ThrowCompletionOr SourceTextModule::execute_module(VM& vm, GC::Ptr executable; + if (!m_has_top_level_await) { + Completion result; + + auto maybe_executable = Bytecode::compile(vm, m_ecmascript_code, FunctionKind::Normal, "ShadowRealmEval"_fly_string); + if (maybe_executable.is_error()) { + result = maybe_executable.release_error(); + } else { + executable = maybe_executable.release_value(); + } + + if (result.is_error()) + return result.release_error(); + } + + u32 registers_and_constants_and_locals_count = 0; + if (executable) { + registers_and_constants_and_locals_count = executable->number_of_registers + executable->constants.size() + executable->local_variable_names.size(); + } + // 1. Let moduleContext be a new ECMAScript code execution context. - auto module_context = ExecutionContext::create(); + auto module_context = ExecutionContext::create(registers_and_constants_and_locals_count); // Note: This is not in the spec but we require it. module_context->is_strict_mode = true; @@ -720,19 +740,11 @@ ThrowCompletionOr SourceTextModule::execute_module(VM& vm, GC::Ptr SyntheticModule::evaluate(VM& vm) // NOTE: Done by the push on step 8. // 2. Let moduleContext be a new ECMAScript code execution context. - auto module_context = ExecutionContext::create(); + auto module_context = ExecutionContext::create(0); // 3. Set the Function of moduleContext to null. // Note: This is the default value. diff --git a/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Libraries/LibWeb/Bindings/MainThreadVM.cpp index a449363f224..2eb303895fb 100644 --- a/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -281,7 +281,7 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) // FIXME: We need to setup a dummy execution context in case a JS::NativeFunction is called when processing the job. // This is because JS::NativeFunction::call excepts something to be on the execution context stack to be able to get the caller context to initialize the environment. // Do note that the JS spec gives _no_ guarantee that the execution context stack has something on it if HostEnqueuePromiseJob was called with a null realm: https://tc39.es/ecma262/#job-preparedtoevaluatecode - dummy_execution_context = JS::ExecutionContext::create(); + dummy_execution_context = JS::ExecutionContext::create(0); dummy_execution_context->script_or_module = script_or_module; vm.push_execution_context(*dummy_execution_context); } @@ -324,7 +324,7 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) // 4. If active script is not null, set script execution context to a new JavaScript execution context, with its Function field set to null, // its Realm field set to active script's realm, and its ScriptOrModule set to active script's record. if (script) { - script_execution_context = JS::ExecutionContext::create(); + script_execution_context = JS::ExecutionContext::create(0); script_execution_context->function = nullptr; script_execution_context->realm = &script->realm(); if (is(script)) { @@ -585,7 +585,7 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) // 5. Perform FinishLoadingImportedModule(referrer, moduleRequest, payload, completion). // NON-STANDARD: To ensure that LibJS can find the module on the stack, we push a new execution context. - auto module_execution_context = JS::ExecutionContext::create(); + auto module_execution_context = JS::ExecutionContext::create(0); module_execution_context->realm = realm; if (module) module_execution_context->script_or_module = GC::Ref { *module }; diff --git a/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp b/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp index 0368a1dd85e..34bbee14ba4 100644 --- a/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp +++ b/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp @@ -102,7 +102,7 @@ JS::Promise* JavaScriptModuleScript::run(PreventErrorReporting) VERIFY(record); // NON-STANDARD: To ensure that LibJS can find the module on the stack, we push a new execution context. - auto module_execution_context = JS::ExecutionContext::create(); + auto module_execution_context = JS::ExecutionContext::create(0); module_execution_context->realm = &realm; module_execution_context->script_or_module = GC::Ref { *record }; vm().push_execution_context(*module_execution_context);