mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-10 01:51:03 +09:00
LibJS: Use GetShadowRealmContext for PerformShadowRealmEval
This commit is contained in:
parent
6a55865bf6
commit
3cb62265ab
Notes:
github-actions[bot]
2024-11-05 00:16:30 +00:00
Author: https://github.com/shannonbooth
Commit: 3cb62265ab
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2134
Reviewed-by: https://github.com/ADKaster ✅
1 changed files with 25 additions and 43 deletions
|
@ -124,57 +124,33 @@ ThrowCompletionOr<Value> perform_shadow_realm_eval(VM& vm, StringView source_tex
|
||||||
auto strict_eval = program->is_strict_mode();
|
auto strict_eval = program->is_strict_mode();
|
||||||
|
|
||||||
// 4. Let runningContext be the running execution context.
|
// 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]]).
|
// 6. Let evalContext be GetShadowRealmContext(evalRealm, strictEval).
|
||||||
Environment* lexical_environment = new_declarative_environment(eval_realm.global_environment()).ptr();
|
auto eval_context = get_shadow_realm_context(eval_realm, strict_eval);
|
||||||
|
|
||||||
// 6. Let varEnv be evalRealm.[[GlobalEnv]].
|
// 7. Let lexEnv be evalContext's LexicalEnvironment.
|
||||||
Environment* variable_environment = &eval_realm.global_environment();
|
auto lexical_environment = eval_context->lexical_environment;
|
||||||
|
|
||||||
// 7. If strictEval is true, set varEnv to lexEnv.
|
// 8. Let varEnv be evalContext's VariableEnvironment.
|
||||||
if (strict_eval)
|
auto variable_environment = eval_context->variable_environment;
|
||||||
variable_environment = lexical_environment;
|
|
||||||
|
|
||||||
// 8. If runningContext is not already suspended, suspend runningContext.
|
// 9. Push evalContext onto the execution context stack; evalContext is now the running execution context.
|
||||||
// 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.
|
|
||||||
TRY(vm.push_execution_context(*eval_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);
|
auto eval_result = eval_declaration_instantiation(vm, program, variable_environment, lexical_environment, nullptr, strict_eval);
|
||||||
|
|
||||||
Completion result;
|
Completion result;
|
||||||
|
|
||||||
// 17. If result.[[Type]] is normal, then
|
// 11. If result.[[Type]] is normal, then
|
||||||
if (!eval_result.is_throw_completion()) {
|
if (!eval_result.is_throw_completion()) {
|
||||||
// a. Set result to the result of evaluating body.
|
// a. Set result to the result of evaluating body.
|
||||||
auto maybe_executable = Bytecode::compile(vm, program, FunctionKind::Normal, "ShadowRealmEval"sv);
|
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();
|
result = maybe_executable.release_error();
|
||||||
else {
|
} else {
|
||||||
auto executable = maybe_executable.release_value();
|
auto executable = maybe_executable.release_value();
|
||||||
|
|
||||||
auto result_and_return_register = vm.bytecode_interpreter().run_executable(*executable, {});
|
auto result_and_return_register = vm.bytecode_interpreter().run_executable(*executable, {});
|
||||||
|
@ -187,24 +163,27 @@ ThrowCompletionOr<Value> 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()) {
|
if (result.type() == Completion::Type::Normal && !result.value().has_value()) {
|
||||||
// a. Set result to NormalCompletion(undefined).
|
// a. Set result to NormalCompletion(undefined).
|
||||||
result = normal_completion(js_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.
|
// NOTE: We don't support this concept yet.
|
||||||
vm.pop_execution_context();
|
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.
|
// NOTE: We don't support this concept yet.
|
||||||
|
|
||||||
// 21. If result.[[Type]] is not normal, throw a TypeError exception.
|
// 15. If result.[[Type]] is not normal, then
|
||||||
if (result.type() != Completion::Type::Normal)
|
if (result.type() != Completion::Type::Normal) {
|
||||||
|
// a. Let copiedError be CreateTypeErrorCopy(callerRealm, result.[[Value]]).
|
||||||
|
// b. Return ThrowCompletion(copiedError).
|
||||||
return vm.throw_completion<TypeError>(ErrorType::ShadowRealmEvaluateAbruptCompletion);
|
return vm.throw_completion<TypeError>(ErrorType::ShadowRealmEvaluateAbruptCompletion);
|
||||||
|
}
|
||||||
|
|
||||||
// 22. Return ? GetWrappedValue(callerRealm, result.[[Value]]).
|
// 16. Return ? GetWrappedValue(callerRealm, result.[[Value]]).
|
||||||
return get_wrapped_value(vm, caller_realm, *result.value());
|
return get_wrapped_value(vm, caller_realm, *result.value());
|
||||||
|
|
||||||
// NOTE: Also see "Editor's Note" in the spec regarding the TypeError above.
|
// NOTE: Also see "Editor's Note" in the spec regarding the TypeError above.
|
||||||
|
@ -342,6 +321,9 @@ NonnullOwnPtr<ExecutionContext> get_shadow_realm_context(Realm& shadow_realm, bo
|
||||||
// 10. Set context's PrivateEnvironment to null.
|
// 10. Set context's PrivateEnvironment to null.
|
||||||
context->private_environment = nullptr;
|
context->private_environment = nullptr;
|
||||||
|
|
||||||
|
// Non-standard
|
||||||
|
context->is_strict_mode = strict_eval;
|
||||||
|
|
||||||
// 11. Return context.
|
// 11. Return context.
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue