1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 14:07:46 +00:00

LibJS: Move prepare_for_ordinary_call() to ECMAScriptFunctionObject

Now that it only needs to deal with ECMAScriptFunctionObject via
internal_call() / internal_construct(), we can:

- Remove the generic FunctionObject parameter
- Move it from the VM to ECMAScriptFunctionObject
- Make it private
This commit is contained in:
Linus Groh 2021-10-08 21:14:22 +01:00
parent cf168fac50
commit 25bcd36116
4 changed files with 62 additions and 60 deletions

View file

@ -525,62 +525,6 @@ Value VM::get_new_target()
return verify_cast<FunctionEnvironment>(env).new_target();
}
// 10.2.1.1 PrepareForOrdinaryCall ( F, newTarget ), https://tc39.es/ecma262/#sec-prepareforordinarycall
void VM::prepare_for_ordinary_call(FunctionObject& function, ExecutionContext& callee_context, Object* new_target)
{
// Non-standard
callee_context.is_strict_mode = function.is_strict_mode();
// 1. Let callerContext be the running execution context.
// 2. Let calleeContext be a new ECMAScript code execution context.
// NOTE: In the specification, PrepareForOrdinaryCall "returns" a new callee execution context.
// To avoid heap allocations, we put our ExecutionContext objects on the C++ stack instead.
// Whoever calls us should put an ExecutionContext on their stack and pass that as the `callee_context`.
// 3. Set the Function of calleeContext to F.
callee_context.function = &function;
callee_context.function_name = function.name();
// 4. Let calleeRealm be F.[[Realm]].
auto* callee_realm = function.realm();
// NOTE: This non-standard fallback is needed until we can guarantee that literally
// every function has a realm - especially in LibWeb that's sometimes not the case
// when a function is created while no JS is running, as we currently need to rely on
// that (:acid2:, I know - see set_event_handler_attribute() for an example).
// If there's no 'current realm' either, we can't continue and crash.
if (!callee_realm)
callee_realm = vm.current_realm();
VERIFY(callee_realm);
// 5. Set the Realm of calleeContext to calleeRealm.
callee_context.realm = callee_realm;
// 6. Set the ScriptOrModule of calleeContext to F.[[ScriptOrModule]].
// FIXME: Our execution context struct currently does not track this item.
// 7. Let localEnv be NewFunctionEnvironment(F, newTarget).
auto* local_environment = function.new_function_environment(new_target);
// 8. Set the LexicalEnvironment of calleeContext to localEnv.
callee_context.lexical_environment = local_environment;
// 9. Set the VariableEnvironment of calleeContext to localEnv.
callee_context.variable_environment = local_environment;
// 10. Set the PrivateEnvironment of calleeContext to F.[[PrivateEnvironment]].
// FIXME: We currently don't support private environments.
// 11. If callerContext is not already suspended, suspend callerContext.
// FIXME: We don't have this concept yet.
// 12. Push calleeContext onto the execution context stack; calleeContext is now the running execution context.
push_execution_context(callee_context, function.global_object());
// 13. NOTE: Any exception objects produced after this point are associated with calleeRealm.
// 14. Return calleeContext. (See NOTE above about how contexts are allocated on the C++ stack.)
}
// 10.2.1.2 OrdinaryCallBindThis ( F, calleeContext, thisArgument ), https://tc39.es/ecma262/#sec-ordinarycallbindthis
void VM::ordinary_call_bind_this(FunctionObject& function, ExecutionContext& callee_context, Value this_argument)
{