浏览代码

LibJS: Implement the GetMethod abstract operation

https://tc39.es/ecma262/#sec-getmethod

We have bunch of duplicated on-demand versions of this, let's do it
properly.
Linus Groh 4 年之前
父节点
当前提交
1b43a6ef2d

+ 1 - 0
Userland/Libraries/LibJS/Forward.h

@@ -139,6 +139,7 @@ class MarkedValueList;
 class NativeFunction;
 class NativeProperty;
 class PrimitiveString;
+class PropertyName;
 class Reference;
 class ScopeNode;
 class ScopeObject;

+ 20 - 0
Userland/Libraries/LibJS/Runtime/Value.cpp

@@ -1231,6 +1231,26 @@ TriState abstract_relation(GlobalObject& global_object, bool left_first, Value l
         return TriState::False;
 }
 
+Function* get_method(GlobalObject& global_object, Value value, const PropertyName& property_name)
+{
+    // 7.3.10 GetMethod, https://tc39.es/ecma262/#sec-getmethod
+
+    auto& vm = global_object.vm();
+    auto* object = value.to_object(global_object);
+    if (vm.exception())
+        return nullptr;
+    auto property_value = object->get(property_name);
+    if (vm.exception())
+        return nullptr;
+    if (property_value.is_empty() || property_value.is_nullish())
+        return nullptr;
+    if (!property_value.is_function()) {
+        vm.throw_exception<TypeError>(global_object, ErrorType::NotAFunction, property_value.to_string_without_side_effects());
+        return nullptr;
+    }
+    return &property_value.as_function();
+}
+
 size_t length_of_array_like(GlobalObject& global_object, const Object& object)
 {
     // 7.3.18 LengthOfArrayLike, https://tc39.es/ecma262/#sec-lengthofarraylike

+ 1 - 0
Userland/Libraries/LibJS/Runtime/Value.h

@@ -340,6 +340,7 @@ bool same_value(Value lhs, Value rhs);
 bool same_value_zero(Value lhs, Value rhs);
 bool same_value_non_numeric(Value lhs, Value rhs);
 TriState abstract_relation(GlobalObject&, bool left_first, Value lhs, Value rhs);
+Function* get_method(GlobalObject& global_object, Value, const PropertyName&);
 size_t length_of_array_like(GlobalObject&, const Object&);
 
 }