mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 06:07:34 +00:00
LibJS: Add NativeFunction::create() overload for CreateBuiltinFunction
Also take a length argument and set the name and length properties internally, instead of at the call site. Additionally, allow passing a realm, prototype, and prefix.
This commit is contained in:
parent
e657e88ed6
commit
e4f165d460
2 changed files with 50 additions and 2 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
|
||||
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -9,15 +9,60 @@
|
|||
#include <LibJS/Runtime/FunctionEnvironment.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/NativeFunction.h>
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
// 10.3.3 CreateBuiltinFunction ( behaviour, length, name, additionalInternalSlotsList [ , realm [ , prototype [ , prefix ] ] ] ), https://tc39.es/ecma262/#sec-createbuiltinfunction
|
||||
// NOTE: This doesn't consider additionalInternalSlotsList, which is rarely used, and can either be implemented using only the `function` lambda, or needs a NativeFunction subclass.
|
||||
NativeFunction* NativeFunction::create(GlobalObject& global_object, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> behaviour, i32 length, PropertyKey const& name, Optional<Realm*> realm, Optional<Object*> prototype, Optional<StringView> const& prefix)
|
||||
{
|
||||
auto& vm = global_object.vm();
|
||||
|
||||
// 1. If realm is not present, set realm to the current Realm Record.
|
||||
if (!realm.has_value())
|
||||
realm = vm.current_realm();
|
||||
|
||||
// 2. If prototype is not present, set prototype to realm.[[Intrinsics]].[[%Function.prototype%]].
|
||||
if (!prototype.has_value())
|
||||
prototype = realm.value()->global_object().function_prototype();
|
||||
|
||||
// 3. Let internalSlotsList be a List containing the names of all the internal slots that 10.3 requires for the built-in function object that is about to be created.
|
||||
// 4. Append to internalSlotsList the elements of additionalInternalSlotsList.
|
||||
|
||||
// 5. Let func be a new built-in function object that, when called, performs the action described by behaviour using the provided arguments as the values of the corresponding parameters specified by behaviour. The new function object has internal slots whose names are the elements of internalSlotsList, and an [[InitialName]] internal slot.
|
||||
// 6. Set func.[[Prototype]] to prototype.
|
||||
// 7. Set func.[[Extensible]] to true.
|
||||
// 8. Set func.[[Realm]] to realm.
|
||||
// 9. Set func.[[InitialName]] to null.
|
||||
auto* function = global_object.heap().allocate<NativeFunction>(global_object, global_object, move(behaviour), prototype.value(), *realm.value());
|
||||
|
||||
// 10. Perform ! SetFunctionLength(func, length).
|
||||
function->set_function_length(length);
|
||||
|
||||
// 11. If prefix is not present, then
|
||||
// a. Perform ! SetFunctionName(func, name).
|
||||
// 12. Else,
|
||||
// a. Perform ! SetFunctionName(func, name, prefix).
|
||||
function->set_function_name(name, prefix);
|
||||
|
||||
// 13. Return func.
|
||||
return function;
|
||||
}
|
||||
|
||||
NativeFunction* NativeFunction::create(GlobalObject& global_object, const FlyString& name, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> function)
|
||||
{
|
||||
return global_object.heap().allocate<NativeFunction>(global_object, name, move(function), *global_object.function_prototype());
|
||||
}
|
||||
|
||||
NativeFunction::NativeFunction(GlobalObject& global_object, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> native_function, Object* prototype, Realm& realm)
|
||||
: FunctionObject(global_object, prototype)
|
||||
, m_native_function(move(native_function))
|
||||
, m_realm(&realm)
|
||||
{
|
||||
}
|
||||
|
||||
// FIXME: m_realm is supposed to be the realm argument of CreateBuiltinFunction, or the current
|
||||
// Realm Record. The former is not something that's commonly used or we support, the
|
||||
// latter is impossible as no ExecutionContext exists when most NativeFunctions are created...
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue