summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorLinus Groh <mail@linusgroh.de>2022-01-24 19:09:40 +0000
committerLinus Groh <mail@linusgroh.de>2022-01-24 20:17:07 +0000
commit5b04c49762a56fed0aafa37883f0c15f3fc41209 (patch)
tree8f75ecea87a526175db0236cd4433782bcc19f0c /Userland
parent6fa600fce31a0eb0d4708bf0d440c8e593e41dce (diff)
downloadserenity-5b04c49762a56fed0aafa37883f0c15f3fc41209.zip
LibJS: Implement the SetFunctionName AO
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibJS/Runtime/FunctionObject.cpp57
-rw-r--r--Userland/Libraries/LibJS/Runtime/FunctionObject.h7
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; }