Преглед изворни кода

LibJS: Use a custom property_name_to_value method instead of to_value

davidot пре 4 година
родитељ
комит
ce59e49e27

+ 19 - 6
Userland/Libraries/LibJS/Runtime/ProxyObject.cpp

@@ -31,6 +31,19 @@ ProxyObject::~ProxyObject()
 {
 }
 
+static Value property_name_to_value(VM& vm, PropertyName const& name)
+{
+    VERIFY(name.is_valid());
+    if (name.is_symbol())
+        return name.as_symbol();
+
+    if (name.is_string())
+        return js_string(vm, name.as_string());
+
+    VERIFY(name.is_number());
+    return js_string(vm, String::number(name.as_number()));
+}
+
 // 10.5.1 [[GetPrototypeOf]] ( ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof
 Object* ProxyObject::internal_get_prototype_of() const
 {
@@ -287,7 +300,7 @@ Optional<PropertyDescriptor> ProxyObject::internal_get_own_property(const Proper
     }
 
     // 8. Let trapResultObj be ? Call(trap, handler, « target, P »).
-    auto trap_result = vm.call(*trap, &m_handler, &m_target, property_name.to_value(vm));
+    auto trap_result = vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name));
     if (vm.exception())
         return {};
 
@@ -408,7 +421,7 @@ bool ProxyObject::internal_define_own_property(PropertyName const& property_name
     auto descriptor_object = from_property_descriptor(global_object, property_descriptor);
 
     // 9. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, descObj »)).
-    auto trap_result = vm.call(*trap, &m_handler, &m_target, property_name.to_value(vm), descriptor_object);
+    auto trap_result = vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name), descriptor_object);
     if (vm.exception())
         return {};
 
@@ -506,7 +519,7 @@ bool ProxyObject::internal_has_property(PropertyName const& property_name) const
     }
 
     // 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P »)).
-    auto trap_result = vm.call(*trap, &m_handler, &m_target, property_name.to_value(vm));
+    auto trap_result = vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name));
     if (vm.exception())
         return {};
 
@@ -576,7 +589,7 @@ Value ProxyObject::internal_get(PropertyName const& property_name, Value receive
     }
 
     // 8. Let trapResult be ? Call(trap, handler, « target, P, Receiver »).
-    auto trap_result = vm.call(*trap, &m_handler, &m_target, property_name.to_value(vm), receiver);
+    auto trap_result = vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name), receiver);
     if (vm.exception())
         return {};
 
@@ -644,7 +657,7 @@ bool ProxyObject::internal_set(PropertyName const& property_name, Value value, V
     }
 
     // 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, V, Receiver »)).
-    auto trap_result = vm.call(*trap, &m_handler, &m_target, property_name.to_value(vm), value, receiver);
+    auto trap_result = vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name), value, receiver);
     if (vm.exception())
         return {};
 
@@ -713,7 +726,7 @@ bool ProxyObject::internal_delete(PropertyName const& property_name)
     }
 
     // 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P »)).
-    auto trap_result = vm.call(*trap, &m_handler, &m_target, property_name.to_value(vm));
+    auto trap_result = vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name));
     if (vm.exception())
         return {};
 

+ 19 - 0
Userland/Libraries/LibJS/Tests/builtins/Proxy/Proxy.handler-defineProperty.js

@@ -27,6 +27,25 @@ describe("[[DefineProperty]] trap normal behavior", () => {
         Object.defineProperty(p, "foo", { configurable: true, writable: true, value: 10 });
     });
 
+    test("correct arguments passed to trap even for number", () => {
+        let o = {};
+        p = new Proxy(o, {
+            defineProperty(target, name, descriptor) {
+                expect(target).toBe(o);
+                expect(name).toBe("1");
+                expect(descriptor.configurable).toBeTrue();
+                expect(descriptor.enumerable).toBeUndefined();
+                expect(descriptor.writable).toBeTrue();
+                expect(descriptor.value).toBe(10);
+                expect(descriptor.get).toBeUndefined();
+                expect(descriptor.set).toBeUndefined();
+                return true;
+            },
+        });
+
+        Object.defineProperty(p, 1, { configurable: true, writable: true, value: 10 });
+    });
+
     test("optionally ignoring the define call", () => {
         let o = {};
         let p = new Proxy(o, {

+ 13 - 0
Userland/Libraries/LibJS/Tests/builtins/Proxy/Proxy.handler-deleteProperty.js

@@ -18,6 +18,19 @@ describe("[[Delete]] trap normal behavior", () => {
         delete p.foo;
     });
 
+    test("correct arguments passed to trap even for number", () => {
+        let o = {};
+        let p = new Proxy(o, {
+            deleteProperty(target, property) {
+                expect(target).toBe(o);
+                expect(property).toBe("1");
+                return true;
+            },
+        });
+
+        delete p[1];
+    });
+
     test("conditional deletion", () => {
         o = { foo: 1, bar: 2 };
         p = new Proxy(o, {

+ 13 - 0
Userland/Libraries/LibJS/Tests/builtins/Proxy/Proxy.handler-get.js

@@ -18,6 +18,19 @@ describe("[[Get]] trap normal behavior", () => {
         p.foo;
     });
 
+    test("correct arguments passed to trap even for number", () => {
+        let o = {};
+        let p = new Proxy(o, {
+            get(target, property, receiver) {
+                expect(target).toBe(o);
+                expect(property).toBe("1");
+                expect(receiver).toBe(p);
+            },
+        });
+
+        p[1];
+    });
+
     test("conditional return", () => {
         let o = { foo: 1 };
         let p = new Proxy(o, {

+ 12 - 0
Userland/Libraries/LibJS/Tests/builtins/Proxy/Proxy.handler-getOwnPropertyDescriptor.js

@@ -24,6 +24,18 @@ describe("[Call][GetOwnProperty]] trap normal behavior", () => {
         Object.getOwnPropertyDescriptor(p, "foo");
     });
 
+    test("correct arguments passed to trap even for number", () => {
+        let o = {};
+        let p = new Proxy(o, {
+            getOwnPropertyDescriptor(target, property) {
+                expect(target).toBe(o);
+                expect(property).toBe("1");
+            },
+        });
+
+        Object.getOwnPropertyDescriptor(p, 1);
+    });
+
     test("conditional returned descriptor", () => {
         let o = { foo: "bar" };
         Object.defineProperty(o, "baz", {

+ 13 - 0
Userland/Libraries/LibJS/Tests/builtins/Proxy/Proxy.handler-has.js

@@ -18,6 +18,19 @@ describe("[[Has]] trap normal behavior", () => {
         "foo" in p;
     });
 
+    test("correct arguments passed to trap even for number", () => {
+        let o = {};
+        let p = new Proxy(o, {
+            has(target, prop) {
+                expect(target).toBe(o);
+                expect(prop).toBe("1");
+                return true;
+            },
+        });
+
+        1 in p;
+    });
+
     test("conditional return", () => {
         let o = {};
         let p = new Proxy(o, {

+ 15 - 0
Userland/Libraries/LibJS/Tests/builtins/Proxy/Proxy.handler-set.js

@@ -20,6 +20,21 @@ describe("[[Set]] trap normal behavior", () => {
         p.foo = 10;
     });
 
+    test("correct arguments passed to trap even for number", () => {
+        let o = {};
+        let p = new Proxy(o, {
+            set(target, prop, value, receiver) {
+                expect(target).toBe(o);
+                expect(prop).toBe("1");
+                expect(value).toBe(10);
+                expect(receiver).toBe(p);
+                return true;
+            },
+        });
+
+        p[1] = 10;
+    });
+
     test("conditional return value", () => {
         let p = new Proxy(
             {},