diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp index 149d10ae6bb..bf3b1f10cf6 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp @@ -210,7 +210,6 @@ Value perform_eval(Value x, GlobalObject& caller_realm, CallerMode strict_caller Object* create_unmapped_arguments_object(GlobalObject& global_object, Vector const& arguments) { auto& vm = global_object.vm(); - // FIXME: This should use OrdinaryObjectCreate auto* object = Object::create(global_object, global_object.object_prototype()); if (vm.exception()) return nullptr; @@ -226,12 +225,8 @@ Object* create_unmapped_arguments_object(GlobalObject& global_object, Vectorindexed_properties().append(argument); - // FIXME: 8. Perform ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor { [[Get]]: %ThrowTypeError%, [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false }). - PropertyAttributes attributes; - attributes.set_has_configurable(); - attributes.set_has_enumerable(); - - object->define_property(vm.names.callee, js_undefined(), attributes); + // 8. Perform ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor { [[Get]]: %ThrowTypeError%, [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false }). + object->define_accessor(vm.names.callee, global_object.throw_type_error_function(), global_object.throw_type_error_function(), 0); if (vm.exception()) return nullptr; diff --git a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h index f40c44533da..6553e594449 100644 --- a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h +++ b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h @@ -76,6 +76,7 @@ namespace JS { P(byteOffset) \ P(call) \ P(callee) \ + P(caller) \ P(cause) \ P(cbrt) \ P(ceil) \ diff --git a/Userland/Libraries/LibJS/Runtime/ErrorTypes.h b/Userland/Libraries/LibJS/Runtime/ErrorTypes.h index 1dbc7c71c80..93434515bae 100644 --- a/Userland/Libraries/LibJS/Runtime/ErrorTypes.h +++ b/Userland/Libraries/LibJS/Runtime/ErrorTypes.h @@ -145,6 +145,8 @@ M(RegExpCompileError, "RegExp compile error: {}") \ M(RegExpObjectBadFlag, "Invalid RegExp flag '{}'") \ M(RegExpObjectRepeatedFlag, "Repeated RegExp flag '{}'") \ + M(RestrictedFunctionPropertiesAccess, "Restricted function properties like 'callee', 'caller' and 'arguments' may " \ + "not be accessed in strict mode") \ M(SpeciesConstructorDidNotCreate, "Species constructor did not create {}") \ M(SpeciesConstructorReturned, "Species constructor returned {}") \ M(StringMatchAllNonGlobalRegExp, "RegExp argument is non-global") \ diff --git a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp index d34f68361bb..62e178c146b 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -142,6 +142,19 @@ void GlobalObject::initialize_global_object() define_native_function(vm.names.eval, eval, 1, attr); m_eval_function = &get_without_side_effects(vm.names.eval).as_function(); + // 10.2.4.1 %ThrowTypeError% ( ), https://tc39.es/ecma262/#sec-%throwtypeerror% + m_throw_type_error_function = NativeFunction::create(global_object(), {}, [](VM& vm, GlobalObject& global_object) { + vm.throw_exception(global_object, ErrorType::RestrictedFunctionPropertiesAccess); + return Value(); + }); + m_throw_type_error_function->prevent_extensions(); + m_throw_type_error_function->define_property_without_transition(vm.names.length, Value(0), 0, false); + m_throw_type_error_function->define_property_without_transition(vm.names.name, js_string(vm, ""), 0, false); + + // 10.2.4 AddRestrictedFunctionProperties ( F, realm ), https://tc39.es/ecma262/#sec-addrestrictedfunctionproperties + m_function_prototype->define_accessor(vm.names.caller, throw_type_error_function(), throw_type_error_function(), Attribute::Configurable); + m_function_prototype->define_accessor(vm.names.arguments, throw_type_error_function(), throw_type_error_function(), Attribute::Configurable); + define_native_function(vm.names.encodeURI, encode_uri, 1, attr); define_native_function(vm.names.decodeURI, decode_uri, 1, attr); define_native_function(vm.names.encodeURIComponent, encode_uri_component, 1, attr); @@ -227,6 +240,7 @@ void GlobalObject::visit_edges(Visitor& visitor) #undef __JS_ENUMERATE visitor.visit(m_eval_function); + visitor.visit(m_throw_type_error_function); } JS_DEFINE_NATIVE_FUNCTION(GlobalObject::gc) diff --git a/Userland/Libraries/LibJS/Runtime/GlobalObject.h b/Userland/Libraries/LibJS/Runtime/GlobalObject.h index 6823676bce3..ec1c5afa4a2 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalObject.h +++ b/Userland/Libraries/LibJS/Runtime/GlobalObject.h @@ -38,6 +38,8 @@ public: FunctionObject* eval_function() const { return m_eval_function; } + FunctionObject* throw_type_error_function() const { return m_throw_type_error_function; } + #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \ ConstructorName* snake_name##_constructor() { return m_##snake_name##_constructor; } \ Object* snake_name##_prototype() { return m_##snake_name##_prototype; } @@ -99,6 +101,7 @@ private: #undef __JS_ENUMERATE FunctionObject* m_eval_function; + FunctionObject* m_throw_type_error_function; }; template