diff options
author | Linus Groh <mail@linusgroh.de> | 2022-01-24 19:09:40 +0000 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-01-24 20:17:07 +0000 |
commit | 5b04c49762a56fed0aafa37883f0c15f3fc41209 (patch) | |
tree | 8f75ecea87a526175db0236cd4433782bcc19f0c /Userland | |
parent | 6fa600fce31a0eb0d4708bf0d440c8e593e41dce (diff) | |
download | serenity-5b04c49762a56fed0aafa37883f0c15f3fc41209.zip |
LibJS: Implement the SetFunctionName AO
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/FunctionObject.cpp | 57 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/FunctionObject.h | 7 |
2 files changed, 62 insertions, 2 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/FunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/FunctionObject.cpp index 1051536a41..a6773a6146 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/FunctionObject.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -8,7 +9,6 @@ #include <LibJS/Runtime/BoundFunction.h> #include <LibJS/Runtime/Completion.h> #include <LibJS/Runtime/FunctionObject.h> -#include <LibJS/Runtime/GlobalObject.h> namespace JS { @@ -21,6 +21,61 @@ FunctionObject::~FunctionObject() { } +// 10.2.9 SetFunctionName ( F, name [ , prefix ] ), https://tc39.es/ecma262/#sec-setfunctionname +void FunctionObject::set_function_name(Variant<PropertyKey, PrivateName> const& name_arg, Optional<StringView> const& prefix) +{ + auto& vm = this->vm(); + + // 1. Assert: F is an extensible object that does not have a "name" own property. + VERIFY(m_is_extensible); + VERIFY(!storage_has(vm.names.name)); + + String name; + + // 2. If Type(name) is Symbol, then + if (auto const* property_key = name_arg.get_pointer<PropertyKey>(); property_key && property_key->is_symbol()) { + // a. Let description be name's [[Description]] value. + auto const& description = property_key->as_symbol()->raw_description(); + + // b. If description is undefined, set name to the empty String. + if (!description.has_value()) + name = String::empty(); + // c. Else, set name to the string-concatenation of "[", description, and "]". + else + name = String::formatted("[{}]", *description); + } + // 3. Else if name is a Private Name, then + else if (auto const* private_name = name_arg.get_pointer<PrivateName>()) { + // a. Set name to name.[[Description]]. + name = private_name->description; + } + // NOTE: This is necessary as we use a different parameter name. + else { + name = name_arg.get<PropertyKey>().to_string(); + } + + // 4. If F has an [[InitialName]] internal slot, then + if (is<NativeFunction>(this)) { + // a. Set F.[[InitialName]] to name. + // TODO: Remove FunctionObject::name(), implement NativeFunction::initial_name(), and then do this. + } + + // 5. If prefix is present, then + if (prefix.has_value()) { + // a. Set name to the string-concatenation of prefix, the code unit 0x0020 (SPACE), and name. + name = String::formatted("{} {}", *prefix, name); + + // b. If F has an [[InitialName]] internal slot, then + if (is<NativeFunction>(this)) { + // i. Optionally, set F.[[InitialName]] to name. + // TODO: See above. + } + } + + // 6. Return ! DefinePropertyOrThrow(F, "name", PropertyDescriptor { [[Value]]: name, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }). + MUST(define_property_or_throw(vm.names.name, PropertyDescriptor { .value = js_string(vm, move(name)), .writable = false, .enumerable = false, .configurable = true })); +} + ThrowCompletionOr<BoundFunction*> FunctionObject::bind(Value bound_this_value, Vector<Value> arguments) { auto& vm = this->vm(); diff --git a/Userland/Libraries/LibJS/Runtime/FunctionObject.h b/Userland/Libraries/LibJS/Runtime/FunctionObject.h index 0aa9d2a33e..12692c2d3e 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionObject.h +++ b/Userland/Libraries/LibJS/Runtime/FunctionObject.h @@ -1,13 +1,17 @@ /* * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once -#include <AK/String.h> +#include <AK/Optional.h> +#include <AK/StringView.h> #include <LibJS/Runtime/Object.h> +#include <LibJS/Runtime/PrivateEnvironment.h> +#include <LibJS/Runtime/PropertyKey.h> namespace JS { @@ -25,6 +29,7 @@ public: virtual const FlyString& name() const = 0; + void set_function_name(Variant<PropertyKey, PrivateName> const& name_arg, Optional<StringView> const& prefix = {}); ThrowCompletionOr<BoundFunction*> bind(Value bound_this_value, Vector<Value> arguments); virtual bool is_strict_mode() const { return false; } |