Selaa lähdekoodia

LibJS: Add and use the %ThrowTypeError% intrinsic

Idan Horowitz 4 vuotta sitten
vanhempi
commit
e2e695bc9f

+ 2 - 7
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<Value> 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, Vector<Val
     for (auto& argument : arguments)
         object->indexed_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;
 

+ 1 - 0
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)                                  \

+ 2 - 0
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")                                                                   \

+ 14 - 0
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<TypeError>(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)

+ 3 - 0
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<typename ConstructorType>