diff options
45 files changed, 656 insertions, 397 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); } diff --git a/Userland/test-js.cpp b/Userland/test-js.cpp index 4bf7141e7d..7a95b61c8f 100644 --- a/Userland/test-js.cpp +++ b/Userland/test-js.cpp @@ -154,8 +154,10 @@ TestRunnerGlobalObject::~TestRunnerGlobalObject() void TestRunnerGlobalObject::initialize() { JS::GlobalObject::initialize(); - define_property("global", this, JS::Attribute::Enumerable); - define_native_function("isStrictMode", is_strict_mode); + static FlyString global_property_name { "global" }; + static FlyString is_strict_mode_property_name { "isStrictMode" }; + define_property(global_property_name, this, JS::Attribute::Enumerable); + define_native_function(is_strict_mode_property_name, is_strict_mode); } JS_DEFINE_NATIVE_FUNCTION(TestRunnerGlobalObject::is_strict_mode) |