diff --git a/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp b/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp index 316e6f4140f..ba5f56fb032 100644 --- a/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp +++ b/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp @@ -124,57 +124,33 @@ ThrowCompletionOr perform_shadow_realm_eval(VM& vm, StringView source_tex auto strict_eval = program->is_strict_mode(); // 4. Let runningContext be the running execution context. - // NOTE: This would be unused due to step 11 and is omitted for that reason. + // 5. If runningContext is not already suspended, suspend runningContext. + // NOTE: This would be unused due to step 9 and is omitted for that reason. - // 5. Let lexEnv be NewDeclarativeEnvironment(evalRealm.[[GlobalEnv]]). - Environment* lexical_environment = new_declarative_environment(eval_realm.global_environment()).ptr(); + // 6. Let evalContext be GetShadowRealmContext(evalRealm, strictEval). + auto eval_context = get_shadow_realm_context(eval_realm, strict_eval); - // 6. Let varEnv be evalRealm.[[GlobalEnv]]. - Environment* variable_environment = &eval_realm.global_environment(); + // 7. Let lexEnv be evalContext's LexicalEnvironment. + auto lexical_environment = eval_context->lexical_environment; - // 7. If strictEval is true, set varEnv to lexEnv. - if (strict_eval) - variable_environment = lexical_environment; + // 8. Let varEnv be evalContext's VariableEnvironment. + auto variable_environment = eval_context->variable_environment; - // 8. If runningContext is not already suspended, suspend runningContext. - // NOTE: We don't support this concept yet. - - // 9. Let evalContext be a new ECMAScript code execution context. - auto eval_context = ExecutionContext::create(); - - // 10. Set evalContext's Function to null. - eval_context->function = nullptr; - - // 11. Set evalContext's Realm to evalRealm. - eval_context->realm = &eval_realm; - - // 12. Set evalContext's ScriptOrModule to null. - // Note: This is already the default value. - - // 13. Set evalContext's VariableEnvironment to varEnv. - eval_context->variable_environment = variable_environment; - - // 14. Set evalContext's LexicalEnvironment to lexEnv. - eval_context->lexical_environment = lexical_environment; - - // Non-standard - eval_context->is_strict_mode = strict_eval; - - // 15. Push evalContext onto the execution context stack; evalContext is now the running execution context. + // 9. Push evalContext onto the execution context stack; evalContext is now the running execution context. TRY(vm.push_execution_context(*eval_context, {})); - // 16. Let result be Completion(EvalDeclarationInstantiation(body, varEnv, lexEnv, null, strictEval)). + // 10. Let result be Completion(EvalDeclarationInstantiation(body, varEnv, lexEnv, null, strictEval)). auto eval_result = eval_declaration_instantiation(vm, program, variable_environment, lexical_environment, nullptr, strict_eval); Completion result; - // 17. If result.[[Type]] is normal, then + // 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"sv); - if (maybe_executable.is_error()) + if (maybe_executable.is_error()) { result = maybe_executable.release_error(); - else { + } else { auto executable = maybe_executable.release_value(); auto result_and_return_register = vm.bytecode_interpreter().run_executable(*executable, {}); @@ -187,24 +163,27 @@ ThrowCompletionOr perform_shadow_realm_eval(VM& vm, StringView source_tex } } - // 18. If result.[[Type]] is normal and result.[[Value]] is empty, then + // 12. If result.[[Type]] is normal and result.[[Value]] is empty, then if (result.type() == Completion::Type::Normal && !result.value().has_value()) { // a. Set result to NormalCompletion(undefined). result = normal_completion(js_undefined()); } - // 19. Suspend evalContext and remove it from the execution context stack. + // 13. Suspend evalContext and remove it from the execution context stack. // NOTE: We don't support this concept yet. vm.pop_execution_context(); - // 20. Resume the context that is now on the top of the execution context stack as the running execution context. + // 14. Resume the context that is now on the top of the execution context stack as the running execution context. // NOTE: We don't support this concept yet. - // 21. If result.[[Type]] is not normal, throw a TypeError exception. - if (result.type() != Completion::Type::Normal) + // 15. If result.[[Type]] is not normal, then + if (result.type() != Completion::Type::Normal) { + // a. Let copiedError be CreateTypeErrorCopy(callerRealm, result.[[Value]]). + // b. Return ThrowCompletion(copiedError). return vm.throw_completion(ErrorType::ShadowRealmEvaluateAbruptCompletion); + } - // 22. Return ? GetWrappedValue(callerRealm, result.[[Value]]). + // 16. Return ? GetWrappedValue(callerRealm, result.[[Value]]). return get_wrapped_value(vm, caller_realm, *result.value()); // NOTE: Also see "Editor's Note" in the spec regarding the TypeError above. @@ -342,6 +321,9 @@ NonnullOwnPtr get_shadow_realm_context(Realm& shadow_realm, bo // 10. Set context's PrivateEnvironment to null. context->private_environment = nullptr; + // Non-standard + context->is_strict_mode = strict_eval; + // 11. Return context. return context; }