diff --git a/Libraries/LibJS/Runtime/ArrayConstructor.cpp b/Libraries/LibJS/Runtime/ArrayConstructor.cpp index 0c9d2ea12f..65da8387c6 100644 --- a/Libraries/LibJS/Runtime/ArrayConstructor.cpp +++ b/Libraries/LibJS/Runtime/ArrayConstructor.cpp @@ -37,8 +37,8 @@ namespace JS { ArrayConstructor::ArrayConstructor() : NativeFunction("Array", *interpreter().global_object().function_prototype()) { - put("prototype", interpreter().global_object().array_prototype()); - put("length", Value(1)); + put("prototype", interpreter().global_object().array_prototype(), 0); + put("length", Value(1), Attribute::Configurable); } ArrayConstructor::~ArrayConstructor() diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Libraries/LibJS/Runtime/ArrayPrototype.cpp index f208973621..b3ac9b7928 100644 --- a/Libraries/LibJS/Runtime/ArrayPrototype.cpp +++ b/Libraries/LibJS/Runtime/ArrayPrototype.cpp @@ -42,24 +42,26 @@ namespace JS { ArrayPrototype::ArrayPrototype() : Object(interpreter().global_object().object_prototype()) { - put_native_function("filter", filter, 1); - put_native_function("forEach", for_each, 1); - put_native_function("map", map, 1); - put_native_function("pop", pop, 0); - put_native_function("push", push, 1); - put_native_function("shift", shift, 0); - put_native_function("toString", to_string, 0); - put_native_function("unshift", unshift, 1); - put_native_function("join", join, 1); - put_native_function("concat", concat, 1); - put_native_function("slice", slice, 2); - put_native_function("indexOf", index_of, 1); - put_native_function("reverse", reverse, 0); - put_native_function("lastIndexOf", last_index_of, 1); - put_native_function("includes", includes, 1); - put_native_function("find", find, 1); - put_native_function("findIndex", find_index, 1); - put("length", Value(0)); + u8 attr = Attribute::Writable | Attribute::Configurable; + + put_native_function("filter", filter, 1, attr); + put_native_function("forEach", for_each, 1, attr); + put_native_function("map", map, 1, attr); + put_native_function("pop", pop, 0, attr); + put_native_function("push", push, 1, attr); + put_native_function("shift", shift, 0, attr); + put_native_function("toString", to_string, 0, attr); + put_native_function("unshift", unshift, 1, attr); + put_native_function("join", join, 1, attr); + put_native_function("concat", concat, 1, attr); + put_native_function("slice", slice, 2, attr); + put_native_function("indexOf", index_of, 1, attr); + put_native_function("reverse", reverse, 0, attr); + put_native_function("lastIndexOf", last_index_of, 1, attr); + put_native_function("includes", includes, 1, attr); + put_native_function("find", find, 1, attr); + put_native_function("findIndex", find_index, 1, attr); + put("length", Value(0), Attribute::Configurable); } ArrayPrototype::~ArrayPrototype() diff --git a/Libraries/LibJS/Runtime/BooleanConstructor.cpp b/Libraries/LibJS/Runtime/BooleanConstructor.cpp index b1522a698c..96a66a2f0b 100644 --- a/Libraries/LibJS/Runtime/BooleanConstructor.cpp +++ b/Libraries/LibJS/Runtime/BooleanConstructor.cpp @@ -36,8 +36,8 @@ namespace JS { BooleanConstructor::BooleanConstructor() : NativeFunction("Boolean", *interpreter().global_object().function_prototype()) { - put("prototype", Value(interpreter().global_object().boolean_prototype())); - put("length", Value(1)); + put("prototype", Value(interpreter().global_object().boolean_prototype()), 0); + put("length", Value(1), Attribute::Configurable); } BooleanConstructor::~BooleanConstructor() diff --git a/Libraries/LibJS/Runtime/BooleanPrototype.cpp b/Libraries/LibJS/Runtime/BooleanPrototype.cpp index 5bd458ae46..19cfba7440 100644 --- a/Libraries/LibJS/Runtime/BooleanPrototype.cpp +++ b/Libraries/LibJS/Runtime/BooleanPrototype.cpp @@ -35,8 +35,8 @@ namespace JS { BooleanPrototype::BooleanPrototype() : BooleanObject(false, *interpreter().global_object().object_prototype()) { - put_native_function("toString", to_string); - put_native_function("valueOf", value_of); + put_native_function("toString", to_string, 0, Attribute::Writable | Attribute::Configurable); + put_native_function("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 6ecc286cf6..4aa82f2c2b 100644 --- a/Libraries/LibJS/Runtime/BoundFunction.cpp +++ b/Libraries/LibJS/Runtime/BoundFunction.cpp @@ -36,7 +36,7 @@ BoundFunction::BoundFunction(Function& target_function, Value bound_this, Vector , m_constructor_prototype(constructor_prototype) , m_name(String::format("bound %s", target_function.name().characters())) { - put("length", Value(length)); + put("length", Value(length), Attribute::Configurable); } BoundFunction::~BoundFunction() diff --git a/Libraries/LibJS/Runtime/DateConstructor.cpp b/Libraries/LibJS/Runtime/DateConstructor.cpp index d2f09ff9f3..a9f573e6be 100644 --- a/Libraries/LibJS/Runtime/DateConstructor.cpp +++ b/Libraries/LibJS/Runtime/DateConstructor.cpp @@ -37,10 +37,10 @@ namespace JS { DateConstructor::DateConstructor() : NativeFunction("Date", *interpreter().global_object().function_prototype()) { - put("prototype", interpreter().global_object().date_prototype()); - put("length", Value(7)); + put("prototype", interpreter().global_object().date_prototype(), 0); + put("length", Value(7), Attribute::Configurable); - put_native_function("now", now); + put_native_function("now", now, 0, Attribute::Writable | Attribute::Configurable); } DateConstructor::~DateConstructor() diff --git a/Libraries/LibJS/Runtime/DatePrototype.cpp b/Libraries/LibJS/Runtime/DatePrototype.cpp index 899232ba78..dc115c5a19 100644 --- a/Libraries/LibJS/Runtime/DatePrototype.cpp +++ b/Libraries/LibJS/Runtime/DatePrototype.cpp @@ -51,18 +51,19 @@ static Date* this_date_from_interpreter(Interpreter& interpreter) DatePrototype::DatePrototype() : Object(interpreter().global_object().object_prototype()) { - put_native_function("getDate", get_date); - put_native_function("getDay", get_day); - put_native_function("getFullYear", get_full_year); - put_native_function("getHours", get_hours); - put_native_function("getMilliseconds", get_milliseconds); - put_native_function("getMinutes", get_minutes); - put_native_function("getMonth", get_month); - put_native_function("getSeconds", get_seconds); - put_native_function("getTime", get_time); - put_native_function("toDateString", to_date_string); - put_native_function("toTimeString", to_time_string); - put_native_function("toString", to_string); + u8 attr = Attribute::Writable | Attribute::Configurable; + put_native_function("getDate", get_date, 0, attr); + put_native_function("getDay", get_day, 0, attr); + put_native_function("getFullYear", get_full_year, 0, attr); + put_native_function("getHours", get_hours, 0, attr); + put_native_function("getMilliseconds", get_milliseconds, 0, attr); + put_native_function("getMinutes", get_minutes, 0, attr); + put_native_function("getMonth", get_month, 0, attr); + put_native_function("getSeconds", get_seconds, 0, attr); + put_native_function("getTime", get_time, 0, attr); + put_native_function("toDateString", to_date_string, 0, attr); + put_native_function("toTimeString", to_time_string, 0, attr); + put_native_function("toString", to_string, 0, attr); } DatePrototype::~DatePrototype() diff --git a/Libraries/LibJS/Runtime/ErrorConstructor.cpp b/Libraries/LibJS/Runtime/ErrorConstructor.cpp index 480a069cfb..8a5a3e9d44 100644 --- a/Libraries/LibJS/Runtime/ErrorConstructor.cpp +++ b/Libraries/LibJS/Runtime/ErrorConstructor.cpp @@ -34,8 +34,8 @@ namespace JS { ErrorConstructor::ErrorConstructor() : NativeFunction("Error", *interpreter().global_object().function_prototype()) { - put("prototype", interpreter().global_object().error_prototype()); - put("length", Value(1)); + put("prototype", interpreter().global_object().error_prototype(), 0); + put("length", Value(1), Attribute::Configurable); } ErrorConstructor::~ErrorConstructor() @@ -59,8 +59,8 @@ Value ErrorConstructor::construct(Interpreter& interpreter) ConstructorName::ConstructorName() \ : NativeFunction(*interpreter().global_object().function_prototype()) \ { \ - put("prototype", interpreter().global_object().snake_name##_prototype()); \ - put("length", Value(1)); \ + put("prototype", interpreter().global_object().snake_name##_prototype(), 0); \ + put("length", Value(1), Attribute::Configurable); \ } \ ConstructorName::~ConstructorName() {} \ Value ConstructorName::call(Interpreter& interpreter) \ diff --git a/Libraries/LibJS/Runtime/ErrorPrototype.cpp b/Libraries/LibJS/Runtime/ErrorPrototype.cpp index 22ea084ab6..10246270f9 100644 --- a/Libraries/LibJS/Runtime/ErrorPrototype.cpp +++ b/Libraries/LibJS/Runtime/ErrorPrototype.cpp @@ -38,9 +38,10 @@ namespace JS { ErrorPrototype::ErrorPrototype() : Object(interpreter().global_object().object_prototype()) { - put_native_property("name", name_getter, name_setter); - put_native_property("message", message_getter, nullptr); - put_native_function("toString", to_string); + u8 attr = Attribute::Writable | Attribute::Configurable; + put_native_property("name", name_getter, name_setter, attr); + put_native_property("message", message_getter, nullptr, attr); + put_native_function("toString", to_string, 0, attr); } ErrorPrototype::~ErrorPrototype() diff --git a/Libraries/LibJS/Runtime/FunctionConstructor.cpp b/Libraries/LibJS/Runtime/FunctionConstructor.cpp index 4dbfcbaed4..0ed6fd1185 100644 --- a/Libraries/LibJS/Runtime/FunctionConstructor.cpp +++ b/Libraries/LibJS/Runtime/FunctionConstructor.cpp @@ -38,8 +38,8 @@ namespace JS { FunctionConstructor::FunctionConstructor() : NativeFunction("Function", *interpreter().global_object().function_prototype()) { - put("prototype", interpreter().global_object().function_prototype()); - put("length", Value(1)); + put("prototype", interpreter().global_object().function_prototype(), 0); + put("length", Value(1), Attribute::Configurable); } FunctionConstructor::~FunctionConstructor() diff --git a/Libraries/LibJS/Runtime/FunctionPrototype.cpp b/Libraries/LibJS/Runtime/FunctionPrototype.cpp index 644bffa481..b7d6b114b7 100644 --- a/Libraries/LibJS/Runtime/FunctionPrototype.cpp +++ b/Libraries/LibJS/Runtime/FunctionPrototype.cpp @@ -45,11 +45,12 @@ FunctionPrototype::FunctionPrototype() void FunctionPrototype::initialize() { - put_native_function("apply", apply, 2); - put_native_function("bind", bind, 1); - put_native_function("call", call, 1); - put_native_function("toString", to_string); - put("length", Value(0)); + u8 attr = Attribute::Writable | Attribute::Configurable; + put_native_function("apply", apply, 2, attr); + put_native_function("bind", bind, 1, attr); + put_native_function("call", call, 1, attr); + put_native_function("toString", to_string, 0, attr); + put("length", Value(0), Attribute::Configurable); } FunctionPrototype::~FunctionPrototype() diff --git a/Libraries/LibJS/Runtime/GlobalObject.cpp b/Libraries/LibJS/Runtime/GlobalObject.cpp index 6e289b7f56..9ec245f475 100644 --- a/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -61,7 +61,7 @@ void GlobalObject::add_constructor(const FlyString& property_name, ConstructorTy { constructor = heap().allocate(); prototype.put("constructor", constructor); - put(property_name, constructor); + put(property_name, constructor, Attribute::Writable | Attribute::Configurable); } GlobalObject::GlobalObject() @@ -85,18 +85,18 @@ void GlobalObject::initialize() JS_ENUMERATE_BUILTIN_TYPES #undef __JS_ENUMERATE - put_native_function("gc", gc); - put_native_function("isNaN", is_nan, 1); - put_native_function("isFinite", is_finite, 1); + u8 attr = Attribute::Writable | Attribute::Configurable; + put_native_function("gc", gc, 0, attr); + put_native_function("isNaN", is_nan, 1, attr); + put_native_function("isFinite", is_finite, 1, attr); - // FIXME: These are read-only in ES5 - put("NaN", js_nan()); - put("Infinity", js_infinity()); - put("undefined", js_undefined()); + put("NaN", js_nan(), 0); + put("Infinity", js_infinity(), 0); + put("undefined", js_undefined(), 0); - put("globalThis", this); - put("console", heap().allocate()); - put("Math", heap().allocate()); + put("globalThis", this, attr); + put("console", heap().allocate(), attr); + put("Math", heap().allocate(), attr); add_constructor("Array", m_array_constructor, *m_array_prototype); add_constructor("Boolean", m_boolean_constructor, *m_boolean_prototype); diff --git a/Libraries/LibJS/Runtime/MathObject.cpp b/Libraries/LibJS/Runtime/MathObject.cpp index 21287bd17d..b538591a44 100644 --- a/Libraries/LibJS/Runtime/MathObject.cpp +++ b/Libraries/LibJS/Runtime/MathObject.cpp @@ -36,28 +36,29 @@ namespace JS { MathObject::MathObject() : Object(interpreter().global_object().object_prototype()) { - put_native_function("abs", abs, 1); - put_native_function("random", random); - put_native_function("sqrt", sqrt, 1); - put_native_function("floor", floor, 1); - put_native_function("ceil", ceil, 1); - put_native_function("round", round, 1); - put_native_function("max", max, 2); - put_native_function("min", min, 2); - put_native_function("trunc", trunc, 1); - put_native_function("sin", sin, 1); - put_native_function("cos", cos, 1); - put_native_function("tan", tan, 1); - put_native_function("pow", pow, 2); + u8 attr = Attribute::Writable | Attribute::Configurable; + put_native_function("abs", abs, 1, attr); + put_native_function("random", random, 0, attr); + put_native_function("sqrt", sqrt, 1, attr); + put_native_function("floor", floor, 1, attr); + put_native_function("ceil", ceil, 1, attr); + put_native_function("round", round, 1, attr); + put_native_function("max", max, 2, attr); + put_native_function("min", min, 2, attr); + put_native_function("trunc", trunc, 1, attr); + put_native_function("sin", sin, 1, attr); + put_native_function("cos", cos, 1, attr); + put_native_function("tan", tan, 1, attr); + put_native_function("pow", pow, 2, attr); - put("E", Value(M_E)); - put("LN2", Value(M_LN2)); - put("LN10", Value(M_LN10)); - put("LOG2E", Value(log2(M_E))); - put("LOG10E", Value(log10(M_E))); - put("PI", Value(M_PI)); - put("SQRT1_2", Value(::sqrt(1.0 / 2.0))); - put("SQRT2", Value(::sqrt(2))); + put("E", Value(M_E), 0); + put("LN2", Value(M_LN2), 0); + put("LN10", Value(M_LN10), 0); + put("LOG2E", Value(log2(M_E)), 0); + put("LOG10E", Value(log10(M_E)), 0); + put("PI", Value(M_PI), 0); + put("SQRT1_2", Value(::sqrt(1.0 / 2.0)), 0); + put("SQRT2", Value(::sqrt(2)), 0); } MathObject::~MathObject() diff --git a/Libraries/LibJS/Runtime/NumberConstructor.cpp b/Libraries/LibJS/Runtime/NumberConstructor.cpp index fc24b85838..4996de3f72 100644 --- a/Libraries/LibJS/Runtime/NumberConstructor.cpp +++ b/Libraries/LibJS/Runtime/NumberConstructor.cpp @@ -40,19 +40,20 @@ namespace JS { NumberConstructor::NumberConstructor() : NativeFunction("Number", *interpreter().global_object().function_prototype()) { - put_native_function("isFinite", is_finite, 1); - put_native_function("isInteger", is_integer, 1); - put_native_function("isNaN", is_nan, 1); - put_native_function("isSafeInteger", is_safe_integer, 1); + u8 attr = Attribute::Writable | Attribute::Configurable; + put_native_function("isFinite", is_finite, 1, attr); + put_native_function("isInteger", is_integer, 1, attr); + put_native_function("isNaN", is_nan, 1, attr); + put_native_function("isSafeInteger", is_safe_integer, 1, attr); - put("prototype", interpreter().global_object().number_prototype()); - put("length", Value(1)); - put("EPSILON", Value(EPSILON)); - put("MAX_SAFE_INTEGER", Value(MAX_SAFE_INTEGER)); - put("MIN_SAFE_INTEGER", Value(MIN_SAFE_INTEGER)); - put("NEGATIVE_INFINITY", js_negative_infinity()); - put("POSITIVE_INFINITY", js_infinity()); - put("NaN", js_nan()); + put("prototype", interpreter().global_object().number_prototype(), 0); + put("length", Value(1), Attribute::Configurable); + put("EPSILON", Value(EPSILON), 0); + put("MAX_SAFE_INTEGER", Value(MAX_SAFE_INTEGER), 0); + put("MIN_SAFE_INTEGER", Value(MIN_SAFE_INTEGER), 0); + put("NEGATIVE_INFINITY", js_negative_infinity(), 0); + put("POSITIVE_INFINITY", js_infinity(), 0); + put("NaN", js_nan(), 0); } NumberConstructor::~NumberConstructor() diff --git a/Libraries/LibJS/Runtime/Object.cpp b/Libraries/LibJS/Runtime/Object.cpp index e5a358eb3d..1be11f70f2 100644 --- a/Libraries/LibJS/Runtime/Object.cpp +++ b/Libraries/LibJS/Runtime/Object.cpp @@ -116,7 +116,9 @@ void Object::set_shape(Shape& new_shape) void Object::put_own_property(Object& this_object, const FlyString& property_name, u8 attributes, Value value, PutOwnPropertyMode mode) { auto metadata = shape().lookup(property_name); - if (!metadata.has_value()) { + bool new_property = !metadata.has_value(); + + if (new_property) { if (m_shape->is_unique()) { m_shape->add_property_to_unique_shape(property_name, attributes); m_storage.resize(m_shape->property_count()); @@ -127,7 +129,7 @@ void Object::put_own_property(Object& this_object, const FlyString& property_nam ASSERT(metadata.has_value()); } - if (mode == PutOwnPropertyMode::DefineProperty && !(metadata.value().attributes & Attribute::Configurable) && attributes != metadata.value().attributes) { + if (!new_property && mode == PutOwnPropertyMode::DefineProperty && !(metadata.value().attributes & Attribute::Configurable) && attributes != metadata.value().attributes) { dbg() << "Disallow reconfig of non-configurable property"; interpreter().throw_exception(String::format("Cannot redefine property '%s'", property_name.characters())); return; @@ -144,7 +146,7 @@ void Object::put_own_property(Object& this_object, const FlyString& property_nam dbg() << "Reconfigured property " << property_name << ", new shape says offset is " << metadata.value().offset << " and my storage capacity is " << m_storage.size(); } - if (mode == PutOwnPropertyMode::Put && !(metadata.value().attributes & Attribute::Writable)) { + if (!new_property && mode == PutOwnPropertyMode::Put && !(metadata.value().attributes & Attribute::Writable)) { dbg() << "Disallow write to non-writable property"; return; } @@ -240,24 +242,25 @@ Value Object::get(PropertyName property_name) const return get(property_name.as_string()); } -void Object::put_by_index(i32 property_index, Value value) +void Object::put_by_index(i32 property_index, Value value, u8 attributes) { ASSERT(!value.is_empty()); if (property_index < 0) - return put(String::number(property_index), value); + return put(String::number(property_index), value, attributes); // FIXME: Implement some kind of sparse storage for arrays with huge indices. + // Also: Take attributes into account here if (static_cast(property_index) >= m_elements.size()) m_elements.resize(property_index + 1); m_elements[property_index] = value; } -void Object::put(const FlyString& property_name, Value value) +void Object::put(const FlyString& property_name, Value value, u8 attributes) { ASSERT(!value.is_empty()); bool ok; i32 property_index = property_name.to_int(ok); if (ok && property_index >= 0) - return put_by_index(property_index, value); + return put_by_index(property_index, value, attributes); // If there's a setter in the prototype chain, we go to the setter. // Otherwise, it goes in the own property storage. @@ -278,26 +281,26 @@ void Object::put(const FlyString& property_name, Value value) } object = object->prototype(); } - put_own_property(*this, property_name, Attribute::Configurable | Attribute::Enumerable | Attribute::Writable, value, PutOwnPropertyMode::Put); + put_own_property(*this, property_name, attributes, value, PutOwnPropertyMode::Put); } -void Object::put(PropertyName property_name, Value value) +void Object::put(PropertyName property_name, Value value, u8 attributes) { if (property_name.is_number()) - return put_by_index(property_name.as_number(), value); - return put(property_name.as_string(), value); + return put_by_index(property_name.as_number(), value, attributes); + return put(property_name.as_string(), value, attributes); } -void Object::put_native_function(const FlyString& property_name, AK::Function native_function, i32 length) +void Object::put_native_function(const FlyString& property_name, AK::Function native_function, i32 length, u8 attributes) { auto* function = NativeFunction::create(interpreter(), interpreter().global_object(), property_name, move(native_function)); - function->put("length", Value(length)); - put(property_name, function); + function->put("length", Value(length), Attribute::Configurable); + put(property_name, function, attributes); } -void Object::put_native_property(const FlyString& property_name, AK::Function getter, AK::Function setter) +void Object::put_native_property(const FlyString& property_name, AK::Function getter, AK::Function setter, u8 attributes) { - put(property_name, heap().allocate(move(getter), move(setter))); + put(property_name, heap().allocate(move(getter), move(setter)), attributes); } void Object::visit_children(Cell::Visitor& visitor) diff --git a/Libraries/LibJS/Runtime/Object.h b/Libraries/LibJS/Runtime/Object.h index 5c945ea888..fa812c102e 100644 --- a/Libraries/LibJS/Runtime/Object.h +++ b/Libraries/LibJS/Runtime/Object.h @@ -32,10 +32,13 @@ #include #include #include +#include #include namespace JS { +const u8 default_attributes = Attribute::Configurable | Attribute::Writable | Attribute::Enumerable; + class Object : public Cell { public: static Object* create_empty(Interpreter&, GlobalObject&); @@ -52,9 +55,9 @@ public: Value get(const FlyString& property_name) const; Value get(PropertyName) const; - virtual void put_by_index(i32 property_index, Value); - void put(const FlyString& property_name, Value); - void put(PropertyName, Value); + virtual void put_by_index(i32 property_index, Value, u8 attributes = default_attributes); + void put(const FlyString& property_name, Value, u8 attributes = default_attributes); + void put(PropertyName, Value, u8 attributes = default_attributes); Value get_own_property(const Object& this_object, const FlyString& property_name) const; @@ -65,8 +68,8 @@ public: void put_own_property(Object& this_object, const FlyString& property_name, u8 attributes, Value, PutOwnPropertyMode); - void put_native_function(const FlyString& property_name, AK::Function, i32 length = 0); - void put_native_property(const FlyString& property_name, AK::Function getter, AK::Function setter); + void put_native_function(const FlyString& property_name, AK::Function, i32 length = 0, u8 attribute = default_attributes); + void put_native_property(const FlyString& property_name, AK::Function getter, AK::Function setter, u8 attribute = default_attributes); virtual bool is_array() const { return false; } virtual bool is_boolean() const { return false; } diff --git a/Libraries/LibJS/Runtime/ObjectConstructor.cpp b/Libraries/LibJS/Runtime/ObjectConstructor.cpp index 1fcbe4e8e2..e7738ecfeb 100644 --- a/Libraries/LibJS/Runtime/ObjectConstructor.cpp +++ b/Libraries/LibJS/Runtime/ObjectConstructor.cpp @@ -38,14 +38,15 @@ namespace JS { ObjectConstructor::ObjectConstructor() : NativeFunction("Object", *interpreter().global_object().function_prototype()) { - put("prototype", interpreter().global_object().object_prototype()); + put("prototype", interpreter().global_object().object_prototype(), 0); - put_native_function("defineProperty", define_property, 3); - put_native_function("is", is, 2); - put_native_function("getOwnPropertyDescriptor", get_own_property_descriptor, 2); - put_native_function("getOwnPropertyNames", get_own_property_names, 1); - put_native_function("getPrototypeOf", get_prototype_of, 1); - put_native_function("setPrototypeOf", set_prototype_of, 2); + u8 attr = Attribute::Writable | Attribute::Configurable; + put_native_function("defineProperty", define_property, 3, attr); + put_native_function("is", is, 2, attr); + put_native_function("getOwnPropertyDescriptor", get_own_property_descriptor, 2, attr); + put_native_function("getOwnPropertyNames", get_own_property_names, 1, attr); + put_native_function("getPrototypeOf", get_prototype_of, 1, attr); + put_native_function("setPrototypeOf", set_prototype_of, 2, attr); } ObjectConstructor::~ObjectConstructor() diff --git a/Libraries/LibJS/Runtime/ObjectPrototype.cpp b/Libraries/LibJS/Runtime/ObjectPrototype.cpp index 56f064be37..53a3c4f518 100644 --- a/Libraries/LibJS/Runtime/ObjectPrototype.cpp +++ b/Libraries/LibJS/Runtime/ObjectPrototype.cpp @@ -42,9 +42,10 @@ void ObjectPrototype::initialize() { // This must be called after the constructor has returned, so that the below code // can find the ObjectPrototype through normal paths. - put_native_function("hasOwnProperty", has_own_property, 1); - put_native_function("toString", to_string); - put_native_function("valueOf", value_of); + u8 attr = Attribute::Writable | Attribute::Configurable; + put_native_function("hasOwnProperty", has_own_property, 1, attr); + put_native_function("toString", to_string, 0, attr); + put_native_function("valueOf", value_of, 0, attr); } ObjectPrototype::~ObjectPrototype() diff --git a/Libraries/LibJS/Runtime/ScriptFunction.cpp b/Libraries/LibJS/Runtime/ScriptFunction.cpp index 3086951a3a..38a1096c17 100644 --- a/Libraries/LibJS/Runtime/ScriptFunction.cpp +++ b/Libraries/LibJS/Runtime/ScriptFunction.cpp @@ -46,8 +46,8 @@ ScriptFunction::ScriptFunction(const FlyString& name, const Statement& body, Vec , m_parameters(move(parameters)) , m_parent_environment(parent_environment) { - put("prototype", Object::create_empty(interpreter(), interpreter().global_object())); - put_native_property("length", length_getter, length_setter); + put("prototype", Object::create_empty(interpreter(), interpreter().global_object()), 0); + put_native_property("length", length_getter, length_setter, Attribute::Configurable); } ScriptFunction::~ScriptFunction() diff --git a/Libraries/LibJS/Runtime/StringConstructor.cpp b/Libraries/LibJS/Runtime/StringConstructor.cpp index 0858ceef2d..0be1df0b24 100644 --- a/Libraries/LibJS/Runtime/StringConstructor.cpp +++ b/Libraries/LibJS/Runtime/StringConstructor.cpp @@ -36,8 +36,8 @@ namespace JS { StringConstructor::StringConstructor() : NativeFunction("String", *interpreter().global_object().function_prototype()) { - put("prototype", interpreter().global_object().string_prototype()); - put("length", Value(1)); + put("prototype", interpreter().global_object().string_prototype(), 0); + put("length", Value(1), Attribute::Configurable); } StringConstructor::~StringConstructor() diff --git a/Libraries/LibJS/Runtime/StringPrototype.cpp b/Libraries/LibJS/Runtime/StringPrototype.cpp index a798cda9dc..b62edcbe4a 100644 --- a/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -41,23 +41,25 @@ namespace JS { StringPrototype::StringPrototype() : StringObject(*js_string(interpreter(), String::empty()), *interpreter().global_object().object_prototype()) { - put_native_property("length", length_getter, nullptr); - put_native_function("charAt", char_at, 1); - put_native_function("repeat", repeat, 1); - put_native_function("startsWith", starts_with, 1); - put_native_function("indexOf", index_of, 1); - put_native_function("toLowerCase", to_lowercase, 0); - put_native_function("toUpperCase", to_uppercase, 0); - put_native_function("toString", to_string, 0); - put_native_function("padStart", pad_start, 1); - put_native_function("padEnd", pad_end, 1); + u8 attr = Attribute::Writable | Attribute::Configurable; - put_native_function("trim", trim, 0); - put_native_function("trimStart", trim_start, 0); - put_native_function("trimEnd", trim_end, 0); - put_native_function("concat", concat, 1); - put_native_function("substring", substring, 2); - put_native_function("includes", includes, 1); + put_native_property("length", length_getter, nullptr, 0); + put_native_function("charAt", char_at, 1, attr); + put_native_function("repeat", repeat, 1, attr); + put_native_function("startsWith", starts_with, 1, attr); + put_native_function("indexOf", index_of, 1, attr); + put_native_function("toLowerCase", to_lowercase, 0, attr); + put_native_function("toUpperCase", to_uppercase, 0, attr); + put_native_function("toString", to_string, 0, attr); + put_native_function("padStart", pad_start, 1, attr); + put_native_function("padEnd", pad_end, 1, attr); + + put_native_function("trim", trim, 0, attr); + put_native_function("trimStart", trim_start, 0, attr); + put_native_function("trimEnd", trim_end, 0, attr); + put_native_function("concat", concat, 1, attr); + put_native_function("substring", substring, 2, attr); + put_native_function("includes", includes, 1, attr); } StringPrototype::~StringPrototype() diff --git a/Libraries/LibJS/Runtime/Uint8ClampedArray.cpp b/Libraries/LibJS/Runtime/Uint8ClampedArray.cpp index b04b236be2..57f4baa598 100644 --- a/Libraries/LibJS/Runtime/Uint8ClampedArray.cpp +++ b/Libraries/LibJS/Runtime/Uint8ClampedArray.cpp @@ -65,8 +65,9 @@ Value Uint8ClampedArray::length_getter(Interpreter& interpreter) return Value(static_cast(this_object)->length()); } -void Uint8ClampedArray::put_by_index(i32 property_index, Value value) +void Uint8ClampedArray::put_by_index(i32 property_index, Value value, u8) { + // FIXME: Use attributes ASSERT(property_index >= 0); ASSERT(property_index < m_length); m_data[property_index] = clamp(value.to_i32(), 0, 255); diff --git a/Libraries/LibJS/Runtime/Uint8ClampedArray.h b/Libraries/LibJS/Runtime/Uint8ClampedArray.h index 411d0018ba..0e66f897b1 100644 --- a/Libraries/LibJS/Runtime/Uint8ClampedArray.h +++ b/Libraries/LibJS/Runtime/Uint8ClampedArray.h @@ -39,7 +39,7 @@ public: i32 length() const { return m_length; } - virtual void put_by_index(i32 property_index, Value value) override; + virtual void put_by_index(i32 property_index, Value value, u8 attribute = default_attributes) override; virtual Value get_by_index(i32 property_index) const override; u8* data() { return m_data; } diff --git a/Libraries/LibWeb/Bindings/WindowObject.cpp b/Libraries/LibWeb/Bindings/WindowObject.cpp index 66867d4ed9..0e00bb6861 100644 --- a/Libraries/LibWeb/Bindings/WindowObject.cpp +++ b/Libraries/LibWeb/Bindings/WindowObject.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -49,8 +50,8 @@ void WindowObject::initialize() { GlobalObject::initialize(); - put("window", this); - put_native_property("document", document_getter, document_setter); + put("window", this, JS::Attribute::Enumerable); + put_native_property("document", document_getter, document_setter, JS::Attribute::Enumerable); put_native_function("alert", alert); put_native_function("confirm", confirm); put_native_function("setInterval", set_interval, 1); @@ -58,12 +59,12 @@ void WindowObject::initialize() put_native_function("requestAnimationFrame", request_animation_frame, 1); put_native_function("cancelAnimationFrame", cancel_animation_frame, 1); - put("navigator", heap().allocate()); + put("navigator", heap().allocate(), JS::Attribute::Enumerable | JS::Attribute::Configurable); m_xhr_prototype = heap().allocate(); m_xhr_constructor = heap().allocate(); - m_xhr_constructor->put("prototype", m_xhr_prototype); - put("XMLHttpRequest", m_xhr_constructor); + m_xhr_constructor->put("prototype", m_xhr_prototype, 0); + put("XMLHttpRequest", m_xhr_constructor, JS::Attribute::Writable | JS::Attribute::Configurable); } WindowObject::~WindowObject() diff --git a/Libraries/LibWeb/Bindings/XMLHttpRequestConstructor.cpp b/Libraries/LibWeb/Bindings/XMLHttpRequestConstructor.cpp index 7fea4c1cc1..2a2acb829c 100644 --- a/Libraries/LibWeb/Bindings/XMLHttpRequestConstructor.cpp +++ b/Libraries/LibWeb/Bindings/XMLHttpRequestConstructor.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -38,13 +39,13 @@ namespace Bindings { XMLHttpRequestConstructor::XMLHttpRequestConstructor() : NativeFunction(*interpreter().global_object().function_prototype()) { - put("length", JS::Value(1)); + put("length", JS::Value(1), JS::Attribute::Configurable); - put("UNSENT", JS::Value((i32)XMLHttpRequest::ReadyState::Unsent)); - put("OPENED", JS::Value((i32)XMLHttpRequest::ReadyState::Opened)); - put("HEADERS_RECEIVED", JS::Value((i32)XMLHttpRequest::ReadyState::HeadersReceived)); - put("LOADING", JS::Value((i32)XMLHttpRequest::ReadyState::Loading)); - put("DONE", JS::Value((i32)XMLHttpRequest::ReadyState::Done)); + put("UNSENT", JS::Value((i32)XMLHttpRequest::ReadyState::Unsent), JS::Attribute::Enumerable); + put("OPENED", JS::Value((i32)XMLHttpRequest::ReadyState::Opened), JS::Attribute::Enumerable); + put("HEADERS_RECEIVED", JS::Value((i32)XMLHttpRequest::ReadyState::HeadersReceived), JS::Attribute::Enumerable); + put("LOADING", JS::Value((i32)XMLHttpRequest::ReadyState::Loading), JS::Attribute::Enumerable); + put("DONE", JS::Value((i32)XMLHttpRequest::ReadyState::Done), JS::Attribute::Enumerable); } XMLHttpRequestConstructor::~XMLHttpRequestConstructor() diff --git a/Libraries/LibWeb/Bindings/XMLHttpRequestPrototype.cpp b/Libraries/LibWeb/Bindings/XMLHttpRequestPrototype.cpp index d749663c20..a5d95c302e 100644 --- a/Libraries/LibWeb/Bindings/XMLHttpRequestPrototype.cpp +++ b/Libraries/LibWeb/Bindings/XMLHttpRequestPrototype.cpp @@ -40,14 +40,14 @@ XMLHttpRequestPrototype::XMLHttpRequestPrototype() { put_native_function("open", open, 2); put_native_function("send", send, 0); - put_native_property("readyState", ready_state_getter, nullptr); - put_native_property("responseText", response_text_getter, nullptr); + put_native_property("readyState", ready_state_getter, nullptr, JS::Attribute::Enumerable | JS::Attribute::Configurable); + put_native_property("responseText", response_text_getter, nullptr, JS::Attribute::Enumerable | JS::Attribute::Configurable); - put("UNSENT", JS::Value((i32)XMLHttpRequest::ReadyState::Unsent)); - put("OPENED", JS::Value((i32)XMLHttpRequest::ReadyState::Opened)); - put("HEADERS_RECEIVED", JS::Value((i32)XMLHttpRequest::ReadyState::HeadersReceived)); - put("LOADING", JS::Value((i32)XMLHttpRequest::ReadyState::Loading)); - put("DONE", JS::Value((i32)XMLHttpRequest::ReadyState::Done)); + put("UNSENT", JS::Value((i32)XMLHttpRequest::ReadyState::Unsent), JS::Attribute::Enumerable); + put("OPENED", JS::Value((i32)XMLHttpRequest::ReadyState::Opened), JS::Attribute::Enumerable); + put("HEADERS_RECEIVED", JS::Value((i32)XMLHttpRequest::ReadyState::HeadersReceived), JS::Attribute::Enumerable); + put("LOADING", JS::Value((i32)XMLHttpRequest::ReadyState::Loading), JS::Attribute::Enumerable); + put("DONE", JS::Value((i32)XMLHttpRequest::ReadyState::Done), JS::Attribute::Enumerable); } XMLHttpRequestPrototype::~XMLHttpRequestPrototype()