summaryrefslogtreecommitdiff
path: root/Libraries/LibJS
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-10-13 23:49:19 +0200
committerAndreas Kling <kling@serenityos.org>2020-10-13 23:57:45 +0200
commit7b863330dc72e5715b17726cdbae95c168015363 (patch)
tree81d02a3c177d86a3295994ef1c1ccb851686d551 /Libraries/LibJS
parent9f6c5f68b663442d4197ab7d93b9da4a0249d575 (diff)
downloadserenity-7b863330dc72e5715b17726cdbae95c168015363.zip
LibJS: Cache commonly used FlyStrings in the VM
Roughly 7% of test-js runtime was spent creating FlyStrings from string literals. This patch frontloads that work and caches all the commonly used names in LibJS on a CommonPropertyNames struct that hangs off VM.
Diffstat (limited to 'Libraries/LibJS')
-rw-r--r--Libraries/LibJS/AST.cpp24
-rw-r--r--Libraries/LibJS/Interpreter.cpp3
-rw-r--r--Libraries/LibJS/Runtime/Array.cpp3
-rw-r--r--Libraries/LibJS/Runtime/ArrayConstructor.cpp13
-rw-r--r--Libraries/LibJS/Runtime/ArrayIteratorPrototype.cpp3
-rw-r--r--Libraries/LibJS/Runtime/ArrayPrototype.cpp67
-rw-r--r--Libraries/LibJS/Runtime/BigIntConstructor.cpp11
-rw-r--r--Libraries/LibJS/Runtime/BigIntPrototype.cpp9
-rw-r--r--Libraries/LibJS/Runtime/BooleanConstructor.cpp7
-rw-r--r--Libraries/LibJS/Runtime/BooleanPrototype.cpp5
-rw-r--r--Libraries/LibJS/Runtime/BoundFunction.cpp3
-rw-r--r--Libraries/LibJS/Runtime/CommonPropertyNames.h209
-rw-r--r--Libraries/LibJS/Runtime/DateConstructor.cpp13
-rw-r--r--Libraries/LibJS/Runtime/DatePrototype.cpp51
-rw-r--r--Libraries/LibJS/Runtime/Error.cpp2
-rw-r--r--Libraries/LibJS/Runtime/ErrorConstructor.cpp14
-rw-r--r--Libraries/LibJS/Runtime/ErrorPrototype.cpp11
-rw-r--r--Libraries/LibJS/Runtime/Exception.cpp2
-rw-r--r--Libraries/LibJS/Runtime/Function.cpp13
-rw-r--r--Libraries/LibJS/Runtime/FunctionConstructor.cpp7
-rw-r--r--Libraries/LibJS/Runtime/FunctionPrototype.cpp17
-rw-r--r--Libraries/LibJS/Runtime/GlobalObject.cpp58
-rw-r--r--Libraries/LibJS/Runtime/GlobalObject.h9
-rw-r--r--Libraries/LibJS/Runtime/IteratorOperations.cpp11
-rw-r--r--Libraries/LibJS/Runtime/JSONObject.cpp2
-rw-r--r--Libraries/LibJS/Runtime/MathObject.cpp67
-rw-r--r--Libraries/LibJS/Runtime/NumberConstructor.cpp38
-rw-r--r--Libraries/LibJS/Runtime/Object.cpp117
-rw-r--r--Libraries/LibJS/Runtime/ObjectConstructor.cpp29
-rw-r--r--Libraries/LibJS/Runtime/ObjectPrototype.cpp9
-rw-r--r--Libraries/LibJS/Runtime/ProxyConstructor.cpp7
-rw-r--r--Libraries/LibJS/Runtime/ProxyObject.cpp71
-rw-r--r--Libraries/LibJS/Runtime/ReflectObject.cpp29
-rw-r--r--Libraries/LibJS/Runtime/RegExpConstructor.cpp7
-rw-r--r--Libraries/LibJS/Runtime/ScriptFunction.cpp9
-rw-r--r--Libraries/LibJS/Runtime/StringConstructor.cpp13
-rw-r--r--Libraries/LibJS/Runtime/StringIteratorPrototype.cpp6
-rw-r--r--Libraries/LibJS/Runtime/StringPrototype.cpp41
-rw-r--r--Libraries/LibJS/Runtime/SymbolConstructor.cpp13
-rw-r--r--Libraries/LibJS/Runtime/SymbolPrototype.cpp7
-rw-r--r--Libraries/LibJS/Runtime/Uint8ClampedArray.cpp3
-rw-r--r--Libraries/LibJS/Runtime/VM.cpp4
-rw-r--r--Libraries/LibJS/Runtime/VM.h3
-rw-r--r--Libraries/LibJS/Runtime/Value.cpp7
44 files changed, 652 insertions, 395 deletions
diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp
index 3b754f2597..044f35bac5 100644
--- a/Libraries/LibJS/AST.cpp
+++ b/Libraries/LibJS/AST.cpp
@@ -698,6 +698,7 @@ Value ClassMethod::execute(Interpreter& interpreter, GlobalObject& global_object
Value ClassExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
{
+ auto& vm = interpreter.vm();
Value class_constructor_value = m_constructor->execute(interpreter, global_object);
if (interpreter.exception())
return {};
@@ -720,22 +721,22 @@ Value ClassExpression::execute(Interpreter& interpreter, GlobalObject& global_ob
Object* super_constructor_prototype = nullptr;
if (!super_constructor.is_null()) {
- super_constructor_prototype = &super_constructor.as_object().get("prototype").as_object();
+ super_constructor_prototype = &super_constructor.as_object().get(vm.names.prototype).as_object();
if (interpreter.exception())
return {};
}
prototype->set_prototype(super_constructor_prototype);
- prototype->define_property("constructor", class_constructor, 0);
+ prototype->define_property(vm.names.constructor, class_constructor, 0);
if (interpreter.exception())
return {};
- class_constructor->define_property("prototype", prototype, 0);
+ class_constructor->define_property(vm.names.prototype, prototype, 0);
if (interpreter.exception())
return {};
class_constructor->set_prototype(super_constructor.is_null() ? global_object.function_prototype() : &super_constructor.as_object());
}
- auto class_prototype = class_constructor->get("prototype");
+ auto class_prototype = class_constructor->get(vm.names.prototype);
if (interpreter.exception())
return {};
@@ -1756,21 +1757,22 @@ void TaggedTemplateLiteral::dump(int indent) const
Value TaggedTemplateLiteral::execute(Interpreter& interpreter, GlobalObject& global_object) const
{
+ auto& vm = interpreter.vm();
auto tag = m_tag->execute(interpreter, global_object);
- if (interpreter.exception())
+ if (vm.exception())
return {};
if (!tag.is_function()) {
- interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotAFunction, tag.to_string_without_side_effects());
+ vm.throw_exception<TypeError>(global_object, ErrorType::NotAFunction, tag.to_string_without_side_effects());
return {};
}
auto& tag_function = tag.as_function();
auto& expressions = m_template_literal->expressions();
auto* strings = Array::create(global_object);
- MarkedValueList arguments(interpreter.heap());
+ MarkedValueList arguments(vm.heap());
arguments.append(strings);
for (size_t i = 0; i < expressions.size(); ++i) {
auto value = expressions[i].execute(interpreter, global_object);
- if (interpreter.exception())
+ if (vm.exception())
return {};
// tag`${foo}` -> "", foo, "" -> tag(["", ""], foo)
// tag`foo${bar}baz${qux}` -> "foo", bar, "baz", qux, "" -> tag(["foo", "baz", ""], bar, qux)
@@ -1784,12 +1786,12 @@ Value TaggedTemplateLiteral::execute(Interpreter& interpreter, GlobalObject& glo
auto* raw_strings = Array::create(global_object);
for (auto& raw_string : m_template_literal->raw_strings()) {
auto value = raw_string.execute(interpreter, global_object);
- if (interpreter.exception())
+ if (vm.exception())
return {};
raw_strings->indexed_properties().append(value);
}
- strings->define_property("raw", raw_strings, 0);
- return interpreter.vm().call(tag_function, js_undefined(), move(arguments));
+ strings->define_property(vm.names.raw, raw_strings, 0);
+ return vm.call(tag_function, js_undefined(), move(arguments));
}
void TryStatement::dump(int indent) const
diff --git a/Libraries/LibJS/Interpreter.cpp b/Libraries/LibJS/Interpreter.cpp
index 51e5cf0a3c..82378b5817 100644
--- a/Libraries/LibJS/Interpreter.cpp
+++ b/Libraries/LibJS/Interpreter.cpp
@@ -69,7 +69,8 @@ Value Interpreter::run(GlobalObject& global_object, const Program& program)
CallFrame global_call_frame;
global_call_frame.this_value = &global_object;
- global_call_frame.function_name = "(global execution context)";
+ static FlyString global_execution_context_name = "(global execution context)";
+ global_call_frame.function_name = global_execution_context_name;
global_call_frame.environment = heap().allocate<LexicalEnvironment>(global_object, LexicalEnvironment::EnvironmentRecordType::Global);
global_call_frame.environment->bind_this_value(global_object, &global_object);
global_call_frame.is_strict_mode = program.is_strict_mode();
diff --git a/Libraries/LibJS/Runtime/Array.cpp b/Libraries/LibJS/Runtime/Array.cpp
index a5b5c24197..f881139f62 100644
--- a/Libraries/LibJS/Runtime/Array.cpp
+++ b/Libraries/LibJS/Runtime/Array.cpp
@@ -40,7 +40,8 @@ Array* Array::create(GlobalObject& global_object)
Array::Array(Object& prototype)
: Object(prototype)
{
- define_native_property("length", length_getter, length_setter, Attribute::Writable);
+ auto& vm = this->vm();
+ define_native_property(vm.names.length, length_getter, length_setter, Attribute::Writable);
}
Array::~Array()
diff --git a/Libraries/LibJS/Runtime/ArrayConstructor.cpp b/Libraries/LibJS/Runtime/ArrayConstructor.cpp
index 42c813c222..3eb3407cbc 100644
--- a/Libraries/LibJS/Runtime/ArrayConstructor.cpp
+++ b/Libraries/LibJS/Runtime/ArrayConstructor.cpp
@@ -37,7 +37,7 @@
namespace JS {
ArrayConstructor::ArrayConstructor(GlobalObject& global_object)
- : NativeFunction("Array", *global_object.function_prototype())
+ : NativeFunction(vm().names.Array, *global_object.function_prototype())
{
}
@@ -47,15 +47,16 @@ ArrayConstructor::~ArrayConstructor()
void ArrayConstructor::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
NativeFunction::initialize(global_object);
- define_property("prototype", global_object.array_prototype(), 0);
- define_property("length", Value(1), Attribute::Configurable);
+ define_property(vm.names.prototype, global_object.array_prototype(), 0);
+ define_property(vm.names.length, Value(1), Attribute::Configurable);
u8 attr = Attribute::Writable | Attribute::Configurable;
- define_native_function("from", from, 1, attr);
- define_native_function("isArray", is_array, 1, attr);
- define_native_function("of", of, 0, attr);
+ define_native_function(vm.names.from, from, 1, attr);
+ define_native_function(vm.names.isArray, is_array, 1, attr);
+ define_native_function(vm.names.of, of, 0, attr);
}
Value ArrayConstructor::call()
diff --git a/Libraries/LibJS/Runtime/ArrayIteratorPrototype.cpp b/Libraries/LibJS/Runtime/ArrayIteratorPrototype.cpp
index 5e941d438b..6872f2ddad 100644
--- a/Libraries/LibJS/Runtime/ArrayIteratorPrototype.cpp
+++ b/Libraries/LibJS/Runtime/ArrayIteratorPrototype.cpp
@@ -40,9 +40,10 @@ ArrayIteratorPrototype::ArrayIteratorPrototype(GlobalObject& global_object)
void ArrayIteratorPrototype::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
Object::initialize(global_object);
- define_native_function("next", next, 0, Attribute::Configurable | Attribute::Writable);
+ define_native_function(vm.names.next, next, 0, Attribute::Configurable | Attribute::Writable);
define_property(global_object.vm().well_known_symbol_to_string_tag(), js_string(global_object.heap(), "Array Iterator"), Attribute::Configurable);
}
diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Libraries/LibJS/Runtime/ArrayPrototype.cpp
index d41a71a66b..377f84b3c0 100644
--- a/Libraries/LibJS/Runtime/ArrayPrototype.cpp
+++ b/Libraries/LibJS/Runtime/ArrayPrototype.cpp
@@ -46,40 +46,41 @@ ArrayPrototype::ArrayPrototype(GlobalObject& global_object)
void ArrayPrototype::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
Object::initialize(global_object);
u8 attr = Attribute::Writable | Attribute::Configurable;
- define_native_function("filter", filter, 1, attr);
- define_native_function("forEach", for_each, 1, attr);
- define_native_function("map", map, 1, attr);
- define_native_function("pop", pop, 0, attr);
- define_native_function("push", push, 1, attr);
- define_native_function("shift", shift, 0, attr);
- define_native_function("toString", to_string, 0, attr);
- define_native_function("toLocaleString", to_locale_string, 0, attr);
- define_native_function("unshift", unshift, 1, attr);
- define_native_function("join", join, 1, attr);
- define_native_function("concat", concat, 1, attr);
- define_native_function("slice", slice, 2, attr);
- define_native_function("indexOf", index_of, 1, attr);
- define_native_function("reduce", reduce, 1, attr);
- define_native_function("reduceRight", reduce_right, 1, attr);
- define_native_function("reverse", reverse, 0, attr);
- define_native_function("lastIndexOf", last_index_of, 1, attr);
- define_native_function("includes", includes, 1, attr);
- define_native_function("find", find, 1, attr);
- define_native_function("findIndex", find_index, 1, attr);
- define_native_function("some", some, 1, attr);
- define_native_function("every", every, 1, attr);
- define_native_function("splice", splice, 2, attr);
- define_native_function("fill", fill, 1, attr);
- define_native_function("values", values, 0, attr);
- define_property("length", Value(0), Attribute::Configurable);
+ define_native_function(vm.names.filter, filter, 1, attr);
+ define_native_function(vm.names.forEach, for_each, 1, attr);
+ define_native_function(vm.names.map, map, 1, attr);
+ define_native_function(vm.names.pop, pop, 0, attr);
+ define_native_function(vm.names.push, push, 1, attr);
+ define_native_function(vm.names.shift, shift, 0, attr);
+ define_native_function(vm.names.toString, to_string, 0, attr);
+ define_native_function(vm.names.toLocaleString, to_locale_string, 0, attr);
+ define_native_function(vm.names.unshift, unshift, 1, attr);
+ define_native_function(vm.names.join, join, 1, attr);
+ define_native_function(vm.names.concat, concat, 1, attr);
+ define_native_function(vm.names.slice, slice, 2, attr);
+ define_native_function(vm.names.indexOf, index_of, 1, attr);
+ define_native_function(vm.names.reduce, reduce, 1, attr);
+ define_native_function(vm.names.reduceRight, reduce_right, 1, attr);
+ define_native_function(vm.names.reverse, reverse, 0, attr);
+ define_native_function(vm.names.lastIndexOf, last_index_of, 1, attr);
+ define_native_function(vm.names.includes, includes, 1, attr);
+ define_native_function(vm.names.find, find, 1, attr);
+ define_native_function(vm.names.findIndex, find_index, 1, attr);
+ define_native_function(vm.names.some, some, 1, attr);
+ define_native_function(vm.names.every, every, 1, attr);
+ define_native_function(vm.names.splice, splice, 2, attr);
+ define_native_function(vm.names.fill, fill, 1, attr);
+ define_native_function(vm.names.values, values, 0, attr);
+ define_property(vm.names.length, Value(0), Attribute::Configurable);
// Use define_property here instead of define_native_function so that
// Object.is(Array.prototype[Symbol.iterator], Array.prototype.values)
// evaluates to true
- define_property(global_object.vm().well_known_symbol_iterator(), get("values"), attr);
+ define_property(vm.well_known_symbol_iterator(), get(vm.names.values), attr);
}
ArrayPrototype::~ArrayPrototype()
@@ -103,7 +104,7 @@ static Function* callback_from_args(GlobalObject& global_object, const String& n
static size_t get_length(VM& vm, Object& object)
{
- auto length_property = object.get("length");
+ auto length_property = object.get(vm.names.length);
if (vm.exception())
return 0;
return length_property.to_size_t(object.global_object());
@@ -208,7 +209,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::push)
return {};
}
auto new_length_value = Value((i32)new_length);
- this_object->put("length", new_length_value);
+ this_object->put(vm.names.length, new_length_value);
if (vm.exception())
return {};
return new_length_value;
@@ -237,7 +238,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop)
}
auto length = get_length(vm, *this_object);
if (length == 0) {
- this_object->put("length", Value(0));
+ this_object->put(vm.names.length, Value(0));
return js_undefined();
}
auto index = length - 1;
@@ -247,7 +248,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop)
this_object->delete_property(index);
if (vm.exception())
return {};
- this_object->put("length", Value((i32)index));
+ this_object->put(vm.names.length, Value((i32)index));
if (vm.exception())
return {};
return element;
@@ -271,7 +272,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_string)
auto* this_object = vm.this_value(global_object).to_object(global_object);
if (!this_object)
return {};
- auto join_function = this_object->get("join");
+ auto join_function = this_object->get(vm.names.join);
if (vm.exception())
return {};
if (!join_function.is_function())
@@ -789,7 +790,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
return {};
}
- this_object->put("length", Value((i32)new_length));
+ this_object->put(vm.names.length, Value((i32)new_length));
if (vm.exception())
return {};
diff --git a/Libraries/LibJS/Runtime/BigIntConstructor.cpp b/Libraries/LibJS/Runtime/BigIntConstructor.cpp
index 25696f4fbb..5eec127b63 100644
--- a/Libraries/LibJS/Runtime/BigIntConstructor.cpp
+++ b/Libraries/LibJS/Runtime/BigIntConstructor.cpp
@@ -35,19 +35,20 @@
namespace JS {
BigIntConstructor::BigIntConstructor(GlobalObject& global_object)
- : NativeFunction("BigInt", *global_object.function_prototype())
+ : NativeFunction(vm().names.BigInt, *global_object.function_prototype())
{
}
void BigIntConstructor::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
NativeFunction::initialize(global_object);
- define_property("prototype", global_object.bigint_prototype(), 0);
- define_property("length", Value(1), Attribute::Configurable);
+ define_property(vm.names.prototype, global_object.bigint_prototype(), 0);
+ define_property(vm.names.length, Value(1), Attribute::Configurable);
u8 attr = Attribute::Writable | Attribute::Configurable;
- define_native_function("asIntN", as_int_n, 2, attr);
- define_native_function("asUintN", as_uint_n, 2, attr);
+ define_native_function(vm.names.asIntN, as_int_n, 2, attr);
+ define_native_function(vm.names.asUintN, as_uint_n, 2, attr);
}
BigIntConstructor::~BigIntConstructor()
diff --git a/Libraries/LibJS/Runtime/BigIntPrototype.cpp b/Libraries/LibJS/Runtime/BigIntPrototype.cpp
index f3b0196b4f..a71c9b260e 100644
--- a/Libraries/LibJS/Runtime/BigIntPrototype.cpp
+++ b/Libraries/LibJS/Runtime/BigIntPrototype.cpp
@@ -39,13 +39,14 @@ BigIntPrototype::BigIntPrototype(GlobalObject& global_object)
void BigIntPrototype::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
Object::initialize(global_object);
u8 attr = Attribute::Writable | Attribute::Configurable;
- define_native_function("toString", to_string, 0, attr);
- define_native_function("toLocaleString", to_locale_string, 0, attr);
- define_native_function("valueOf", value_of, 0, attr);
+ define_native_function(vm.names.toString, to_string, 0, attr);
+ define_native_function(vm.names.toLocaleString, to_locale_string, 0, attr);
+ define_native_function(vm.names.valueOf, value_of, 0, attr);
- define_property(global_object.vm().well_known_symbol_to_string_tag(), js_string(global_object.heap(), "BigInt"), Attribute::Configurable);
+ define_property(vm.well_known_symbol_to_string_tag(), js_string(global_object.heap(), "BigInt"), Attribute::Configurable);
}
BigIntPrototype::~BigIntPrototype()
diff --git a/Libraries/LibJS/Runtime/BooleanConstructor.cpp b/Libraries/LibJS/Runtime/BooleanConstructor.cpp
index bab8ca473a..33e71c238d 100644
--- a/Libraries/LibJS/Runtime/BooleanConstructor.cpp
+++ b/Libraries/LibJS/Runtime/BooleanConstructor.cpp
@@ -33,15 +33,16 @@
namespace JS {
BooleanConstructor::BooleanConstructor(GlobalObject& global_object)
- : NativeFunction("Boolean", *global_object.function_prototype())
+ : NativeFunction(vm().names.Boolean, *global_object.function_prototype())
{
}
void BooleanConstructor::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
NativeFunction::initialize(global_object);
- define_property("prototype", Value(global_object.boolean_prototype()), 0);
- define_property("length", Value(1), Attribute::Configurable);
+ define_property(vm.names.prototype, Value(global_object.boolean_prototype()), 0);
+ define_property(vm.names.length, Value(1), Attribute::Configurable);
}
BooleanConstructor::~BooleanConstructor()
diff --git a/Libraries/LibJS/Runtime/BooleanPrototype.cpp b/Libraries/LibJS/Runtime/BooleanPrototype.cpp
index dbb4652bcc..aff90c07dc 100644
--- a/Libraries/LibJS/Runtime/BooleanPrototype.cpp
+++ b/Libraries/LibJS/Runtime/BooleanPrototype.cpp
@@ -38,9 +38,10 @@ BooleanPrototype::BooleanPrototype(GlobalObject& global_object)
void BooleanPrototype::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
BooleanObject::initialize(global_object);
- define_native_function("toString", to_string, 0, Attribute::Writable | Attribute::Configurable);
- define_native_function("valueOf", value_of, 0, Attribute::Writable | Attribute::Configurable);
+ define_native_function(vm.names.toString, to_string, 0, Attribute::Writable | Attribute::Configurable);
+ define_native_function(vm.names.valueOf, value_of, 0, Attribute::Writable | Attribute::Configurable);
}
BooleanPrototype::~BooleanPrototype()
diff --git a/Libraries/LibJS/Runtime/BoundFunction.cpp b/Libraries/LibJS/Runtime/BoundFunction.cpp
index 6aa0cbf5ae..82ad1aba41 100644
--- a/Libraries/LibJS/Runtime/BoundFunction.cpp
+++ b/Libraries/LibJS/Runtime/BoundFunction.cpp
@@ -40,8 +40,9 @@ BoundFunction::BoundFunction(GlobalObject& global_object, Function& target_funct
void BoundFunction::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
Function::initialize(global_object);
- define_property("length", Value(m_length), Attribute::Configurable);
+ define_property(vm.names.length, Value(m_length), Attribute::Configurable);
}
BoundFunction::~BoundFunction()
diff --git a/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Libraries/LibJS/Runtime/CommonPropertyNames.h
new file mode 100644
index 0000000000..f13e0f84e5
--- /dev/null
+++ b/Libraries/LibJS/Runtime/CommonPropertyNames.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <AK/FlyString.h>
+#include <LibJS/Forward.h>
+
+namespace JS {
+
+#define ENUMERATE_STANDARD_PROPERTY_NAMES(P) \
+ P(BigInt) \
+ P(Boolean) \
+ P(E) \
+ P(EPSILON) \
+ P(Infinity) \
+ P(JSON) \
+ P(LN10) \
+ P(LN2) \
+ P(LOG10E) \
+ P(LOG2E) \
+ P(MAX_SAFE_INTEGER) \
+ P(MIN_SAFE_INTEGER) \
+ P(Math) \
+ P(NEGATIVE_INFINITY) \
+ P(NaN) \
+ P(Number) \
+ P(PI) \
+ P(POSITIVE_INFINITY) \
+ P(Proxy) \
+ P(Reflect) \
+ P(RegExp) \
+ P(SQRT1_2) \
+ P(SQRT2) \
+ P(String) \
+ P(Symbol) \
+ P(UTC) \
+ P(abs) \
+ P(acosh) \
+ P(apply) \
+ P(asIntN) \
+ P(asUintN) \
+ P(asinh) \
+ P(atanh) \
+ P(bind) \
+ P(call) \
+ P(cbrt) \
+ P(ceil) \
+ P(charAt) \
+ P(charCodeAt) \
+ P(clz32) \
+ P(concat) \
+ P(console) \
+ P(construct) \
+ P(constructor) \
+ P(cos) \
+ P(defineProperty) \
+ P(deleteProperty) \
+ P(description) \
+ P(done) \
+ P(entries) \
+ P(every) \
+ P(exp) \
+ P(expm1) \
+ P(fill) \
+ P(filter) \
+ P(find) \
+ P(findIndex) \
+ P(floor) \
+ P(forEach) \
+ P(from) \
+ P(fromCharCode) \
+ P(gc) \
+ P(get) \
+ P(getDate) \
+ P(getDay) \
+ P(getFullYear) \
+ P(getHours) \
+ P(getMilliseconds) \
+ P(getMinutes) \
+ P(getMonth) \
+ P(getOwnPropertyDescriptor) \
+ P(getOwnPropertyNames) \
+ P(getPrototypeOf) \
+ P(getSeconds) \
+ P(getTime) \
+ P(getUTCDate) \
+ P(getUTCDay) \
+ P(getUTCFullYear) \
+ P(getUTCHours) \
+ P(getUTCMilliseconds) \
+ P(getUTCMinutes) \
+ P(getUTCMonth) \
+ P(getUTCSeconds) \
+ P(globalThis) \
+ P(has) \
+ P(hasOwnProperty) \
+ P(includes) \
+ P(indexOf) \
+ P(is) \
+ P(isArray) \
+ P(isExtensible) \
+ P(isFinite) \
+ P(isInteger) \
+ P(isNaN) \
+ P(isSafeInteger) \
+ P(join) \
+ P(keyFor) \
+ P(keys) \
+ P(lastIndexOf) \
+ P(length) \
+ P(log1p) \
+ P(map) \
+ P(max) \
+ P(message) \
+ P(min) \
+ P(name) \
+ P(now) \
+ P(of) \
+ P(ownKeys) \
+ P(padEnd) \
+ P(padStart) \
+ P(parse) \
+ P(parseFloat) \
+ P(pop) \
+ P(pow) \
+ P(preventExtensions) \
+ P(prototype) \
+ P(push) \
+ P(random) \
+ P(raw) \
+ P(reduce) \
+ P(reduceRight) \
+ P(repeat) \
+ P(reverse) \
+ P(round) \
+ P(set) \
+ P(setPrototypeOf) \
+ P(shift) \
+ P(sign) \
+ P(sin) \
+ P(slice) \
+ P(some) \
+ P(splice) \
+ P(sqrt) \
+ P(startsWith) \
+ P(substring) \
+ P(tan) \
+ P(toDateString) \
+ P(toISOString) \
+ P(toJSON) \
+ P(toLocaleDateString) \
+ P(toLocaleString) \
+ P(toLocaleTimeString) \
+ P(toLowerCase) \
+ P(toString) \
+ P(toTimeString) \
+ P(toUpperCase) \
+ P(trim) \
+ P(trimEnd) \
+ P(trimStart) \
+ P(trunc) \
+ P(undefined) \
+ P(unshift) \
+ P(value) \
+ P(valueOf) \
+ P(enumerable) \
+ P(configurable) \
+ P(writable) \
+ P(next) \
+ P(values)
+
+struct CommonPropertyNames {
+ FlyString for_ { "for" };
+#define __ENUMERATE(x) FlyString x { #x };
+ ENUMERATE_STANDARD_PROPERTY_NAMES(__ENUMERATE)
+#undef __ENUMERATE
+#define __JS_ENUMERATE(x, a, b, c) FlyString x { #x };
+ JS_ENUMERATE_BUILTIN_TYPES
+#undef __JS_ENUMERATE
+#define __JS_ENUMERATE(x, a) FlyString x { #x };
+ JS_ENUMERATE_WELL_KNOWN_SYMBOLS
+#undef __JS_ENUMERATE
+};
+
+}
diff --git a/Libraries/LibJS/Runtime/DateConstructor.cpp b/Libraries/LibJS/Runtime/DateConstructor.cpp
index e4c2abec22..37b4d87865 100644
--- a/Libraries/LibJS/Runtime/DateConstructor.cpp
+++ b/Libraries/LibJS/Runtime/DateConstructor.cpp
@@ -138,19 +138,20 @@ static Value parse_simplified_iso8601(const String& iso_8601)
}
DateConstructor::DateConstructor(GlobalObject& global_object)
- : NativeFunction("Date", *global_object.function_prototype())
+ : NativeFunction(vm().names.Date, *global_object.function_prototype())
{
}
void DateConstructor::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
NativeFunction::initialize(global_object);
- define_property("prototype", global_object.date_prototype(), 0);
- define_property("length", Value(7), Attribute::Configurable);
+ define_property(vm.names.prototype, global_object.date_prototype(), 0);
+ define_property(vm.names.length, Value(7), Attribute::Configurable);
- define_native_function("now", now, 0, Attribute::Writable | Attribute::Configurable);
- define_native_function("parse", parse, 1, Attribute::Writable | Attribute::Configurable);
- define_native_function("UTC", utc, 1, Attribute::Writable | Attribute::Configurable);
+ define_native_function(vm.names.now, now, 0, Attribute::Writable | Attribute::Configurable);
+ define_native_function(vm.names.parse, parse, 1, Attribute::Writable | Attribute::Configurable);
+ define_native_function(vm.names.UTC, utc, 1, Attribute::Writable | Attribute::Configurable);
}
DateConstructor::~DateConstructor()
diff --git a/Libraries/LibJS/Runtime/DatePrototype.cpp b/Libraries/LibJS/Runtime/DatePrototype.cpp
index 3b4bb4988c..b84cbff3df 100644
--- a/Libraries/LibJS/Runtime/DatePrototype.cpp
+++ b/Libraries/LibJS/Runtime/DatePrototype.cpp
@@ -54,35 +54,36 @@ DatePrototype::DatePrototype(GlobalObject& global_object)
void DatePrototype::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
Object::initialize(global_object);
u8 attr = Attribute::Writable | Attribute::Configurable;
- define_native_function("getDate", get_date, 0, attr);
- define_native_function("getDay", get_day, 0, attr);
- define_native_function("getFullYear", get_full_year, 0, attr);
- define_native_function("getHours", get_hours, 0, attr);
- define_native_function("getMilliseconds", get_milliseconds, 0, attr);
- define_native_function("getMinutes", get_minutes, 0, attr);
- define_native_function("getMonth", get_month, 0, attr);
- define_native_function("getSeconds", get_seconds, 0, attr);
- define_native_function("getTime", get_time, 0, attr);
- define_native_function("getUTCDate", get_utc_date, 0, attr);
- define_native_function("getUTCDay", get_utc_day, 0, attr);
- define_native_function("getUTCFullYear", get_utc_full_year, 0, attr);
- define_native_function("getUTCHours", get_utc_hours, 0, attr);
- define_native_function("getUTCMilliseconds", get_utc_milliseconds, 0, attr);
- define_native_function("getUTCMinutes", get_utc_minutes, 0, attr);
- define_native_function("getUTCMonth", get_utc_month, 0, attr);
- define_native_function("getUTCSeconds", get_utc_seconds, 0, attr);
- define_native_function("toDateString", to_date_string, 0, attr);
- define_native_function("toISOString", to_iso_string, 0, attr);
- define_native_function("toLocaleDateString", to_locale_date_string, 0, attr);
- define_native_function("toLocaleString", to_locale_string, 0, attr);
- define_native_function("toLocaleTimeString", to_locale_time_string, 0, attr);
- define_native_function("toTimeString", to_time_string, 0, attr);
- define_native_function("toString", to_string, 0, attr);
+ define_native_function(vm.names.getDate, get_date, 0, attr);
+ define_native_function(vm.names.getDay, get_day, 0, attr);
+ define_native_function(vm.names.getFullYear, get_full_year, 0, attr);
+ define_native_function(vm.names.getHours, get_hours, 0, attr);
+ define_native_function(vm.names.getMilliseconds, get_milliseconds, 0, attr);
+ define_native_function(vm.names.getMinutes, get_minutes, 0, attr);
+ define_native_function(vm.names.getMonth, get_month, 0, attr);
+ define_native_function(vm.names.getSeconds, get_seconds, 0, attr);
+ define_native_function(vm.names.getTime, get_time, 0, attr);
+ define_native_function(vm.names.getUTCDate, get_utc_date, 0, attr);
+ define_native_function(vm.names.getUTCDay, get_utc_day, 0, attr);
+ define_native_function(vm.names.getUTCFullYear, get_utc_full_year, 0, attr);
+ define_native_function(vm.names.getUTCHours, get_utc_hours, 0, attr);
+ define_native_function(vm.names.getUTCMilliseconds, get_utc_milliseconds, 0, attr);
+ define_native_function(vm.names.getUTCMinutes, get_utc_minutes, 0, attr);
+ define_native_function(vm.names.getUTCMonth, get_utc_month, 0, attr);
+ define_native_function(vm.names.getUTCSeconds, get_utc_seconds, 0, attr);
+ define_native_function(vm.names.toDateString, to_date_string, 0, attr);
+ define_native_function(vm.names.toISOString, to_iso_string, 0, attr);
+ define_native_function(vm.names.toLocaleDateString, to_locale_date_string, 0, attr);
+ define_native_function(vm.names.toLocaleString, to_locale_string, 0, attr);
+ define_native_function(vm.names.toLocaleTimeString, to_locale_time_string, 0, attr);
+ define_native_function(vm.names.toTimeString, to_time_string, 0, attr);
+ define_native_function(vm.names.toString, to_string, 0, attr);
// Aliases.
- define_native_function("valueOf", get_time, 0, attr);
+ define_native_function(vm.names.valueOf, get_time, 0, attr);
// toJSON() isn't quite an alias for toISOString():
// - it returns null instead of throwing RangeError
// - its .length is 1, not 0
diff --git a/Libraries/LibJS/Runtime/Error.cpp b/Libraries/LibJS/Runtime/Error.cpp
index ce17bbed9f..f0d8c891b4 100644
--- a/Libraries/LibJS/Runtime/Error.cpp
+++ b/Libraries/LibJS/Runtime/Error.cpp
@@ -51,7 +51,7 @@ Error::~Error()
return global_object.heap().allocate<ClassName>(global_object, message, *global_object.snake_name##_prototype()); \
} \
ClassName::ClassName(const String& message, Object& prototype) \
- : Error(#ClassName, message, prototype) \
+ : Error(vm().names.ClassName, message, prototype) \
{ \
} \
ClassName::~ClassName() { }
diff --git a/Libraries/LibJS/Runtime/ErrorConstructor.cpp b/Libraries/LibJS/Runtime/ErrorConstructor.cpp
index 0c00b78485..28b01bac33 100644
--- a/Libraries/LibJS/Runtime/ErrorConstructor.cpp
+++ b/Libraries/LibJS/Runtime/ErrorConstructor.cpp
@@ -31,15 +31,16 @@
namespace JS {
ErrorConstructor::ErrorConstructor(GlobalObject& global_object)
- : NativeFunction("Error", *global_object.function_prototype())
+ : NativeFunction(vm().names.Error, *global_object.function_prototype())
{
}
void ErrorConstructor::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
NativeFunction::initialize(global_object);
- define_property("prototype", global_object.error_prototype(), 0);
- define_property("length", Value(1), Attribute::Configurable);
+ define_property(vm.names.prototype, global_object.error_prototype(), 0);
+ define_property(vm.names.length, Value(1), Attribute::Configurable);
}
ErrorConstructor::~ErrorConstructor()
@@ -60,7 +61,7 @@ Value ErrorConstructor::construct(Function&)
if (vm.exception())
return {};
}
- return Error::create(global_object(), "Error", message);
+ return Error::create(global_object(), vm.names.Error, message);
}
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \
@@ -70,9 +71,10 @@ Value ErrorConstructor::construct(Function&)
} \
void ConstructorName::initialize(GlobalObject& global_object) \
{ \
+ auto& vm = this->vm(); \
NativeFunction::initialize(global_object); \
- define_property("prototype", global_object.snake_name##_prototype(), 0); \
- define_property("length", Value(1), Attribute::Configurable); \
+ define_property(vm.names.prototype, global_object.snake_name##_prototype(), 0); \
+ define_property(vm.names.length, Value(1), Attribute::Configurable); \
} \
ConstructorName::~ConstructorName() { } \
Value ConstructorName::call() \
diff --git a/Libraries/LibJS/Runtime/ErrorPrototype.cpp b/Libraries/LibJS/Runtime/ErrorPrototype.cpp
index c448d3deb6..0a74ee8173 100644
--- a/Libraries/LibJS/Runtime/ErrorPrototype.cpp
+++ b/Libraries/LibJS/Runtime/ErrorPrototype.cpp
@@ -41,11 +41,12 @@ ErrorPrototype::ErrorPrototype(GlobalObject& global_object)
void ErrorPrototype::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
Object::initialize(global_object);
u8 attr = Attribute::Writable | Attribute::Configurable;
- define_native_property("name", name_getter, name_setter, attr);
- define_native_property("message", message_getter, nullptr, attr);
- define_native_function("toString", to_string, 0, attr);
+ define_native_property(vm.names.name, name_getter, name_setter, attr);
+ define_native_property(vm.names.message, message_getter, nullptr, attr);
+ define_native_function(vm.names.toString, to_string, 0, attr);
}
ErrorPrototype::~ErrorPrototype()
@@ -100,7 +101,7 @@ JS_DEFINE_NATIVE_FUNCTION(ErrorPrototype::to_string)
auto& this_object = vm.this_value(global_object).as_object();
String name = "Error";
- auto name_property = this_object.get("name");
+ auto name_property = this_object.get(vm.names.name);
if (vm.exception())
return {};
if (!name_property.is_empty() && !name_property.is_undefined()) {
@@ -110,7 +111,7 @@ JS_DEFINE_NATIVE_FUNCTION(ErrorPrototype::to_string)
}
String message = "";
- auto message_property = this_object.get("message");
+ auto message_property = this_object.get(vm.names.message);
if (vm.exception())
return {};
if (!message_property.is_empty() && !message_property.is_undefined()) {
diff --git a/Libraries/LibJS/Runtime/Exception.cpp b/Libraries/LibJS/Runtime/Exception.cpp
index efaef88ec2..071a2a97eb 100644
--- a/Libraries/LibJS/Runtime/Exception.cpp
+++ b/Libraries/LibJS/Runtime/Exception.cpp
@@ -35,7 +35,7 @@ Exception::Exception(Value value)
{
auto& call_stack = vm().call_stack();
for (ssize_t i = call_stack.size() - 1; i >= 0; --i) {
- auto function_name = call_stack[i].function_name;
+ String function_name = call_stack[i].function_name;
if (function_name.is_empty())
function_name = "<anonymous>";
m_trace.append(function_name);
diff --git a/Libraries/LibJS/Runtime/Function.cpp b/Libraries/LibJS/Runtime/Function.cpp
index 1881a079b5..7b604e89fa 100644
--- a/Libraries/LibJS/Runtime/Function.cpp
+++ b/Libraries/LibJS/Runtime/Function.cpp
@@ -49,15 +49,16 @@ Function::~Function()
BoundFunction* Function::bind(Value bound_this_value, Vector<Value> arguments)
{
+ auto& vm = this->vm();
Function& target_function = is_bound_function() ? static_cast<BoundFunction&>(*this).target_function() : *this;
- auto bound_this_object = [bound_this_value, this]() -> Value {
+ auto bound_this_object = [&vm, bound_this_value, this]() -> Value {
if (!m_bound_this.is_empty())
return m_bound_this;
switch (bound_this_value.type()) {
case Value::Type::Undefined:
case Value::Type::Null:
- if (vm().in_strict_mode())
+ if (vm.in_strict_mode())
return bound_this_value;
return &global_object();
default:
@@ -66,15 +67,15 @@ BoundFunction* Function::bind(Value bound_this_value, Vector<Value> arguments)
}();
i32 computed_length = 0;
- auto length_property = get("length");
- if (vm().exception())
+ auto length_property = get(vm.names.length);
+ if (vm.exception())
return nullptr;
if (length_property.is_number())
computed_length = max(0, length_property.as_i32() - static_cast<i32>(arguments.size()));
Object* constructor_prototype = nullptr;
- auto prototype_property = target_function.get("prototype");
- if (vm().exception())
+ auto prototype_property = target_function.get(vm.names.prototype);
+ if (vm.exception())
return nullptr;
if (prototype_property.is_object())
constructor_prototype = &prototype_property.as_object();
diff --git a/Libraries/LibJS/Runtime/FunctionConstructor.cpp b/Libraries/LibJS/Runtime/FunctionConstructor.cpp
index 2368635b00..7b269269c0 100644
--- a/Libraries/LibJS/Runtime/FunctionConstructor.cpp
+++ b/Libraries/LibJS/Runtime/FunctionConstructor.cpp
@@ -36,15 +36,16 @@
namespace JS {
FunctionConstructor::FunctionConstructor(GlobalObject& global_object)
- : NativeFunction("Function", *global_object.function_prototype())
+ : NativeFunction(vm().names.Function, *global_object.function_prototype())
{
}
void FunctionConstructor::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
NativeFunction::initialize(global_object);
- define_property("prototype", global_object.function_prototype(), 0);
- define_property("length", Value(1), Attribute::Configurable);
+ define_property(vm.names.prototype, global_object.function_prototype(), 0);
+ define_property(vm.names.length, Value(1), Attribute::Configurable);
}
FunctionConstructor::~FunctionConstructor()
diff --git a/Libraries/LibJS/Runtime/FunctionPrototype.cpp b/Libraries/LibJS/Runtime/FunctionPrototype.cpp
index a166c3de41..b4dbbee602 100644
--- a/Libraries/LibJS/Runtime/FunctionPrototype.cpp
+++ b/Libraries/LibJS/Runtime/FunctionPrototype.cpp
@@ -45,15 +45,16 @@ FunctionPrototype::FunctionPrototype(GlobalObject& global_object)
void FunctionPrototype::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
Object::initialize(global_object);
u8 attr = Attribute::Writable | Attribute::Configurable;
- define_native_function("apply", apply, 2, attr);
- define_native_function("bind", bind, 1, attr);
- define_native_function("call", call, 1, attr);
- define_native_function("toString", to_string, 0, attr);
- define_native_function(global_object.vm().well_known_symbol_has_instance(), symbol_has_instance, 1, 0);
- define_property("length", Value(0), Attribute::Configurable);
- define_property("name", js_string(heap(), ""), Attribute::Configurable);
+ define_native_function(vm.names.apply, apply, 2, attr);
+ define_native_function(vm.names.bind, bind, 1, attr);
+ define_native_function(vm.names.call, call, 1, attr);
+ define_native_function(vm.names.toString, to_string, 0, attr);
+ define_native_function(vm.well_known_symbol_has_instance(), symbol_has_instance, 1, 0);
+ define_property(vm.names.length, Value(0), Attribute::Configurable);
+ define_property(vm.names.name, js_string(heap(), ""), Attribute::Configurable);
}
FunctionPrototype::~FunctionPrototype()
@@ -78,7 +79,7 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::apply)
vm.throw_exception<TypeError>(global_object, ErrorType::FunctionArgsNotObject);
return {};
}
- auto length_property = arg_array.as_object().get("length");
+ auto length_property = arg_array.as_object().get(vm.names.length);
if (vm.exception())
return {};
auto length = length_property.to_size_t(global_object);
diff --git a/Libraries/LibJS/Runtime/GlobalObject.cpp b/Libraries/LibJS/Runtime/GlobalObject.cpp
index c4a52a6a80..581cf69405 100644
--- a/Libraries/LibJS/Runtime/GlobalObject.cpp
+++ b/Libraries/LibJS/Runtime/GlobalObject.cpp
@@ -75,6 +75,8 @@ GlobalObject::GlobalObject()
void GlobalObject::initialize()
{
+ auto& vm = this->vm();
+
ensure_shape_is_unique();
// These are done first since other prototypes depend on their presence.
@@ -98,36 +100,36 @@ void GlobalObject::initialize()
#undef __JS_ENUMERATE
u8 attr = Attribute::Writable | Attribute::Configurable;
- define_native_function("gc", gc, 0, attr);
- define_native_function("isNaN", is_nan, 1, attr);
- define_native_function("isFinite", is_finite, 1, attr);
- define_native_function("parseFloat", parse_float, 1, attr);
-
- define_property("NaN", js_nan(), 0);
- define_property("Infinity", js_infinity(), 0);
- define_property("undefined", js_undefined(), 0);
-
- define_property("globalThis", this, attr);
- define_property("console", heap().allocate<ConsoleObject>(*this, *this), attr);
- define_property("Math", heap().allocate<MathObject>(*this, *this), attr);
- define_property("JSON", heap().allocate<JSONObject>(*this, *this), attr);
- define_property("Reflect", heap().allocate<ReflectObject>(*this, *this), attr);
-
- add_constructor("Array", m_array_constructor, *m_array_prototype);
- add_constructor("BigInt", m_bigint_constructor, *m_bigint_prototype);
- add_constructor("Boolean", m_boolean_constructor, *m_boolean_prototype);
- add_constructor("Date", m_date_constructor, *m_date_prototype);
- add_constructor("Error", m_error_constructor, *m_error_prototype);
- add_constructor("Function", m_function_constructor, *m_function_prototype);
- add_constructor("Number", m_number_constructor, *m_number_prototype);
- add_constructor("Object", m_object_constructor, *m_object_prototype);
- add_constructor("Proxy", m_proxy_constructor, *m_proxy_prototype);
- add_constructor("RegExp", m_regexp_constructor, *m_regexp_prototype);
- add_constructor("String", m_string_constructor, *m_string_prototype);
- add_constructor("Symbol", m_symbol_constructor, *m_symbol_prototype);
+ define_native_function(vm.names.gc, gc, 0, attr);
+ define_native_function(vm.names.isNaN, is_nan, 1, attr);
+ define_native_function(vm.names.isFinite, is_finite, 1, attr);
+ define_native_function(vm.names.parseFloat, parse_float, 1, attr);
+
+ define_property(vm.names.NaN, js_nan(), 0);
+ define_property(vm.names.Infinity, js_infinity(), 0);
+ define_property(vm.names.undefined, js_undefined(), 0);
+
+ define_property(vm.names.globalThis, this, attr);
+ define_property(vm.names.console, heap().allocate<ConsoleObject>(*this, *this), attr);
+ define_property(vm.names.Math, heap().allocate<MathObject>(*this, *this), attr);
+ define_property(vm.names.JSON, heap().allocate<JSONObject>(*this, *this), attr);
+ define_property(vm.names.Reflect, heap().allocate<ReflectObject>(*this, *this), attr);
+
+ add_constructor(vm.names.Array, m_array_constructor, *m_array_prototype);
+ add_constructor(vm.names.BigInt, m_bigint_constructor, *m_bigint_prototype);
+ add_constructor(vm.names.Boolean, m_boolean_constructor, *m_boolean_prototype);
+ add_constructor(vm.names.Date, m_date_constructor, *m_date_prototype);
+ add_constructor(vm.names.Error, m_error_constructor, *m_error_prototype);
+ add_constructor(vm.names.Function, m_function_constructor, *m_function_prototype);
+ add_constructor(vm.names.Number, m_number_constructor, *m_number_prototype);
+ add_constructor(vm.names.Object, m_object_constructor, *m_object_prototype);
+ add_constructor(vm.names.Proxy, m_proxy_constructor, *m_proxy_prototype);
+ add_constructor(vm.names.RegExp, m_regexp_constructor, *m_regexp_prototype);
+ add_constructor(vm.names.String, m_string_constructor, *m_string_prototype);
+ add_constructor(vm.names.Symbol, m_symbol_constructor, *m_symbol_prototype);
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \
- add_constructor(#ClassName, m_##snake_name##_constructor, *m_##snake_name##_prototype);
+ add_constructor(vm.names.ClassName, m_##snake_name##_constructor, *m_##snake_name##_prototype);
JS_ENUMERATE_ERROR_SUBCLASSES
#undef __JS_ENUMERATE
}
diff --git a/Libraries/LibJS/Runtime/GlobalObject.h b/Libraries/LibJS/Runtime/GlobalObject.h
index 7c0c8892e0..d45c1f74f5 100644
--- a/Libraries/LibJS/Runtime/GlobalObject.h
+++ b/Libraries/LibJS/Runtime/GlobalObject.h
@@ -87,12 +87,13 @@ private:
template<typename ConstructorType>
inline void GlobalObject::add_constructor(const FlyString& property_name, ConstructorType*& constructor, Object& prototype)
{
+ auto& vm = this->vm();
constructor = heap().allocate<ConstructorType>(*this, *this);
- constructor->define_property("name", js_string(heap(), property_name), Attribute::Configurable);
- if (vm().exception())
+ constructor->define_property(vm.names.name, js_string(heap(), property_name), Attribute::Configurable);
+ if (vm.exception())
return;
- prototype.define_property("constructor", constructor, Attribute::Writable | Attribute::Configurable);
- if (vm().exception())
+ prototype.define_property(vm.names.constructor, constructor, Attribute::Writable | Attribute::Configurable);
+ if (vm.exception())
return;
define_property(property_name, constructor, Attribute::Writable | Attribute::Configurable);
}
diff --git a/Libraries/LibJS/Runtime/IteratorOperations.cpp b/Libraries/LibJS/Runtime/IteratorOperations.cpp
index c8a794e076..32c1c00e83 100644
--- a/Libraries/LibJS/Runtime/IteratorOperations.cpp
+++ b/Libraries/LibJS/Runtime/IteratorOperations.cpp
@@ -62,7 +62,7 @@ Object* iterator_next(Object& iterator, Value value)
{
auto& vm = iterator.vm();
auto& global_object = iterator.global_object();
- auto next_method = iterator.get("next");
+ auto next_method = iterator.get(vm.names.next);
if (vm.exception())
return {};
@@ -95,9 +95,10 @@ void iterator_close(Object& iterator)
Value create_iterator_result_object(GlobalObject& global_object, Value value, bool done)
{
+ auto& vm = global_object.vm();
auto* object = Object::create_empty(global_object);
- object->define_property("value", value);
- object->define_property("done", Value(done));
+ object->define_property(vm.names.value, value);
+ object->define_property(vm.names.done, Value(done));
return object;
}
@@ -114,14 +115,14 @@ void get_iterator_values(GlobalObject& global_object, Value value, AK::Function<
if (!next_object)
return;
- auto done_property = next_object->get("done");
+ auto done_property = next_object->get(vm.names.done);
if (vm.exception())
return;
if (!done_property.is_empty() && done_property.to_boolean())
return;
- auto next_value = next_object->get("value");
+ auto next_value = next_object->get(vm.names.value);
if (vm.exception())
return;
diff --git a/Libraries/LibJS/Runtime/JSONObject.cpp b/Libraries/LibJS/Runtime/JSONObject.cpp
index b5c8ab8683..4b43007d3a 100644
--- a/Libraries/LibJS/Runtime/JSONObject.cpp
+++ b/Libraries/LibJS/Runtime/JSONObject.cpp
@@ -154,7 +154,7 @@ String JSONObject::serialize_json_property(GlobalObject& global_object, Stringif
if (vm.exception())
return {};
if (value.is_object()) {
- auto to_json = value.as_object().get("toJSON");
+ auto to_json = value.as_object().get(vm.names.toJSON);
if (vm.exception())
return {};
if (to_json.is_function()) {
diff --git a/Libraries/LibJS/Runtime/MathObject.cpp b/Libraries/LibJS/Runtime/MathObject.cpp
index 5f7039c88f..024d242665 100644
--- a/Libraries/LibJS/Runtime/MathObject.cpp
+++ b/Libraries/LibJS/Runtime/MathObject.cpp
@@ -40,41 +40,42 @@ MathObject::MathObject(GlobalObject& global_object)
void MathObject::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
Object::initialize(global_object);
u8 attr = Attribute::Writable | Attribute::Configurable;
- define_native_function("abs", abs, 1, attr);
- define_native_function("random", random, 0, attr);
- define_native_function("sqrt", sqrt, 1, attr);
- define_native_function("floor", floor, 1, attr);
- define_native_function("ceil", ceil, 1, attr);
- define_native_function("round", round, 1, attr);
- define_native_function("max", max, 2, attr);
- define_native_function("min", min, 2, attr);
- define_native_function("trunc", trunc, 1, attr);
- define_native_function("sin", sin, 1, attr);
- define_native_function("cos", cos, 1, attr);
- define_native_function("tan", tan, 1, attr);
- define_native_function("pow", pow, 2, attr);
- define_native_function("exp", exp, 1, attr);
- define_native_function("expm1", expm1, 1, attr);
- define_native_function("sign", sign, 1, attr);
- define_native_function("clz32", clz32, 1, attr);
- define_native_function("acosh", acosh, 1, attr);
- define_native_function("asinh", asinh, 1, attr);
- define_native_function("atanh", atanh, 1, attr);
- define_native_function("log1p", log1p, 1, attr);
- define_native_function("cbrt", cbrt, 1, attr);
-
- define_property("E", Value(M_E), 0);
- define_property("LN2", Value(M_LN2), 0);
- define_property("LN10", Value(M_LN10), 0);
- define_property("LOG2E", Value(log2(M_E)), 0);
- define_property("LOG10E", Value(log10(M_E)), 0);
- define_property("PI", Value(M_PI), 0);
- define_property("SQRT1_2", Value(M_SQRT1_2), 0);
- define_property("SQRT2", Value(M_SQRT2), 0);
-
- define_property(global_object.vm().well_known_symbol_to_string_tag(), js_string(global_object.heap(), "Math"), Attribute::Configurable);
+ define_native_function(vm.names.abs, abs, 1, attr);
+ define_native_function(vm.names.random, random, 0, attr);
+ define_native_function(vm.names.sqrt, sqrt, 1, attr);
+ define_native_function(vm.names.floor, floor, 1, attr);
+ define_native_function(vm.names.ceil, ceil, 1, attr);
+ define_native_function(vm.names.round, round, 1, attr);
+ define_native_function(vm.names.max, max, 2, attr);
+ define_native_function(vm.names.min, min, 2, attr);
+ define_native_function(vm.names.trunc, trunc, 1, attr);
+ define_native_function(vm.names.sin, sin, 1, attr);
+ define_native_function(vm.names.cos, cos, 1, attr);
+ define_native_function(vm.names.tan, tan, 1, attr);
+ define_native_function(vm.names.pow, pow, 2, attr);
+ define_native_function(vm.names.exp, exp, 1, attr);
+ define_native_function(vm.names.expm1, expm1, 1, attr);
+ define_native_function(vm.names.sign, sign, 1, attr);
+ define_native_function(vm.names.clz32, clz32, 1, attr);
+ define_native_function(vm.names.acosh, acosh, 1, attr);
+ define_native_function(vm.names.asinh, asinh, 1, attr);
+ define_native_function(vm.names.atanh, atanh, 1, attr);
+ define_native_function(vm.names.log1p, log1p, 1, attr);
+ define_native_function(vm.names.cbrt, cbrt, 1, attr);
+
+ define_property(vm.names.E, Value(M_E), 0);
+ define_property(vm.names.LN2, Value(M_LN2), 0);
+ define_property(vm.names.LN10, Value(M_LN10), 0);
+ define_property(vm.names.LOG2E, Value(log2(M_E)), 0);
+ define_property(vm.names.LOG10E, Value(log10(M_E)), 0);
+ define_property(vm.names.PI, Value(M_PI), 0);
+ define_property(vm.names.SQRT1_2, Value(M_SQRT1_2), 0);
+ define_property(vm.names.SQRT2, Value(M_SQRT2), 0);
+
+ define_property(vm.well_known_symbol_to_string_tag(), js_string(vm.heap(), "Math"), Attribute::Configurable);
}
MathObject::~MathObject()
diff --git a/Libraries/LibJS/Runtime/NumberConstructor.cpp b/Libraries/LibJS/Runtime/NumberConstructor.cpp
index f859beb204..4eb26f1211 100644
--- a/Libraries/LibJS/Runtime/NumberConstructor.cpp
+++ b/Libraries/LibJS/Runtime/NumberConstructor.cpp
@@ -30,34 +30,36 @@
#include <LibJS/Runtime/NumberObject.h>
#include <math.h>
-#define EPSILON pow(2, -52)
-#define MAX_SAFE_INTEGER pow(2, 53) - 1
-#define MIN_SAFE_INTEGER -(pow(2, 53) - 1)
+// FIXME: constexpr these?
+#define EPSILON_VALUE pow(2, -52)
+#define MAX_SAFE_INTEGER_VALUE pow(2, 53) - 1
+#define MIN_SAFE_INTEGER_VALUE -(pow(2, 53) - 1)
namespace JS {
NumberConstructor::NumberConstructor(GlobalObject& global_object)
- : NativeFunction("Number", *global_object.function_prototype())
+ : NativeFunction(vm().names.Number, *global_object.function_prototype())
{
}
void NumberConstructor::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
NativeFunction::initialize(global_object);
u8 attr = Attribute::Writable | Attribute::Configurable;
- define_native_function("isFinite", is_finite, 1, attr);
- define_native_function("isInteger", is_integer, 1, attr);
- define_native_function("isNaN", is_nan, 1, attr);
- define_native_function("isSafeInteger", is_safe_integer, 1, attr);
- define_property("parseFloat", global_object.get("parseFloat"));
- define_property("prototype", global_object.number_prototype(), 0);
- define_property("length", Value(1), Attribute::Configurable);
- define_property("EPSILON", Value(EPSILON), 0);
- define_property("MAX_SAFE_INTEGER", Value(MAX_SAFE_INTEGER), 0);
- define_property("MIN_SAFE_INTEGER", Value(MIN_SAFE_INTEGER), 0);
- define_property("NEGATIVE_INFINITY", js_negative_infinity(), 0);
- define_property("POSITIVE_INFINITY", js_infinity(), 0);
- define_property("NaN", js_nan(), 0);
+ define_native_function(vm.names.isFinite, is_finite, 1, attr);
+ define_native_function(vm.names.isInteger, is_integer, 1, attr);
+ define_native_function(vm.names.isNaN, is_nan, 1, attr);
+ define_native_function(vm.names.isSafeInteger, is_safe_integer, 1, attr);
+ define_property(vm.names.parseFloat, global_object.get(vm.names.parseFloat));
+ define_property(vm.names.prototype, global_object.number_prototype(), 0);
+ define_property(vm.names.length, Value(1), Attribute::Configurable);
+ define_property(vm.names.EPSILON, Value(EPSILON_VALUE), 0);
+ define_property(vm.names.MAX_SAFE_INTEGER, Value(MAX_SAFE_INTEGER_VALUE), 0);
+ define_property(vm.names.MIN_SAFE_INTEGER, Value(MIN_SAFE_INTEGER_VALUE), 0);
+ define_property(vm.names.NEGATIVE_INFINITY, js_negative_infinity(), 0);
+ define_property(vm.names.POSITIVE_INFINITY, js_infinity(), 0);
+ define_property(vm.names.NaN, js_nan(), 0);
}
NumberConstructor::~NumberConstructor()
@@ -102,7 +104,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberConstructor::is_safe_integer)
if (!vm.argument(0).is_number())
return Value(false);
auto value = vm.argument(0).as_double();
- return Value((int64_t)value == value && value >= MIN_SAFE_INTEGER && value <= MAX_SAFE_INTEGER);
+ return Value((int64_t)value == value && value >= MIN_SAFE_INTEGER_VALUE && value <= MAX_SAFE_INTEGER_VALUE);
}
}
diff --git a/Libraries/LibJS/Runtime/Object.cpp b/Libraries/LibJS/Runtime/Object.cpp
index fc71268089..aefef76a64 100644
--- a/Libraries/LibJS/Runtime/Object.cpp
+++ b/Libraries/LibJS/Runtime/Object.cpp
@@ -44,36 +44,36 @@ namespace JS {
PropertyDescriptor PropertyDescriptor::from_dictionary(VM& vm, const Object& object)
{
PropertyAttributes attributes;
- if (object.has_property("configurable")) {
+ if (object.has_property(vm.names.configurable)) {
attributes.set_has_configurable();
- if (object.get("configurable").value_or(Value(false)).to_boolean())
+ if (object.get(vm.names.configurable).value_or(Value(false)).to_boolean())
attributes.set_configurable();
if (vm.exception())
return {};
}
- if (object.has_property("enumerable")) {
+ if (object.has_property(vm.names.enumerable)) {
attributes.set_has_enumerable();
- if (object.get("enumerable").value_or(Value(false)).to_boolean())
+ if (object.get(vm.names.enumerable).value_or(Value(false)).to_boolean())
attributes.set_enumerable();
if (vm.exception())
return {};
}
- if (object.has_property("writable")) {
+ if (object.has_property(vm.names.writable)) {
attributes.set_has_writable();
- if (object.get("writable").value_or(Value(false)).to_boolean())
+ if (object.get(vm.names.writable).value_or(Value(false)).to_boolean())
attributes.set_writable();
if (vm.exception())
return {};
}
- PropertyDescriptor descriptor { attributes, object.get("value"), nullptr, nullptr };
+ PropertyDescriptor descriptor { attributes, object.get(vm.names.value), nullptr, nullptr };
if (vm.exception())
return {};
- auto getter = object.get("get");
+ auto getter = object.get(vm.names.get);
if (vm.exception())
return {};
if (getter.is_function())
descriptor.getter = &getter.as_function();
- auto setter = object.get("set");
+ auto setter = object.get(vm.names.set);
if (vm.exception())
return {};
if (setter.is_function())
@@ -295,34 +295,35 @@ Optional<PropertyDescriptor> Object::get_own_property_descriptor(const PropertyN
Value Object::get_own_property_descriptor_object(const PropertyName& property_name) const
{
+ auto& vm = this->vm();
auto descriptor_opt = get_own_property_descriptor(property_name);
if (!descriptor_opt.has_value())
return js_undefined();
auto descriptor = descriptor_opt.value();
auto* descriptor_object = Object::create_empty(global_object());
- descriptor_object->define_property("enumerable", Value(descriptor.attributes.is_enumerable()));
- if (vm().exception())
+ descriptor_object->define_property(vm.names.enumerable, Value(descriptor.attributes.is_enumerable()));
+ if (vm.exception())
return {};
- descriptor_object->define_property("configurable", Value(descriptor.attributes.is_configurable()));
- if (vm().exception())
+ descriptor_object->define_property(vm.names.configurable, Value(descriptor.attributes.is_configurable()));
+ if (vm.exception())
return {};
if (descriptor.is_data_descriptor()) {
- descriptor_object->define_property("value", descriptor.value.value_or(js_undefined()));
- if (vm().exception())
+ descriptor_object->define_property(vm.names.value, descriptor.value.value_or(js_undefined()));
+ if (vm.exception())
return {};
- descriptor_object->define_property("writable", Value(descriptor.attributes.is_writable()));
- if (vm().exception())
+ descriptor_object->define_property(vm.names.writable, Value(descriptor.attributes.is_writable()));
+ if (vm.exception())
return {};
} else if (descriptor.is_accessor_descriptor()) {
if (descriptor.getter) {
- descriptor_object->define_property("get", Value(descriptor.getter));
- if (vm().exception())
+ descriptor_object->define_property(vm.names.get, Value(descriptor.getter));
+ if (vm.exception())
return {};
}
if (descriptor.setter) {
- descriptor_object->define_property("set", Value(descriptor.setter));
- if (vm().exception())
+ descriptor_object->define_property(vm.names.set, Value(descriptor.setter));
+ if (vm.exception())
return {};
}
}
@@ -337,35 +338,36 @@ void Object::set_shape(Shape& new_shape)
bool Object::define_property(const StringOrSymbol& property_name, const Object& descriptor, bool throw_exceptions)
{
- bool is_accessor_property = descriptor.has_property("get") || descriptor.has_property("set");
+ auto& vm = this->vm();
+ bool is_accessor_property = descriptor.has_property(vm.names.get) || descriptor.has_property(vm.names.set);
PropertyAttributes attributes;
- if (descriptor.has_property("configurable")) {
+ if (descriptor.has_property(vm.names.configurable)) {
attributes.set_has_configurable();
- if (descriptor.get("configurable").value_or(Value(false)).to_boolean())
+ if (descriptor.get(vm.names.configurable).value_or(Value(false)).to_boolean())
attributes.set_configurable();
- if (vm().exception())
+ if (vm.exception())
return false;
}
- if (descriptor.has_property("enumerable")) {
+ if (descriptor.has_property(vm.names.enumerable)) {
attributes.set_has_enumerable();
- if (descriptor.get("enumerable").value_or(Value(false)).to_boolean())
+ if (descriptor.get(vm.names.enumerable).value_or(Value(false)).to_boolean())
attributes.set_enumerable();
- if (vm().exception())
+ if (vm.exception())
return false;
}
if (is_accessor_property) {
- if (descriptor.has_property("value") || descriptor.has_property("writable")) {
+ if (descriptor.has_property(vm.names.value) || descriptor.has_property(vm.names.writable)) {
if (throw_exceptions)
- vm().throw_exception<TypeError>(global_object(), ErrorType::AccessorValueOrWritable);
+ vm.throw_exception<TypeError>(global_object(), ErrorType::AccessorValueOrWritable);
return false;
}
- auto getter = descriptor.get("get").value_or(js_undefined());
- if (vm().exception())
+ auto getter = descriptor.get(vm.names.get).value_or(js_undefined());
+ if (vm.exception())
return {};
- auto setter = descriptor.get("set").value_or(js_undefined());
- if (vm().exception())
+ auto setter = descriptor.get(vm.names.set).value_or(js_undefined());
+ if (vm.exception())
return {};
Function* getter_function { nullptr };
@@ -374,14 +376,14 @@ bool Object::define_property(const StringOrSymbol& property_name, const Object&
if (getter.is_function()) {
getter_function = &getter.as_function();
} else if (!getter.is_undefined()) {
- vm().throw_exception<TypeError>(global_object(), ErrorType::AccessorBadField, "get");
+ vm.throw_exception<TypeError>(global_object(), ErrorType::AccessorBadField, "get");
return false;
}
if (setter.is_function()) {
setter_function = &setter.as_function();
} else if (!setter.is_undefined()) {
- vm().throw_exception<TypeError>(global_object(), ErrorType::AccessorBadField, "set");
+ vm.throw_exception<TypeError>(global_object(), ErrorType::AccessorBadField, "set");
return false;
}
@@ -391,20 +393,20 @@ bool Object::define_property(const StringOrSymbol& property_name, const Object&
<< "setter=" << setter.to_string_without_side_effects() << "}";
#endif
- return define_property(property_name, Accessor::create(vm(), getter_function, setter_function), attributes, throw_exceptions);
+ return define_property(property_name, Accessor::create(vm, getter_function, setter_function), attributes, throw_exceptions);
}
- auto value = descriptor.get("value");
- if (vm().exception())
+ auto value = descriptor.get(vm.names.value);
+ if (vm.exception())
return {};
- if (descriptor.has_property("writable")) {
+ if (descriptor.has_property(vm.names.writable)) {
attributes.set_has_writable();
- if (descriptor.get("writable").value_or(Value(false)).to_boolean())
+ if (descriptor.get(vm.names.writable).value_or(Value(false)).to_boolean())
attributes.set_writable();
- if (vm().exception())
+ if (vm.exception())
return false;
}
- if (vm().exception())
+ if (vm.exception())
return {};
#ifdef OBJECT_DEBUG
@@ -462,6 +464,14 @@ bool Object::put_own_property(Object& this_object, const StringOrSymbol& propert
{
ASSERT(!(mode == PutOwnPropertyMode::Put && value.is_accessor()));
+ if (value.is_accessor()) {
+ auto& accessor = value.as_accessor();
+ if (accessor.getter())
+ attributes.set_has_getter();
+ if (accessor.setter())
+ attributes.set_has_setter();
+ }
+
auto metadata = shape().lookup(property_name);
bool new_property = !metadata.has_value();
@@ -474,14 +484,6 @@ bool Object::put_own_property(Object& this_object, const StringOrSymbol& propert
return false;
}
- if (value.is_accessor()) {
- auto& accessor = value.as_accessor();
- if (accessor.getter())
- attributes.set_has_getter();
- if (accessor.setter())
- attributes.set_has_setter();
- }
-
if (new_property) {
if (!m_shape->is_unique() && shape().property_count() > 100) {
// If you add more than 100 properties to an object, let's stop doing
@@ -752,6 +754,7 @@ bool Object::put(const PropertyName& property_name, Value value, Value receiver)
bool Object::define_native_function(const StringOrSymbol& property_name, AK::Function<Value(VM&, GlobalObject&)> native_function, i32 length, PropertyAttributes attribute)
{
+ auto& vm = this->vm();
String function_name;
if (property_name.is_string()) {
function_name = property_name.as_string();
@@ -759,11 +762,11 @@ bool Object::define_native_function(const StringOrSymbol& property_name, AK::Fun
function_name = String::formatted("[{}]", property_name.as_symbol()->description());
}
auto* function = NativeFunction::create(global_object(), function_name, move(native_function));
- function->define_property_without_transition("length", Value(length), Attribute::Configurable);
- if (vm().exception())
+ function->define_property_without_transition(vm.names.length, Value(length), Attribute::Configurable);
+ if (vm.exception())
return {};
- function->define_property_without_transition("name", js_string(heap(), function_name), Attribute::Configurable);
- if (vm().exception())
+ function->define_property_without_transition(vm.names.name, js_string(vm.heap(), function_name), Attribute::Configurable);
+ if (vm.exception())
return {};
return define_property(property_name, function, attribute);
}
@@ -846,7 +849,7 @@ Value Object::to_primitive(Value::PreferredType preferred_type) const
Value Object::to_string() const
{
auto& vm = this->vm();
- auto to_string_property = get("toString");
+ auto to_string_property = get(vm.names.toString);
if (to_string_property.is_function()) {
auto& to_string_function = to_string_property.as_function();
auto to_string_result = vm.call(to_string_function, const_cast<Object*>(this));
@@ -859,7 +862,7 @@ Value Object::to_string() const
return {};
return string;
}
- return js_string(heap(), String::formatted("[object {}]", class_name()));
+ return js_string(vm, String::formatted("[object {}]", class_name()));
}
Value Object::invoke(const StringOrSymbol& property_name, Optional<MarkedValueList> arguments)
diff --git a/Libraries/LibJS/Runtime/ObjectConstructor.cpp b/Libraries/LibJS/Runtime/ObjectConstructor.cpp
index f6c6cb7d77..2eda863241 100644
--- a/Libraries/LibJS/Runtime/ObjectConstructor.cpp
+++ b/Libraries/LibJS/Runtime/ObjectConstructor.cpp
@@ -35,28 +35,29 @@
namespace JS {
ObjectConstructor::ObjectConstructor(GlobalObject& global_object)
- : NativeFunction("Object", *global_object.function_prototype())
+ : NativeFunction(vm().names.Object, *global_object.function_prototype())
{
}
void ObjectConstructor::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
NativeFunction::initialize(global_object);
- define_property("prototype", global_object.object_prototype(), 0);
- define_property("length", Value(1), Attribute::Configurable);
+ define_property(vm.names.prototype, global_object.object_prototype(), 0);
+ define_property(vm.names.length, Value(1), Attribute::Configurable);
u8 attr = Attribute::Writable | Attribute::Configurable;
- define_native_function("defineProperty", define_property_, 3, attr);
- define_native_function("is", is, 2, attr);
- define_native_function("getOwnPropertyDescriptor", get_own_property_descriptor, 2, attr);
- define_native_function("getOwnPropertyNames", get_own_property_names, 1, attr);
- define_native_function("getPrototypeOf", get_prototype_of, 1, attr);
- define_native_function("setPrototypeOf", set_prototype_of, 2, attr);
- define_native_function("isExtensible", is_extensible, 1, attr);
- define_native_function("preventExtensions", prevent_extensions, 1, attr);
- define_native_function("keys", keys, 1, attr);
- define_native_function("values", values, 1, attr);
- define_native_function("entries", entries, 1, attr);
+ define_native_function(vm.names.defineProperty, define_property_, 3, attr);
+ define_native_function(vm.names.is, is, 2, attr);
+ define_native_function(vm.names.getOwnPropertyDescriptor, get_own_property_descriptor, 2, attr);
+ define_native_function(vm.names.getOwnPropertyNames, get_own_property_names, 1, attr);
+ define_native_function(vm.names.getPrototypeOf, get_prototype_of, 1, attr);
+ define_native_function(vm.names.setPrototypeOf, set_prototype_of, 2, attr);
+ define_native_function(vm.names.isExtensible, is_extensible, 1, attr);
+ define_native_function(vm.names.preventExtensions, prevent_extensions, 1, attr);
+ define_native_function(vm.names.keys, keys, 1, attr);
+ define_native_function(vm.names.values, values, 1, attr);
+ define_native_function(vm.names.entries, entries, 1, attr);
}
ObjectConstructor::~ObjectConstructor()
diff --git a/Libraries/LibJS/Runtime/ObjectPrototype.cpp b/Libraries/LibJS/Runtime/ObjectPrototype.cpp
index d01054d5c3..2f620fa457 100644
--- a/Libraries/LibJS/Runtime/ObjectPrototype.cpp
+++ b/Libraries/LibJS/Runtime/ObjectPrototype.cpp
@@ -40,14 +40,15 @@ ObjectPrototype::ObjectPrototype(GlobalObject& global_object)
void ObjectPrototype::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
Object::initialize(global_object);
// This must be called after the constructor has returned, so that the below code
// can find the ObjectPrototype through normal paths.
u8 attr = Attribute::Writable | Attribute::Configurable;
- define_native_function("hasOwnProperty", has_own_property, 1, attr);
- define_native_function("toString", to_string, 0, attr);
- define_native_function("toLocaleString", to_locale_string, 0, attr);
- define_native_function("valueOf", value_of, 0, attr);
+ define_native_function(vm.names.hasOwnProperty, has_own_property, 1, attr);
+ define_native_function(vm.names.toString, to_string, 0, attr);
+ define_native_function(vm.names.toLocaleString, to_locale_string, 0, attr);
+ define_native_function(vm.names.valueOf, value_of, 0, attr);
}
ObjectPrototype::~ObjectPrototype()
diff --git a/Libraries/LibJS/Runtime/ProxyConstructor.cpp b/Libraries/LibJS/Runtime/ProxyConstructor.cpp
index 293b70ec61..747b74a852 100644
--- a/Libraries/LibJS/Runtime/ProxyConstructor.cpp
+++ b/Libraries/LibJS/Runtime/ProxyConstructor.cpp
@@ -33,15 +33,16 @@
namespace JS {
ProxyConstructor::ProxyConstructor(GlobalObject& global_object)
- : NativeFunction("Proxy", *global_object.function_prototype())
+ : NativeFunction(vm().names.Proxy, *global_object.function_prototype())
{
}
void ProxyConstructor::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
NativeFunction::initialize(global_object);
- define_property("prototype", global_object.proxy_prototype(), 0);
- define_property("length", Value(2), Attribute::Configurable);
+ define_property(vm.names.prototype, global_object.proxy_prototype(), 0);
+ define_property(vm.names.length, Value(2), Attribute::Configurable);
}
ProxyConstructor::~ProxyConstructor()
diff --git a/Libraries/LibJS/Runtime/ProxyObject.cpp b/Libraries/LibJS/Runtime/ProxyObject.cpp
index 45b04f8354..fcfa586fa3 100644
--- a/Libraries/LibJS/Runtime/ProxyObject.cpp
+++ b/Libraries/LibJS/Runtime/ProxyObject.cpp
@@ -79,7 +79,7 @@ Object* ProxyObject::prototype()
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
return nullptr;
}
- auto trap = m_handler.get("getPrototypeOf");
+ auto trap = m_handler.get(vm().names.getPrototypeOf);
if (vm().exception())
return nullptr;
if (trap.is_empty() || trap.is_nullish())
@@ -128,7 +128,7 @@ bool ProxyObject::set_prototype(Object* object)
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
return false;
}
- auto trap = m_handler.get("setPrototypeOf");
+ auto trap = m_handler.get(vm().names.setPrototypeOf);
if (vm().exception())
return false;
if (trap.is_empty() || trap.is_nullish())
@@ -159,7 +159,7 @@ bool ProxyObject::is_extensible() const
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
return false;
}
- auto trap = m_handler.get("isExtensible");
+ auto trap = m_handler.get(vm().names.isExtensible);
if (vm().exception())
return false;
if (trap.is_empty() || trap.is_nullish())
@@ -186,7 +186,7 @@ bool ProxyObject::prevent_extensions()
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
return false;
}
- auto trap = m_handler.get("preventExtensions");
+ auto trap = m_handler.get(vm().names.preventExtensions);
if (vm().exception())
return false;
if (trap.is_empty() || trap.is_nullish())
@@ -213,7 +213,7 @@ Optional<PropertyDescriptor> ProxyObject::get_own_property_descriptor(const Prop
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
return {};
}
- auto trap = m_handler.get("getOwnPropertyDescriptor");
+ auto trap = m_handler.get(vm().names.getOwnPropertyDescriptor);
if (vm().exception())
return {};
if (trap.is_empty() || trap.is_nullish())
@@ -268,7 +268,7 @@ bool ProxyObject::define_property(const StringOrSymbol& property_name, const Obj
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
return false;
}
- auto trap = m_handler.get("defineProperty");
+ auto trap = m_handler.get(vm().names.defineProperty);
if (vm().exception())
return false;
if (trap.is_empty() || trap.is_nullish())
@@ -285,7 +285,7 @@ bool ProxyObject::define_property(const StringOrSymbol& property_name, const Obj
if (vm().exception())
return false;
bool setting_config_false = false;
- if (descriptor.has_property("configurable") && !descriptor.get("configurable").to_boolean())
+ if (descriptor.has_property(vm().names.configurable) && !descriptor.get(vm().names.configurable).to_boolean())
setting_config_false = true;
if (vm().exception())
return false;
@@ -319,7 +319,7 @@ bool ProxyObject::has_property(const PropertyName& name) const
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
return false;
}
- auto trap = m_handler.get("has");
+ auto trap = m_handler.get(vm().names.has);
if (vm().exception())
return false;
if (trap.is_empty() || trap.is_nullish())
@@ -357,7 +357,7 @@ Value ProxyObject::get(const PropertyName& name, Value) const
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
return {};
}
- auto trap = m_handler.get("get");
+ auto trap = m_handler.get(vm().names.get);
if (vm().exception())
return {};
if (trap.is_empty() || trap.is_nullish())
@@ -388,32 +388,33 @@ Value ProxyObject::get(const PropertyName& name, Value) const
bool ProxyObject::put(const PropertyName& name, Value value, Value)
{
+ auto& vm = this->vm();
if (m_is_revoked) {
- vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
+ vm.throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
return false;
}
- auto trap = m_handler.get("set");
- if (vm().exception())
+ auto trap = m_handler.get(vm.names.set);
+ if (vm.exception())
return false;
if (trap.is_empty() || trap.is_nullish())
return m_target.put(name, value);
if (!trap.is_function()) {
- vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "set");
+ vm.throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "set");
return false;
}
- auto trap_result = vm().call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(vm(), name.to_string()), value, Value(const_cast<ProxyObject*>(this))).to_boolean();
- if (vm().exception() || !trap_result)
+ auto trap_result = vm.call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(vm, name.to_string()), value, Value(const_cast<ProxyObject*>(this))).to_boolean();
+ if (vm.exception() || !trap_result)
return false;
auto target_desc = m_target.get_own_property_descriptor(name);
- if (vm().exception())
+ if (vm.exception())
return false;
if (target_desc.has_value() && !target_desc.value().attributes.is_configurable()) {
if (target_desc.value().is_data_descriptor() && !target_desc.value().attributes.is_writable() && !same_value(value, target_desc.value().value)) {
- vm().throw_exception<TypeError>(global_object(), ErrorType::ProxySetImmutableDataProperty);
+ vm.throw_exception<TypeError>(global_object(), ErrorType::ProxySetImmutableDataProperty);
return false;
}
if (target_desc.value().is_accessor_descriptor() && !target_desc.value().setter) {
- vm().throw_exception<TypeError>(global_object(), ErrorType::ProxySetNonConfigurableAccessor);
+ vm.throw_exception<TypeError>(global_object(), ErrorType::ProxySetNonConfigurableAccessor);
}
}
return true;
@@ -421,32 +422,33 @@ bool ProxyObject::put(const PropertyName& name, Value value, Value)
Value ProxyObject::delete_property(const PropertyName& name)
{
+ auto& vm = this->vm();
if (m_is_revoked) {
- vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
+ vm.throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
return {};
}
- auto trap = m_handler.get("deleteProperty");
- if (vm().exception())
+ auto trap = m_handler.get(vm.names.deleteProperty);
+ if (vm.exception())
return {};
if (trap.is_empty() || trap.is_nullish())
return m_target.delete_property(name);
if (!trap.is_function()) {
- vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "deleteProperty");
+ vm.throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "deleteProperty");
return {};
}
- auto trap_result = vm().call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(vm(), name.to_string())).to_boolean();
- if (vm().exception())
+ auto trap_result = vm.call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(vm, name.to_string())).to_boolean();
+ if (vm.exception())
return {};
if (!trap_result)
return Value(false);
auto target_desc = m_target.get_own_property_descriptor(name);
- if (vm().exception())
+ if (vm.exception())
return {};
if (!target_desc.has_value())
return Value(true);
if (!target_desc.value().attributes.is_configurable()) {
- vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyDeleteNonConfigurable);
+ vm.throw_exception<TypeError>(global_object(), ErrorType::ProxyDeleteNonConfigurable);
return {};
}
return Value(true);
@@ -461,21 +463,22 @@ void ProxyObject::visit_children(Cell::Visitor& visitor)
Value ProxyObject::call()
{
+ auto& vm = this->vm();
if (!is_function()) {
- vm().throw_exception<TypeError>(global_object(), ErrorType::NotAFunction, Value(this).to_string_without_side_effects());
+ vm.throw_exception<TypeError>(global_object(), ErrorType::NotAFunction, Value(this).to_string_without_side_effects());
return {};
}
if (m_is_revoked) {
- vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
+ vm.throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
return {};
}
- auto trap = m_handler.get("apply");
- if (vm().exception())
+ auto trap = m_handler.get(vm.names.apply);
+ if (vm.exception())
return {};
if (trap.is_empty() || trap.is_nullish())
return static_cast<Function&>(m_target).call();
if (!trap.is_function()) {
- vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "apply");
+ vm.throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "apply");
return {};
}
MarkedValueList arguments(heap());
@@ -483,12 +486,12 @@ Value ProxyObject::call()
arguments.append(Value(&m_handler));
// FIXME: Pass global object
auto arguments_array = Array::create(global_object());
- vm().for_each_argument([&](auto& argument) {
+ vm.for_each_argument([&](auto& argument) {
arguments_array->indexed_properties().append(argument);
});
arguments.append(arguments_array);
- return vm().call(trap.as_function(), Value(&m_handler), move(arguments));
+ return vm.call(trap.as_function(), Value(&m_handler), move(arguments));
}
Value ProxyObject::construct(Function& new_target)
@@ -502,7 +505,7 @@ Value ProxyObject::construct(Function& new_target)
vm.throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
return {};
}
- auto trap = m_handler.get("construct");
+ auto trap = m_handler.get(vm.names.construct);
if (vm.exception())
return {};
if (trap.is_empty() || trap.is_nullish())
diff --git a/Libraries/LibJS/Runtime/ReflectObject.cpp b/Libraries/LibJS/Runtime/ReflectObject.cpp
index 8ab3bbe144..9fc7cd429c 100644
--- a/Libraries/LibJS/Runtime/ReflectObject.cpp
+++ b/Libraries/LibJS/Runtime/ReflectObject.cpp
@@ -63,7 +63,7 @@ static void prepare_arguments_list(GlobalObject& global_object, Value value, Mar
return;
}
auto& arguments_list = value.as_object();
- auto length_property = arguments_list.get("length");
+ auto length_property = arguments_list.get(vm.names.length);
if (vm.exception())
return;
auto length = length_property.to_size_t(global_object);
@@ -84,21 +84,22 @@ ReflectObject::ReflectObject(GlobalObject& global_object)
void ReflectObject::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
Object::initialize(global_object);
u8 attr = Attribute::Writable | Attribute::Configurable;
- define_native_function("apply", apply, 3, attr);
- define_native_function("construct", construct, 2, attr);
- define_native_function("defineProperty", define_property, 3, attr);
- define_native_function("deleteProperty", delete_property, 2, attr);
- define_native_function("get", get, 2, attr);
- define_native_function("getOwnPropertyDescriptor", get_own_property_descriptor, 2, attr);
- define_native_function("getPrototypeOf", get_prototype_of, 1, attr);
- define_native_function("has", has, 2, attr);
- define_native_function("isExtensible", is_extensible, 1, attr);
- define_native_function("ownKeys", own_keys, 1, attr);
- define_native_function("preventExtensions", prevent_extensions, 1, attr);
- define_native_function("set", set, 3, attr);
- define_native_function("setPrototypeOf", set_prototype_of, 2, attr);
+ define_native_function(vm.names.apply, apply, 3, attr);
+ define_native_function(vm.names.construct, construct, 2, attr);
+ define_native_function(vm.names.defineProperty, define_property, 3, attr);
+ define_native_function(vm.names.deleteProperty, delete_property, 2, attr);
+ define_native_function(vm.names.get, get, 2, attr);
+ define_native_function(vm.names.getOwnPropertyDescriptor, get_own_property_descriptor, 2, attr);
+ define_native_function(vm.names.getPrototypeOf, get_prototype_of, 1, attr);
+ define_native_function(vm.names.has, has, 2, attr);
+ define_native_function(vm.names.isExtensible, is_extensible, 1, attr);
+ define_native_function(vm.names.ownKeys, own_keys, 1, attr);
+ define_native_function(vm.names.preventExtensions, prevent_extensions, 1, attr);
+ define_native_function(vm.names.set, set, 3, attr);
+ define_native_function(vm.names.setPrototypeOf, set_prototype_of, 2, attr);
}
ReflectObject::~ReflectObject()
diff --git a/Libraries/LibJS/Runtime/RegExpConstructor.cpp b/Libraries/LibJS/Runtime/RegExpConstructor.cpp
index 8031b8f39c..6e96637d38 100644
--- a/Libraries/LibJS/Runtime/RegExpConstructor.cpp
+++ b/Libraries/LibJS/Runtime/RegExpConstructor.cpp
@@ -32,15 +32,16 @@
namespace JS {
RegExpConstructor::RegExpConstructor(GlobalObject& global_object)
- : NativeFunction("RegExp", *global_object.function_prototype())
+ : NativeFunction(vm().names.RegExp, *global_object.function_prototype())
{
}
void RegExpConstructor::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
NativeFunction::initialize(global_object);
- define_property("prototype", global_object.regexp_prototype(), 0);
- define_property("length", Value(2), Attribute::Configurable);
+ define_property(vm.names.prototype, global_object.regexp_prototype(), 0);
+ define_property(vm.names.length, Value(2), Attribute::Configurable);
}
RegExpConstructor::~RegExpConstructor()
diff --git a/Libraries/LibJS/Runtime/ScriptFunction.cpp b/Libraries/LibJS/Runtime/ScriptFunction.cpp
index 668f747e00..4218045dd0 100644
--- a/Libraries/LibJS/Runtime/ScriptFunction.cpp
+++ b/Libraries/LibJS/Runtime/ScriptFunction.cpp
@@ -66,14 +66,15 @@ ScriptFunction::ScriptFunction(GlobalObject& global_object, const FlyString& nam
void ScriptFunction::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
Function::initialize(global_object);
if (!m_is_arrow_function) {
Object* prototype = Object::create_empty(global_object);
- prototype->define_property_without_transition("constructor", this, Attribute::Writable | Attribute::Configurable);
- define_property("prototype", prototype, 0);
+ prototype->define_property_without_transition(vm.names.constructor, this, Attribute::Writable | Attribute::Configurable);
+ define_property(vm.names.prototype, prototype, 0);
}
- define_native_property("length", length_getter, nullptr, Attribute::Configurable);
- define_native_property("name", name_getter, nullptr, Attribute::Configurable);
+ define_native_property(vm.names.length, length_getter, nullptr, Attribute::Configurable);
+ define_native_property(vm.names.name, name_getter, nullptr, Attribute::Configurable);
}
ScriptFunction::~ScriptFunction()
diff --git a/Libraries/LibJS/Runtime/StringConstructor.cpp b/Libraries/LibJS/Runtime/StringConstructor.cpp
index b8c4e3592f..50872f2387 100644
--- a/Libraries/LibJS/Runtime/StringConstructor.cpp
+++ b/Libraries/LibJS/Runtime/StringConstructor.cpp
@@ -35,19 +35,20 @@
namespace JS {
StringConstructor::StringConstructor(GlobalObject& global_object)
- : NativeFunction("String", *global_object.function_prototype())
+ : NativeFunction(vm().names.String, *global_object.function_prototype())
{
}
void StringConstructor::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
NativeFunction::initialize(global_object);
- define_property("prototype", global_object.string_prototype(), 0);
- define_property("length", Value(1), Attribute::Configurable);
+ define_property(vm.names.prototype, global_object.string_prototype(), 0);
+ define_property(vm.names.length, Value(1), Attribute::Configurable);
u8 attr = Attribute::Writable | Attribute::Configurable;
- define_native_function("raw", raw, 1, attr);
- define_native_function("fromCharCode", from_char_code, 1, attr);
+ define_native_function(vm.names.raw, raw, 1, attr);
+ define_native_function(vm.names.fromCharCode, from_char_code, 1, attr);
}
StringConstructor::~StringConstructor()
@@ -84,7 +85,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringConstructor::raw)
if (vm.exception())
return {};
- auto raw = template_object->get("raw");
+ auto raw = template_object->get(vm.names.raw);
if (vm.exception())
return {};
if (raw.is_empty() || raw.is_nullish()) {
diff --git a/Libraries/LibJS/Runtime/StringIteratorPrototype.cpp b/Libraries/LibJS/Runtime/StringIteratorPrototype.cpp
index 31f1a4a226..b7c599c485 100644
--- a/Libraries/LibJS/Runtime/StringIteratorPrototype.cpp
+++ b/Libraries/LibJS/Runtime/StringIteratorPrototype.cpp
@@ -40,10 +40,10 @@ StringIteratorPrototype::StringIteratorPrototype(GlobalObject& global_object)
void StringIteratorPrototype::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
Object::initialize(global_object);
-
- define_native_function("next", next, 0, Attribute::Configurable | Attribute::Writable);
- define_property(global_object.vm().well_known_symbol_to_string_tag(), js_string(global_object.heap(), "String Iterator"), Attribute::Configurable);
+ define_native_function(vm.names.next, next, 0, Attribute::Configurable | Attribute::Writable);
+ define_property(vm.well_known_symbol_to_string_tag(), js_string(global_object.heap(), "String Iterator"), Attribute::Configurable);
}
StringIteratorPrototype::~StringIteratorPrototype()
diff --git a/Libraries/LibJS/Runtime/StringPrototype.cpp b/Libraries/LibJS/Runtime/StringPrototype.cpp
index 400d99a0f8..46760d7118 100644
--- a/Libraries/LibJS/Runtime/StringPrototype.cpp
+++ b/Libraries/LibJS/Runtime/StringPrototype.cpp
@@ -66,29 +66,30 @@ StringPrototype::StringPrototype(GlobalObject& global_object)
void StringPrototype::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
StringObject::initialize(global_object);
u8 attr = Attribute::Writable | Attribute::Configurable;
- define_native_property("length", length_getter, nullptr, 0);
- define_native_function("charAt", char_at, 1, attr);
- define_native_function("charCodeAt", char_code_at, 1, attr);
- define_native_function("repeat", repeat, 1, attr);
- define_native_function("startsWith", starts_with, 1, attr);
- define_native_function("indexOf", index_of, 1, attr);
- define_native_function("toLowerCase", to_lowercase, 0, attr);
- define_native_function("toUpperCase", to_uppercase, 0, attr);
- define_native_function("toString", to_string, 0, attr);
- define_native_function("padStart", pad_start, 1, attr);
- define_native_function("padEnd", pad_end, 1, attr);
- define_native_function("trim", trim, 0, attr);
- define_native_function("trimStart", trim_start, 0, attr);
- define_native_function("trimEnd", trim_end, 0, attr);
- define_native_function("concat", concat, 1, attr);
- define_native_function("substring", substring, 2, attr);
- define_native_function("includes", includes, 1, attr);
- define_native_function("slice", slice, 2, attr);
- define_native_function("lastIndexOf", last_index_of, 1, attr);
- define_native_function(global_object.vm().well_known_symbol_iterator(), symbol_iterator, 0, attr);
+ define_native_property(vm.names.length, length_getter, nullptr, 0);
+ define_native_function(vm.names.charAt, char_at, 1, attr);
+ define_native_function(vm.names.charCodeAt, char_code_at, 1, attr);
+ define_native_function(vm.names.repeat, repeat, 1, attr);
+ define_native_function(vm.names.startsWith, starts_with, 1, attr);
+ define_native_function(vm.names.indexOf, index_of, 1, attr);
+ define_native_function(vm.names.toLowerCase, to_lowercase, 0, attr);
+ define_native_function(vm.names.toUpperCase, to_uppercase, 0, attr);
+ define_native_function(vm.names.toString, to_string, 0, attr);
+ define_native_function(vm.names.padStart, pad_start, 1, attr);
+ define_native_function(vm.names.padEnd, pad_end, 1, attr);
+ define_native_function(vm.names.trim, trim, 0, attr);
+ define_native_function(vm.names.trimStart, trim_start, 0, attr);
+ define_native_function(vm.names.trimEnd, trim_end, 0, attr);
+ define_native_function(vm.names.concat, concat, 1, attr);
+ define_native_function(vm.names.substring, substring, 2, attr);
+ define_native_function(vm.names.includes, includes, 1, attr);
+ define_native_function(vm.names.slice, slice, 2, attr);
+ define_native_function(vm.names.lastIndexOf, last_index_of, 1, attr);
+ define_native_function(vm.well_known_symbol_iterator(), symbol_iterator, 0, attr);
}
StringPrototype::~StringPrototype()
diff --git a/Libraries/LibJS/Runtime/SymbolConstructor.cpp b/Libraries/LibJS/Runtime/SymbolConstructor.cpp
index b5b8b4815f..0697ad98e6 100644
--- a/Libraries/LibJS/Runtime/SymbolConstructor.cpp
+++ b/Libraries/LibJS/Runtime/SymbolConstructor.cpp
@@ -32,21 +32,22 @@
namespace JS {
SymbolConstructor::SymbolConstructor(GlobalObject& global_object)
- : NativeFunction("Symbol", *global_object.function_prototype())
+ : NativeFunction(vm().names.Symbol, *global_object.function_prototype())
{
}
void SymbolConstructor::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
NativeFunction::initialize(global_object);
- define_property("prototype", global_object.symbol_prototype(), 0);
- define_property("length", Value(0), Attribute::Configurable);
+ define_property(vm.names.prototype, global_object.symbol_prototype(), 0);
+ define_property(vm.names.length, Value(0), Attribute::Configurable);
- define_native_function("for", for_, 1, Attribute::Writable | Attribute::Configurable);
- define_native_function("keyFor", key_for, 1, Attribute::Writable | Attribute::Configurable);
+ define_native_function(vm.names.for_, for_, 1, Attribute::Writable | Attribute::Configurable);
+ define_native_function(vm.names.keyFor, key_for, 1, Attribute::Writable | Attribute::Configurable);
#define __JS_ENUMERATE(SymbolName, snake_name) \
- define_property(#SymbolName, global_object.vm().well_known_symbol_##snake_name(), 0);
+ define_property(vm.names.SymbolName, vm.well_known_symbol_##snake_name(), 0);
JS_ENUMERATE_WELL_KNOWN_SYMBOLS
#undef __JS_ENUMERATE
}
diff --git a/Libraries/LibJS/Runtime/SymbolPrototype.cpp b/Libraries/LibJS/Runtime/SymbolPrototype.cpp
index f00a2626d7..b5e7869281 100644
--- a/Libraries/LibJS/Runtime/SymbolPrototype.cpp
+++ b/Libraries/LibJS/Runtime/SymbolPrototype.cpp
@@ -45,10 +45,11 @@ SymbolPrototype::SymbolPrototype(GlobalObject& global_object)
void SymbolPrototype::initialize(GlobalObject& global_object)
{
+ auto& vm = this->vm();
Object::initialize(global_object);
- define_native_property("description", description_getter, nullptr, Attribute::Configurable);
- define_native_function("toString", to_string, 0, Attribute::Writable | Attribute::Configurable);
- define_native_function("valueOf", value_of, 0, Attribute::Writable | Attribute::Configurable);
+ define_native_property(vm.names.description, description_getter, nullptr, Attribute::Configurable);
+ define_native_function(vm.names.toString, to_string, 0, Attribute::Writable | Attribute::Configurable);
+ define_native_function(vm.names.valueOf, value_of, 0, Attribute::Writable | Attribute::Configurable);
define_property(global_object.vm().well_known_symbol_to_string_tag(), js_string(global_object.heap(), "Symbol"), Attribute::Configurable);
}
diff --git a/Libraries/LibJS/Runtime/Uint8ClampedArray.cpp b/Libraries/LibJS/Runtime/Uint8ClampedArray.cpp
index 54194a2580..5683e7f646 100644
--- a/Libraries/LibJS/Runtime/Uint8ClampedArray.cpp
+++ b/Libraries/LibJS/Runtime/Uint8ClampedArray.cpp
@@ -40,7 +40,8 @@ Uint8ClampedArray::Uint8ClampedArray(u32 length, Object& prototype)
: Object(prototype)
, m_length(length)
{
- define_native_property("length", length_getter, nullptr);
+ auto& vm = this->vm();
+ define_native_property(vm.names.length, length_getter, nullptr);
m_data = new u8[m_length];
}
diff --git a/Libraries/LibJS/Runtime/VM.cpp b/Libraries/LibJS/Runtime/VM.cpp
index 24b13cb6cc..bc515d0034 100644
--- a/Libraries/LibJS/Runtime/VM.cpp
+++ b/Libraries/LibJS/Runtime/VM.cpp
@@ -207,7 +207,7 @@ Value VM::construct(Function& function, Function& new_target, Optional<MarkedVal
current_environment()->bind_this_value(global_object, new_object);
if (exception())
return {};
- auto prototype = new_target.get("prototype");
+ auto prototype = new_target.get(names.prototype);
if (exception())
return {};
if (prototype.is_object()) {
@@ -230,7 +230,7 @@ Value VM::construct(Function& function, Function& new_target, Optional<MarkedVal
// set the prototype on objects created by constructors that return an object (i.e. NativeFunction subclasses).
if (function.constructor_kind() == Function::ConstructorKind::Base && new_target.constructor_kind() == Function::ConstructorKind::Derived && result.is_object()) {
current_environment()->replace_this_binding(result);
- auto prototype = new_target.get("prototype");
+ auto prototype = new_target.get(names.prototype);
if (exception())
return {};
if (prototype.is_object()) {
diff --git a/Libraries/LibJS/Runtime/VM.h b/Libraries/LibJS/Runtime/VM.h
index 01b8db1288..3334276640 100644
--- a/Libraries/LibJS/Runtime/VM.h
+++ b/Libraries/LibJS/Runtime/VM.h
@@ -30,6 +30,7 @@
#include <AK/HashMap.h>
#include <AK/RefCounted.h>
#include <LibJS/Heap/Heap.h>
+#include <LibJS/Runtime/CommonPropertyNames.h>
#include <LibJS/Runtime/ErrorTypes.h>
#include <LibJS/Runtime/Exception.h>
#include <LibJS/Runtime/MarkedValueList.h>
@@ -223,6 +224,8 @@ public:
return call(function, this_value);
}
+ CommonPropertyNames names;
+
private:
VM();
diff --git a/Libraries/LibJS/Runtime/Value.cpp b/Libraries/LibJS/Runtime/Value.cpp
index 0ca094b4b3..7c05fe3468 100644
--- a/Libraries/LibJS/Runtime/Value.cpp
+++ b/Libraries/LibJS/Runtime/Value.cpp
@@ -738,7 +738,7 @@ Value ordinary_has_instance(GlobalObject& global_object, Value lhs, Value rhs)
return Value(false);
Object* lhs_object = &lhs.as_object();
- auto rhs_prototype = rhs_function.get("prototype");
+ auto rhs_prototype = rhs_function.get(vm.names.prototype);
if (vm.exception())
return {};
@@ -1013,8 +1013,9 @@ TriState abstract_relation(GlobalObject& global_object, bool left_first, Value l
size_t length_of_array_like(GlobalObject& global_object, Value value)
{
ASSERT(value.is_object());
- auto result = value.as_object().get("length");
- if (global_object.vm().exception())
+ auto& vm = global_object.vm();
+ auto result = value.as_object().get(vm.names.length);
+ if (vm.exception())
return 0;
return result.to_size_t(global_object);
}