Title: [272885] trunk
Revision
272885
Author
[email protected]
Date
2021-02-15 15:08:52 -0800 (Mon, 15 Feb 2021)

Log Message

[JSC] PropertySlot should allow passing custom setters
https://bugs.webkit.org/show_bug.cgi?id=221872

Reviewed by Yusuke Suzuki.

LayoutTests/imported/w3c:

* web-platform-tests/WebIDL/ecmascript-binding/attributes-accessors-unique-function-objects-expected.txt: Added.
* web-platform-tests/WebIDL/ecmascript-binding/attributes-accessors-unique-function-objects.html: Added.
* web-platform-tests/dom/events/Event-isTrusted.any-expected.txt:
* web-platform-tests/dom/events/Event-isTrusted.any.worker-expected.txt:
* web-platform-tests/html/browsers/history/the-location-interface/document_location-expected.txt:
* web-platform-tests/html/browsers/windows/auxiliary-browsing-contexts/opener-setter.window-expected.txt:
* web-platform-tests/html/browsers/windows/embedded-opener-expected.txt:

Source/_javascript_Core:

This patch:

1. Merges PropertySlot::TypeCustomAccessor into TypeCustom, allowing to pass a setter for
   CustomAccessor / CustomValue. Raw C++ function pointers are used to avoid creating
   CustomGetterSetter instances for non-reified static properties.
2. Reworks JSObject::getOwnPropertyDescriptor() for custom accessors, making it simpler,
   more robust, and no longer required to reify all static properties.
3. Hoists GetValueFunc / PutValueFunc declarations to JSC namespace so they can be used
   in header files.
4. Moves CustomAccessor's wrapper maps to JSGlobalObject (because VM outlives it) and
   simplifies their keys to C++ function pointers.
5. Splits JSCustomGetterSetterFunction into JSCustomGetterFunction / JSCustomSetterFunction
   since their signatures and [[Call]] logic are quite different. This is a nice refactor
   that also simplifies garbage collection and reduces memory needed for setter wrappers.
6. Removes PropertyDescriptor::setCustomDescriptor(), making PropertyDescriptor unaware of
   custom accessors. Also, drops CustomAccessor check from validateAndApplyPropertyDescriptor()
   that was incorrect (no error should be thrown if accessors are unchanged) yet unreachable
   because PropertyDescriptor::equalTo() ignores CustomAccessor.

This change fixes a) accessor functions of unforgeable properties [1] to be persistent
(in terms of referential equality) and b) cross-realm accessor functions to be of correct
global object (instead of lexical).

[1]: https://heycam.github.io/webidl/#dfn-unforgeable-on-an-interface

* API/JSCallbackObject.h:
* _javascript_Core.xcodeproj/project.pbxproj:
* Sources.txt:
* runtime/JSCustomGetterFunction.cpp: Added.
(JSC::JSC_DEFINE_HOST_FUNCTION):
(JSC::JSCustomGetterFunction::JSCustomGetterFunction):
(JSC::JSCustomGetterFunction::create):
* runtime/JSCustomGetterFunction.h: Added.
* runtime/JSCustomGetterSetterFunction.cpp: Removed.
* runtime/JSCustomGetterSetterFunction.h: Removed.
* runtime/JSCustomSetterFunction.cpp: Added.
(JSC::JSC_DEFINE_HOST_FUNCTION):
(JSC::JSCustomSetterFunction::JSCustomSetterFunction):
(JSC::JSCustomSetterFunction::create):
* runtime/JSCustomSetterFunction.h: Added.
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::JSGlobalObject):
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::customGetterFunctionMap):
(JSC::JSGlobalObject::customSetterFunctionMap):
(JSC::JSGlobalObject::customGetterFunctionStructure const):
(JSC::JSGlobalObject::customSetterFunctionStructure const):
(JSC::JSGlobalObject::customGetterSetterFunctionStructure const): Deleted.
* runtime/JSObject.cpp:
(JSC::getCustomGetterFunction):
(JSC::getCustomSetterFunction):
(JSC::JSObject::getOwnPropertyDescriptor):
(JSC::validateAndApplyPropertyDescriptor):
(JSC::getCustomGetterSetterFunctionForGetterSetter): Deleted.
* runtime/JSObject.h:
(JSC::JSObject::fillCustomGetterPropertySlot):
* runtime/Lookup.h:
(JSC::getStaticPropertySlotFromTable):
* runtime/PropertyDescriptor.cpp:
(JSC::PropertyDescriptor::setAccessorDescriptor):
(JSC::PropertyDescriptor::setCustomDescriptor): Deleted.
* runtime/PropertyDescriptor.h:
* runtime/PropertySlot.cpp:
(JSC::PropertySlot::customAccessorGetter const): Deleted.
* runtime/PropertySlot.h:
(JSC::PropertySlot::isCustom const):
(JSC::PropertySlot::customGetter const):
(JSC::PropertySlot::customSetter const):
(JSC::PropertySlot::setCustom):
(JSC::PropertySlot::setCacheableCustom):
(JSC::PropertySlot::getValue const):
(JSC::PropertySlot::isCustomAccessor const): Deleted.
(JSC::PropertySlot::customGetterSetter const): Deleted.
(JSC::PropertySlot::setCustomGetterSetter): Deleted.
* runtime/PutPropertySlot.h:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:

Source/WebCore:

To prevent cross-origin accessor functions from different realms to have the same wrapper,
return PropertySlot::TypeGetter instead.

Tests: fast/dom/Window/getOwnPropertyDescriptor-other-window.html
       js/instance-property-getter-other-instance.html
       imported/w3c/web-platform-tests/dom/events/Event-isTrusted.any.js
       imported/w3c/web-platform-tests/html/browsers/history/the-location-interface/document_location.html

* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::jsDOMWindowGetOwnPropertySlotRestrictedAccess):
* bindings/js/JSLocationCustom.cpp:
(WebCore::getOwnPropertySlotCommon):

LayoutTests:

* fast/dom/Window/getOwnPropertyDescriptor-other-window-expected.txt:
* fast/dom/Window/getOwnPropertyDescriptor-other-window.html:
* js/instance-property-getter-other-instance-expected.txt:
* js/instance-property-getter-other-instance.html:

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (272884 => 272885)


--- trunk/LayoutTests/ChangeLog	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/LayoutTests/ChangeLog	2021-02-15 23:08:52 UTC (rev 272885)
@@ -1,3 +1,15 @@
+2021-02-15  Alexey Shvayka  <[email protected]>
+
+        [JSC] PropertySlot should allow passing custom setters
+        https://bugs.webkit.org/show_bug.cgi?id=221872
+
+        Reviewed by Yusuke Suzuki.
+
+        * fast/dom/Window/getOwnPropertyDescriptor-other-window-expected.txt:
+        * fast/dom/Window/getOwnPropertyDescriptor-other-window.html:
+        * js/instance-property-getter-other-instance-expected.txt:
+        * js/instance-property-getter-other-instance.html:
+
 2021-02-15  Aditya Keerthi  <[email protected]>
 
         [iOS][FCR] Add new look for input type=range with datalist

Modified: trunk/LayoutTests/fast/dom/Window/getOwnPropertyDescriptor-other-window-expected.txt (272884 => 272885)


--- trunk/LayoutTests/fast/dom/Window/getOwnPropertyDescriptor-other-window-expected.txt	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/LayoutTests/fast/dom/Window/getOwnPropertyDescriptor-other-window-expected.txt	2021-02-15 23:08:52 UTC (rev 272885)
@@ -5,12 +5,12 @@
 
 descriptor = Object.getOwnPropertyDescriptor(otherWindow, 'location')
 PASS descriptor is not undefined
-PASS descriptor.get is an instance of Function
-PASS descriptor.set is an instance of Function
+PASS descriptor.get instanceof otherWindow.Function is true
+PASS descriptor.set instanceof otherWindow.Function is true
 PASS descriptor.enumerable is true
 PASS descriptor.configurable is false
 PASS descriptor.get.call(otherWindow).toString() is "about:blank"
-PASS descriptor.get.call() is descriptor.get.call(window)
+PASS descriptor.get.call() is descriptor.get.call(otherWindow)
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/dom/Window/getOwnPropertyDescriptor-other-window.html (272884 => 272885)


--- trunk/LayoutTests/fast/dom/Window/getOwnPropertyDescriptor-other-window.html	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/LayoutTests/fast/dom/Window/getOwnPropertyDescriptor-other-window.html	2021-02-15 23:08:52 UTC (rev 272885)
@@ -10,12 +10,12 @@
 
 evalAndLog("descriptor = Object.getOwnPropertyDescriptor(otherWindow, 'location')");
 shouldNotBe("descriptor", "undefined");
-shouldBeType("descriptor.get", "Function");
-shouldBeType("descriptor.set", "Function");
+shouldBeTrue("descriptor.get instanceof otherWindow.Function");
+shouldBeTrue("descriptor.set instanceof otherWindow.Function");
 shouldBeTrue("descriptor.enumerable");
 shouldBeFalse("descriptor.configurable");
 shouldBeEqualToString("descriptor.get.call(otherWindow).toString()", "about:blank");
-shouldBe("descriptor.get.call()", "descriptor.get.call(window)");
+shouldBe("descriptor.get.call()", "descriptor.get.call(otherWindow)");
 </script>
 <script src=""
 </body>

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (272884 => 272885)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2021-02-15 23:08:52 UTC (rev 272885)
@@ -1,3 +1,18 @@
+2021-02-15  Alexey Shvayka  <[email protected]>
+
+        [JSC] PropertySlot should allow passing custom setters
+        https://bugs.webkit.org/show_bug.cgi?id=221872
+
+        Reviewed by Yusuke Suzuki.
+
+        * web-platform-tests/WebIDL/ecmascript-binding/attributes-accessors-unique-function-objects-expected.txt: Added.
+        * web-platform-tests/WebIDL/ecmascript-binding/attributes-accessors-unique-function-objects.html: Added.
+        * web-platform-tests/dom/events/Event-isTrusted.any-expected.txt:
+        * web-platform-tests/dom/events/Event-isTrusted.any.worker-expected.txt:
+        * web-platform-tests/html/browsers/history/the-location-interface/document_location-expected.txt:
+        * web-platform-tests/html/browsers/windows/auxiliary-browsing-contexts/opener-setter.window-expected.txt:
+        * web-platform-tests/html/browsers/windows/embedded-opener-expected.txt:
+
 2021-02-15  Antoine Quint  <[email protected]>
 
         Getting the computed style should resolve animations using the last style change event style

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/attributes-accessors-unique-function-objects-expected.txt (0 => 272885)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/attributes-accessors-unique-function-objects-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/attributes-accessors-unique-function-objects-expected.txt	2021-02-15 23:08:52 UTC (rev 272885)
@@ -0,0 +1,3 @@
+
+PASS For attributes, each copy of the accessor property has distinct built-in function objects for its getters and setters.
+

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/attributes-accessors-unique-function-objects.html (0 => 272885)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/attributes-accessors-unique-function-objects.html	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/attributes-accessors-unique-function-objects.html	2021-02-15 23:08:52 UTC (rev 272885)
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>All attributes accessors are unique function objects</title>
+<link rel="help" href=""
+<script src=""
+<script src=""
+<script>
+"use strict";
+
+test(() => {
+  const seenPrototypes = new WeakSet([Function.prototype]);
+  const seenFunctions = new WeakMap();
+
+  for (const windowKey of Object.getOwnPropertyNames(window)) {
+    const windowValue = window[windowKey];
+    if (typeof windowValue !== "function") continue;
+
+    const {prototype} = windowValue;
+    if (!prototype || seenPrototypes.has(prototype)) continue;
+    seenPrototypes.add(prototype);
+
+    for (const key of Object.getOwnPropertyNames(prototype)) {
+      const assert_not_seen = (fn, field) => {
+        const fnInfo = `${windowKey}.${key}.${field}`;
+        assert_equals(seenFunctions.get(fn), undefined, fnInfo);
+        seenFunctions.set(fn, fnInfo);
+      };
+
+      const desc = Object.getOwnPropertyDescriptor(prototype, key);
+      if (desc.get) assert_not_seen(desc.get, "[[Get]]");
+      if (desc.set) assert_not_seen(desc.set, "[[Set]]");
+    }
+  }
+}, "For attributes, each copy of the accessor property has distinct built-in function objects for its getters and setters.");
+</script>

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-isTrusted.any-expected.txt (272884 => 272885)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-isTrusted.any-expected.txt	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-isTrusted.any-expected.txt	2021-02-15 23:08:52 UTC (rev 272885)
@@ -1,7 +1,3 @@
 
-FAIL Event-isTrusted assert_equals: expected function "function isTrusted() {
-    [native code]
-}" but got function "function isTrusted() {
-    [native code]
-}"
+PASS Event-isTrusted
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-isTrusted.any.worker-expected.txt (272884 => 272885)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-isTrusted.any.worker-expected.txt	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-isTrusted.any.worker-expected.txt	2021-02-15 23:08:52 UTC (rev 272885)
@@ -1,7 +1,3 @@
 
-FAIL Event-isTrusted assert_equals: expected function "function isTrusted() {
-    [native code]
-}" but got function "function isTrusted() {
-    [native code]
-}"
+PASS Event-isTrusted
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/browsers/history/the-location-interface/document_location-expected.txt (272884 => 272885)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/browsers/history/the-location-interface/document_location-expected.txt	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/browsers/history/the-location-interface/document_location-expected.txt	2021-02-15 23:08:52 UTC (rev 272885)
@@ -1,14 +1,6 @@
 
 PASS document not in a browsing context
 PASS document.location equals window.location
-FAIL Attribute getter deduplication assert_equals: expected function "function location() {
-    [native code]
-}" but got function "function location() {
-    [native code]
-}"
-FAIL Attribute setter deduplication assert_equals: expected function "function location() {
-    [native code]
-}" but got function "function location() {
-    [native code]
-}"
+PASS Attribute getter deduplication
+PASS Attribute setter deduplication
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/browsers/windows/auxiliary-browsing-contexts/opener-setter.window-expected.txt (272884 => 272885)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/browsers/windows/auxiliary-browsing-contexts/opener-setter.window-expected.txt	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/browsers/windows/auxiliary-browsing-contexts/opener-setter.window-expected.txt	2021-02-15 23:08:52 UTC (rev 272885)
@@ -1,9 +1,9 @@
 
-FAIL Setting window.opener to undefined assert_equals: expected (string) "x" but got (undefined) undefined
-FAIL Setting window.opener to 42 assert_equals: expected (string) "x" but got (number) 42
-FAIL Setting window.opener to function () { return "hi" } assert_equals: expected (string) "x" but got (function) function "function () { return "hi" }"
-FAIL Setting window.opener to hi assert_equals: expected "x" but got "hi"
-FAIL Setting window.opener to [object Object] assert_equals: expected (string) "x" but got (object) object "[object Object]"
-FAIL Setting window.opener to  assert_equals: expected (string) "x" but got (object) []
-FAIL Setting window.opener to Symbol() assert_equals: expected (string) "x" but got (symbol) symbol "Symbol()"
+PASS Setting window.opener to undefined
+PASS Setting window.opener to 42
+PASS Setting window.opener to function () { return "hi" }
+PASS Setting window.opener to hi
+PASS Setting window.opener to [object Object]
+PASS Setting window.opener to
+PASS Setting window.opener to Symbol()
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/browsers/windows/embedded-opener-expected.txt (272884 => 272885)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/browsers/windows/embedded-opener-expected.txt	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/browsers/windows/embedded-opener-expected.txt	2021-02-15 23:08:52 UTC (rev 272885)
@@ -1,3 +1,3 @@
 
-FAIL opener and embedded documents; using window.open() assert_equals: opener before setting it to null via directly invoking the getter expected object "[object Window]" but got null
+PASS opener and embedded documents; using window.open()
 

Modified: trunk/LayoutTests/js/instance-property-getter-other-instance-expected.txt (272884 => 272885)


--- trunk/LayoutTests/js/instance-property-getter-other-instance-expected.txt	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/LayoutTests/js/instance-property-getter-other-instance-expected.txt	2021-02-15 23:08:52 UTC (rev 272885)
@@ -3,9 +3,7 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS locationGetter is an instance of function Function() {
-    [native code]
-}
+PASS locationGetter instanceof otherWindow.Function is true
 PASS locationGetter.call(otherWindow.document).toString() is "about:blank"
 PASS locationGetter.call(window.document) === window.document.location is true
 PASS successfullyParsed is true

Modified: trunk/LayoutTests/js/instance-property-getter-other-instance.html (272884 => 272885)


--- trunk/LayoutTests/js/instance-property-getter-other-instance.html	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/LayoutTests/js/instance-property-getter-other-instance.html	2021-02-15 23:08:52 UTC (rev 272885)
@@ -12,7 +12,7 @@
 {
     otherWindow = window.open("about:blank");
         locationGetter = Object.getOwnPropertyDescriptor(otherWindow.document, "location").get;
-        shouldBeType("locationGetter", Function);
+        shouldBeTrue("locationGetter instanceof otherWindow.Function");
         shouldBeEqualToString("locationGetter.call(otherWindow.document).toString()", "about:blank");
         // Should return the current document's location.
         shouldBeTrue("locationGetter.call(window.document) === window.document.location");

Modified: trunk/Source/_javascript_Core/API/JSCallbackObject.h (272884 => 272885)


--- trunk/Source/_javascript_Core/API/JSCallbackObject.h	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/API/JSCallbackObject.h	2021-02-15 23:08:52 UTC (rev 272885)
@@ -234,8 +234,6 @@
     static RawNativeFunction getCallFunction();
     static RawNativeFunction getConstructFunction();
 
-    using GetValueFunc = EncodedJSValue(JIT_OPERATION_ATTRIBUTES*)(JSGlobalObject*, EncodedJSValue, PropertyName);
-
     static GetValueFunc getStaticFunctionGetter();
     static GetValueFunc getCallbackGetter();
  

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (272884 => 272885)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2021-02-15 23:08:52 UTC (rev 272885)
@@ -905,6 +905,7 @@
     runtime/GenericTypedArrayView.h
     runtime/GenericTypedArrayViewInlines.h
     runtime/GetPutInfo.h
+    runtime/GetterSetter.h
     runtime/GetVM.h
     runtime/GlobalExecutable.h
     runtime/HashMapImpl.h
@@ -940,6 +941,8 @@
     runtime/JSCast.h
     runtime/JSCell.h
     runtime/JSCellInlines.h
+    runtime/JSCustomGetterFunction.h
+    runtime/JSCustomSetterFunction.h
     runtime/JSDataView.h
     runtime/JSDateMath.h
     runtime/JSDestructibleObject.h
@@ -999,6 +1002,8 @@
     runtime/ModuleProgramExecutable.h
     runtime/NativeExecutable.h
     runtime/NativeFunction.h
+    runtime/NullGetterFunction.h
+    runtime/NullSetterFunction.h
     runtime/NumberObject.h
     runtime/NumberPrototype.h
     runtime/NumericStrings.h

Modified: trunk/Source/_javascript_Core/ChangeLog (272884 => 272885)


--- trunk/Source/_javascript_Core/ChangeLog	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-02-15 23:08:52 UTC (rev 272885)
@@ -1,3 +1,91 @@
+2021-02-15  Alexey Shvayka  <[email protected]>
+
+        [JSC] PropertySlot should allow passing custom setters
+        https://bugs.webkit.org/show_bug.cgi?id=221872
+
+        Reviewed by Yusuke Suzuki.
+
+        This patch:
+
+        1. Merges PropertySlot::TypeCustomAccessor into TypeCustom, allowing to pass a setter for
+           CustomAccessor / CustomValue. Raw C++ function pointers are used to avoid creating
+           CustomGetterSetter instances for non-reified static properties.
+        2. Reworks JSObject::getOwnPropertyDescriptor() for custom accessors, making it simpler,
+           more robust, and no longer required to reify all static properties.
+        3. Hoists GetValueFunc / PutValueFunc declarations to JSC namespace so they can be used
+           in header files.
+        4. Moves CustomAccessor's wrapper maps to JSGlobalObject (because VM outlives it) and
+           simplifies their keys to C++ function pointers.
+        5. Splits JSCustomGetterSetterFunction into JSCustomGetterFunction / JSCustomSetterFunction
+           since their signatures and [[Call]] logic are quite different. This is a nice refactor
+           that also simplifies garbage collection and reduces memory needed for setter wrappers.
+        6. Removes PropertyDescriptor::setCustomDescriptor(), making PropertyDescriptor unaware of
+           custom accessors. Also, drops CustomAccessor check from validateAndApplyPropertyDescriptor()
+           that was incorrect (no error should be thrown if accessors are unchanged) yet unreachable
+           because PropertyDescriptor::equalTo() ignores CustomAccessor.
+
+        This change fixes a) accessor functions of unforgeable properties [1] to be persistent
+        (in terms of referential equality) and b) cross-realm accessor functions to be of correct
+        global object (instead of lexical).
+
+        [1]: https://heycam.github.io/webidl/#dfn-unforgeable-on-an-interface
+
+        * API/JSCallbackObject.h:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * Sources.txt:
+        * runtime/JSCustomGetterFunction.cpp: Added.
+        (JSC::JSC_DEFINE_HOST_FUNCTION):
+        (JSC::JSCustomGetterFunction::JSCustomGetterFunction):
+        (JSC::JSCustomGetterFunction::create):
+        * runtime/JSCustomGetterFunction.h: Added.
+        * runtime/JSCustomGetterSetterFunction.cpp: Removed.
+        * runtime/JSCustomGetterSetterFunction.h: Removed.
+        * runtime/JSCustomSetterFunction.cpp: Added.
+        (JSC::JSC_DEFINE_HOST_FUNCTION):
+        (JSC::JSCustomSetterFunction::JSCustomSetterFunction):
+        (JSC::JSCustomSetterFunction::create):
+        * runtime/JSCustomSetterFunction.h: Added.
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::JSGlobalObject):
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::customGetterFunctionMap):
+        (JSC::JSGlobalObject::customSetterFunctionMap):
+        (JSC::JSGlobalObject::customGetterFunctionStructure const):
+        (JSC::JSGlobalObject::customSetterFunctionStructure const):
+        (JSC::JSGlobalObject::customGetterSetterFunctionStructure const): Deleted.
+        * runtime/JSObject.cpp:
+        (JSC::getCustomGetterFunction):
+        (JSC::getCustomSetterFunction):
+        (JSC::JSObject::getOwnPropertyDescriptor):
+        (JSC::validateAndApplyPropertyDescriptor):
+        (JSC::getCustomGetterSetterFunctionForGetterSetter): Deleted.
+        * runtime/JSObject.h:
+        (JSC::JSObject::fillCustomGetterPropertySlot):
+        * runtime/Lookup.h:
+        (JSC::getStaticPropertySlotFromTable):
+        * runtime/PropertyDescriptor.cpp:
+        (JSC::PropertyDescriptor::setAccessorDescriptor):
+        (JSC::PropertyDescriptor::setCustomDescriptor): Deleted.
+        * runtime/PropertyDescriptor.h:
+        * runtime/PropertySlot.cpp:
+        (JSC::PropertySlot::customAccessorGetter const): Deleted.
+        * runtime/PropertySlot.h:
+        (JSC::PropertySlot::isCustom const):
+        (JSC::PropertySlot::customGetter const):
+        (JSC::PropertySlot::customSetter const):
+        (JSC::PropertySlot::setCustom):
+        (JSC::PropertySlot::setCacheableCustom):
+        (JSC::PropertySlot::getValue const):
+        (JSC::PropertySlot::isCustomAccessor const): Deleted.
+        (JSC::PropertySlot::customGetterSetter const): Deleted.
+        (JSC::PropertySlot::setCustomGetterSetter): Deleted.
+        * runtime/PutPropertySlot.h:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+
 2021-02-15  Caio Lima  <[email protected]>
 
         [ESNext] Implement private accessors

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (272884 => 272885)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2021-02-15 23:08:52 UTC (rev 272885)
@@ -1182,7 +1182,6 @@
 		70EC0EC71AA0D7DA00B6AAFA /* StringIteratorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 70EC0EC11AA0D7DA00B6AAFA /* StringIteratorPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		70ECA6061AFDBEA200449739 /* JSTemplateObjectDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6011AFDBEA200449739 /* JSTemplateObjectDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		70ECA6091AFDBEA200449739 /* TemplateObjectDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6041AFDBEA200449739 /* TemplateObjectDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		72AAF7CE1D0D31B3005E60BE /* JSCustomGetterSetterFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 72AAF7CC1D0D318B005E60BE /* JSCustomGetterSetterFunction.h */; };
 		7311FA32240DB1D3003D48DB /* DeleteByIdVariant.h in Headers */ = {isa = PBXBuildFile; fileRef = 7311FA31240DB1D3003D48DB /* DeleteByIdVariant.h */; };
 		734B655523F5C10400A069D1 /* DeletePropertySlot.h in Headers */ = {isa = PBXBuildFile; fileRef = 734B655423F4A33100A069D1 /* DeletePropertySlot.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		73AD062923FF662600F53593 /* DeleteByStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 73AD062823FF662600F53593 /* DeleteByStatus.h */; };
@@ -1233,6 +1232,11 @@
 		7C184E2317BEE240007CB63A /* JSPromiseConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C184E2117BEE240007CB63A /* JSPromiseConstructor.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		7E4EE7090EBB7963005934AA /* StructureChain.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E4EE7080EBB7963005934AA /* StructureChain.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		840480131021A1D9008E7F01 /* JSAPIValueWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = BC0894D60FAFBA2D00001865 /* JSAPIValueWrapper.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		84323E7825D5EC1900F97776 /* NullGetterFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 6546F5201A32A59C006F07D5 /* NullGetterFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		84323E7925D5EC2800F97776 /* NullSetterFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 65525FC41A6DD3B3007B5495 /* NullSetterFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		84323E7A25D5EC3B00F97776 /* GetterSetter.h in Headers */ = {isa = PBXBuildFile; fileRef = BC337BDE0E1AF0B80076918A /* GetterSetter.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		84323E7F25D5EC6A00F97776 /* JSCustomSetterFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 84323E7B25D5EC6900F97776 /* JSCustomSetterFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		84323E8025D5EC6A00F97776 /* JSCustomGetterFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 84323E7C25D5EC6900F97776 /* JSCustomGetterFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		860161E30F3A83C100F84710 /* AbstractMacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161DF0F3A83C100F84710 /* AbstractMacroAssembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		860161E40F3A83C100F84710 /* MacroAssemblerX86.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161E00F3A83C100F84710 /* MacroAssemblerX86.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		860161E50F3A83C100F84710 /* MacroAssemblerX86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161E10F3A83C100F84710 /* MacroAssemblerX86_64.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -4036,8 +4040,6 @@
 		70ECA6001AFDBEA200449739 /* JSTemplateObjectDescriptor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTemplateObjectDescriptor.cpp; sourceTree = "<group>"; };
 		70ECA6011AFDBEA200449739 /* JSTemplateObjectDescriptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTemplateObjectDescriptor.h; sourceTree = "<group>"; };
 		70ECA6041AFDBEA200449739 /* TemplateObjectDescriptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateObjectDescriptor.h; sourceTree = "<group>"; };
-		72AAF7CB1D0D318B005E60BE /* JSCustomGetterSetterFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCustomGetterSetterFunction.cpp; sourceTree = "<group>"; };
-		72AAF7CC1D0D318B005E60BE /* JSCustomGetterSetterFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomGetterSetterFunction.h; sourceTree = "<group>"; };
 		7311FA31240DB1D3003D48DB /* DeleteByIdVariant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeleteByIdVariant.h; sourceTree = "<group>"; };
 		7311FA33240DB249003D48DB /* DeleteByIdVariant.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DeleteByIdVariant.cpp; sourceTree = "<group>"; };
 		73190D962400934900F891C9 /* DeleteByStatus.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DeleteByStatus.cpp; sourceTree = "<group>"; };
@@ -4133,6 +4135,10 @@
 		7D5FB19220744BF2005DDF64 /* IntlPluralRules.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlPluralRules.h; sourceTree = "<group>"; };
 		7E4EE7080EBB7963005934AA /* StructureChain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureChain.h; sourceTree = "<group>"; };
 		7E4EE70E0EBB7A5B005934AA /* StructureChain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureChain.cpp; sourceTree = "<group>"; };
+		84323E7B25D5EC6900F97776 /* JSCustomSetterFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomSetterFunction.h; sourceTree = "<group>"; };
+		84323E7C25D5EC6900F97776 /* JSCustomGetterFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomGetterFunction.h; sourceTree = "<group>"; };
+		84323E7D25D5EC6A00F97776 /* JSCustomGetterFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCustomGetterFunction.cpp; sourceTree = "<group>"; };
+		84323E7E25D5EC6A00F97776 /* JSCustomSetterFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCustomSetterFunction.cpp; sourceTree = "<group>"; };
 		84925A9A22B30CBA00D1DFFF /* RegExpStringIteratorPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpStringIteratorPrototype.cpp; sourceTree = "<group>"; };
 		84925A9B22B30CBA00D1DFFF /* RegExpStringIteratorPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpStringIteratorPrototype.h; sourceTree = "<group>"; };
 		84925A9C22B30CC800D1DFFF /* RegExpStringIteratorPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = RegExpStringIteratorPrototype.js; sourceTree = "<group>"; };
@@ -7482,8 +7488,10 @@
 				865A30F0135007E100CDB49E /* JSCJSValueInlines.h */,
 				FE1E2C3C2240C1EF00F6B729 /* JSCPtrTag.cpp */,
 				FE7497E5209001B00003565B /* JSCPtrTag.h */,
-				72AAF7CB1D0D318B005E60BE /* JSCustomGetterSetterFunction.cpp */,
-				72AAF7CC1D0D318B005E60BE /* JSCustomGetterSetterFunction.h */,
+				84323E7D25D5EC6A00F97776 /* JSCustomGetterFunction.cpp */,
+				84323E7C25D5EC6900F97776 /* JSCustomGetterFunction.h */,
+				84323E7E25D5EC6A00F97776 /* JSCustomSetterFunction.cpp */,
+				84323E7B25D5EC6900F97776 /* JSCustomSetterFunction.h */,
 				0F2B66BD17B6B5AB00A7AE3F /* JSDataView.cpp */,
 				0F2B66BE17B6B5AB00A7AE3F /* JSDataView.h */,
 				0F2B66BF17B6B5AB00A7AE3F /* JSDataViewPrototype.cpp */,
@@ -9811,6 +9819,7 @@
 				0F9332A014CA7DCD0085F3C6 /* GetByStatus.h in Headers */,
 				520D99F12388CC81000509A3 /* GetByValHistory.h in Headers */,
 				7964656A1B952FF0003059EE /* GetPutInfo.h in Headers */,
+				84323E7A25D5EC3B00F97776 /* GetterSetter.h in Headers */,
 				534E03581E53BF2F00213F64 /* GetterSetterAccessCase.h in Headers */,
 				FE1D6D6F236258FE007A5C26 /* GetVM.h in Headers */,
 				0FEC3C5B1F33A48900F59B6C /* GigacageAlignedMemoryAllocator.h in Headers */,
@@ -10038,7 +10047,8 @@
 				148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */,
 				FE7497E6209001B10003565B /* JSCPtrTag.h in Headers */,
 				A72028B81797601E0098028C /* JSCTestRunnerUtils.h in Headers */,
-				72AAF7CE1D0D31B3005E60BE /* JSCustomGetterSetterFunction.h in Headers */,
+				84323E8025D5EC6A00F97776 /* JSCustomGetterFunction.h in Headers */,
+				84323E7F25D5EC6A00F97776 /* JSCustomSetterFunction.h in Headers */,
 				0F2B66EC17B6B5AB00A7AE3F /* JSDataView.h in Headers */,
 				0F2B66EE17B6B5AB00A7AE3F /* JSDataViewPrototype.h in Headers */,
 				996B731C1BDA08DD00331B84 /* JSDataViewPrototype.lut.h in Headers */,
@@ -10270,6 +10280,8 @@
 				FE1409072056F3FF00CFE318 /* NativeFunction.h in Headers */,
 				0FFB922016D033B70055A5DB /* NodeConstructors.h in Headers */,
 				BC18C43F0E16F5CD00B34460 /* Nodes.h in Headers */,
+				84323E7825D5EC1900F97776 /* NullGetterFunction.h in Headers */,
+				84323E7925D5EC2800F97776 /* NullSetterFunction.h in Headers */,
 				BC18C4410E16F5CD00B34460 /* NumberConstructor.h in Headers */,
 				BC18C4420E16F5CD00B34460 /* NumberConstructor.lut.h in Headers */,
 				BC18C4430E16F5CD00B34460 /* NumberObject.h in Headers */,

Modified: trunk/Source/_javascript_Core/Sources.txt (272884 => 272885)


--- trunk/Source/_javascript_Core/Sources.txt	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/Sources.txt	2021-02-15 23:08:52 UTC (rev 272885)
@@ -865,7 +865,8 @@
 runtime/JSCPtrTag.cpp
 runtime/JSCallee.cpp
 runtime/JSCell.cpp
-runtime/JSCustomGetterSetterFunction.cpp
+runtime/JSCustomGetterFunction.cpp
+runtime/JSCustomSetterFunction.cpp
 runtime/JSDataView.cpp
 runtime/JSDataViewPrototype.cpp
 runtime/JSDateMath.cpp @no-unify // Confine U_SHOW_CPLUSPLUS_API's effect to this file.

Added: trunk/Source/_javascript_Core/runtime/JSCustomGetterFunction.cpp (0 => 272885)


--- trunk/Source/_javascript_Core/runtime/JSCustomGetterFunction.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/JSCustomGetterFunction.cpp	2021-02-15 23:08:52 UTC (rev 272885)
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2015-2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSCustomGetterFunction.h"
+
+#include "JSCJSValueInlines.h"
+
+namespace JSC {
+
+const ClassInfo JSCustomGetterFunction::s_info = { "Function", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCustomGetterFunction) };
+static JSC_DECLARE_HOST_FUNCTION(customGetterFunctionCall);
+
+JSC_DEFINE_HOST_FUNCTION(customGetterFunctionCall, (JSGlobalObject* globalObject, CallFrame* callFrame))
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    JSCustomGetterFunction* customGetterFunction = jsCast<JSCustomGetterFunction*>(callFrame->jsCallee());
+    JSValue thisValue = callFrame->thisValue();
+
+    GetValueFunc getter = customGetterFunction->getter();
+    ASSERT(getter);
+
+    if (auto domAttribute = customGetterFunction->domAttribute()) {
+        if (!thisValue.inherits(vm, domAttribute->classInfo))
+            return throwVMDOMAttributeGetterTypeError(globalObject, scope, domAttribute->classInfo, customGetterFunction->propertyName());
+    }
+
+    RELEASE_AND_RETURN(scope, getter(globalObject, JSValue::encode(thisValue), customGetterFunction->propertyName()));
+}
+
+JSCustomGetterFunction::JSCustomGetterFunction(VM& vm, NativeExecutable* executable, JSGlobalObject* globalObject, Structure* structure, const PropertyName& propertyName, GetValueFunc getter, Optional<DOMAttributeAnnotation> domAttribute)
+    : Base(vm, executable, globalObject, structure)
+    , m_propertyName(propertyName)
+    , m_getter(getter)
+    , m_domAttribute(domAttribute)
+{
+}
+
+JSCustomGetterFunction* JSCustomGetterFunction::create(VM& vm, JSGlobalObject* globalObject, const PropertyName& propertyName, GetValueFunc getter, Optional<DOMAttributeAnnotation> domAttribute)
+{
+    NativeExecutable* executable = vm.getHostFunction(customGetterFunctionCall, callHostFunctionAsConstructor, String(propertyName.publicName()));
+    Structure* structure = globalObject->customGetterFunctionStructure();
+    JSCustomGetterFunction* function = new (NotNull, allocateCell<JSCustomGetterFunction>(vm.heap)) JSCustomGetterFunction(vm, executable, globalObject, structure, propertyName, getter, domAttribute);
+
+    // Can't do this during initialization because getHostFunction might do a GC allocation.
+    String name = makeString("get ", String(propertyName.publicName()));
+    function->finishCreation(vm, executable, 0, name);
+    return function;
+}
+
+} // namespace JSC

Added: trunk/Source/_javascript_Core/runtime/JSCustomGetterFunction.h (0 => 272885)


--- trunk/Source/_javascript_Core/runtime/JSCustomGetterFunction.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/JSCustomGetterFunction.h	2021-02-15 23:08:52 UTC (rev 272885)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015-2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "JSFunction.h"
+
+namespace JSC {
+
+class JSCustomGetterFunction final : public JSFunction {
+public:
+    typedef JSFunction Base;
+    static constexpr unsigned StructureFlags = Base::StructureFlags;
+
+    template<typename CellType, SubspaceAccess mode>
+    static IsoSubspace* subspaceFor(VM& vm)
+    {
+        return vm.customGetterFunctionSpace<mode>();
+    }
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        ASSERT(globalObject);
+        return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), info());
+    }
+
+    JS_EXPORT_PRIVATE static JSCustomGetterFunction* create(VM&, JSGlobalObject*, const PropertyName&, GetValueFunc, Optional<DOMAttributeAnnotation> = WTF::nullopt);
+
+    DECLARE_EXPORT_INFO;
+
+    const PropertyName& propertyName() const { return m_propertyName; }
+    GetValueFunc getter() const { return m_getter; };
+    Optional<DOMAttributeAnnotation> domAttribute() const { return m_domAttribute; };
+
+private:
+    JSCustomGetterFunction(VM&, NativeExecutable*, JSGlobalObject*, Structure*, const PropertyName&, GetValueFunc, Optional<DOMAttributeAnnotation>);
+
+    PropertyName m_propertyName;
+    GetValueFunc m_getter;
+    Optional<DOMAttributeAnnotation> m_domAttribute;
+};
+
+} // namespace JSC

Deleted: trunk/Source/_javascript_Core/runtime/JSCustomGetterSetterFunction.cpp (272884 => 272885)


--- trunk/Source/_javascript_Core/runtime/JSCustomGetterSetterFunction.cpp	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/runtime/JSCustomGetterSetterFunction.cpp	2021-02-15 23:08:52 UTC (rev 272885)
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2015, 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "JSCustomGetterSetterFunction.h"
-
-#include "CustomGetterSetter.h"
-#include "JSCJSValueInlines.h"
-
-namespace JSC {
-
-const ClassInfo JSCustomGetterSetterFunction::s_info = { "Function", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCustomGetterSetterFunction) };
-
-static JSC_DECLARE_HOST_FUNCTION(customGetterSetterFunctionCall);
-
-JSC_DEFINE_HOST_FUNCTION(customGetterSetterFunctionCall, (JSGlobalObject* globalObject, CallFrame* callFrame))
-{
-    VM& vm = globalObject->vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    JSCustomGetterSetterFunction* customGetterSetterFunction = jsCast<JSCustomGetterSetterFunction*>(callFrame->jsCallee());
-    CustomGetterSetter* customGetterSetter = customGetterSetterFunction->customGetterSetter();
-    JSValue thisValue = callFrame->thisValue();
-
-    if (customGetterSetterFunction->isSetter()) {
-        CustomGetterSetter::CustomSetter setter = customGetterSetter->setter();
-        ASSERT(setter);
-        scope.release();
-        setter(globalObject, JSValue::encode(thisValue), JSValue::encode(callFrame->argument(0)));
-        return JSValue::encode(jsUndefined());
-    }
-
-    if (customGetterSetter->inherits<DOMAttributeGetterSetter>(vm)) {
-        auto domAttribute = jsCast<DOMAttributeGetterSetter*>(customGetterSetter)->domAttribute();
-        if (!thisValue.inherits(vm, domAttribute.classInfo))
-            return throwVMDOMAttributeGetterTypeError(globalObject, scope, domAttribute.classInfo, customGetterSetterFunction->propertyName());
-    }
-
-    RELEASE_AND_RETURN(scope, customGetterSetter->getter()(globalObject, JSValue::encode(thisValue), customGetterSetterFunction->propertyName()));
-}
-
-JSCustomGetterSetterFunction::JSCustomGetterSetterFunction(VM& vm, NativeExecutable* executable, JSGlobalObject* globalObject, Structure* structure, const Type type, const PropertyName& propertyName)
-    : Base(vm, executable, globalObject, structure)
-    , m_type(type)
-    , m_propertyName(propertyName)
-{
-}
-
-JSCustomGetterSetterFunction* JSCustomGetterSetterFunction::create(VM& vm, JSGlobalObject* globalObject, CustomGetterSetter* getterSetter, const Type type, const PropertyName& propertyName)
-{
-    ASSERT(type == Type::Getter ? !!getterSetter->getter() : !!getterSetter->setter());
-
-    const char* prefix = (type == Type::Getter) ? "get " : "set ";
-    String name = makeString(prefix, String(propertyName.publicName()));
-
-    NativeExecutable* executable = vm.getHostFunction(customGetterSetterFunctionCall, callHostFunctionAsConstructor, String(propertyName.publicName()));
-
-    Structure* structure = globalObject->customGetterSetterFunctionStructure();
-    JSCustomGetterSetterFunction* function = new (NotNull, allocateCell<JSCustomGetterSetterFunction>(vm.heap)) JSCustomGetterSetterFunction(vm, executable, globalObject, structure, type, propertyName);
-
-    // Can't do this during initialization because getHostFunction might do a GC allocation.
-    function->finishCreation(vm, executable, getterSetter, name);
-    return function;
-}
-
-void JSCustomGetterSetterFunction::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    JSCustomGetterSetterFunction* thisObject = jsCast<JSCustomGetterSetterFunction*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    Base::visitChildren(thisObject, visitor);
-
-    visitor.append(thisObject->m_getterSetter);
-}
-
-void JSCustomGetterSetterFunction::finishCreation(VM& vm, NativeExecutable* executable, CustomGetterSetter* getterSetter, const String& name)
-{
-    Base::finishCreation(vm, executable, isSetter(), name);
-    ASSERT(inherits(vm, info()));
-    ASSERT(getterSetter);
-    m_getterSetter.set(vm, this, getterSetter);
-}
-
-} // namespace JSC

Deleted: trunk/Source/_javascript_Core/runtime/JSCustomGetterSetterFunction.h (272884 => 272885)


--- trunk/Source/_javascript_Core/runtime/JSCustomGetterSetterFunction.h	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/runtime/JSCustomGetterSetterFunction.h	2021-02-15 23:08:52 UTC (rev 272885)
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2015-2019 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include "JSFunction.h"
-
-namespace JSC {
-
-class CustomGetterSetter;
-
-class JSCustomGetterSetterFunction final : public JSFunction {
-public:
-    typedef JSFunction Base;
-
-    // The Type is set to the number of arguments the resultant function will have.
-    enum class Type { Getter = 0, Setter = 1 };
-
-    static constexpr unsigned StructureFlags = Base::StructureFlags;
-
-    template<typename CellType, SubspaceAccess mode>
-    static IsoSubspace* subspaceFor(VM& vm)
-    {
-        return vm.customGetterSetterFunctionSpace<mode>();
-    }
-
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-    {
-        ASSERT(globalObject);
-        return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), info());
-    }
-
-    static JSCustomGetterSetterFunction* create(VM&, JSGlobalObject*, CustomGetterSetter*, const Type, const PropertyName&);
-
-    DECLARE_EXPORT_INFO;
-
-    CustomGetterSetter* customGetterSetter() const { return m_getterSetter.get(); }
-    bool isSetter() const { return m_type == Type::Setter; }
-    const PropertyName& propertyName() const { return m_propertyName; }
-
-private:
-    JSCustomGetterSetterFunction(VM&, NativeExecutable*, JSGlobalObject*, Structure*, Type, const PropertyName&);
-    void finishCreation(VM&, NativeExecutable*, CustomGetterSetter*, const String&);
-    static void visitChildren(JSCell*, SlotVisitor&);
-
-    WriteBarrier<CustomGetterSetter> m_getterSetter;
-    Type m_type;
-    PropertyName m_propertyName;
-};
-
-} // namespace JSC

Added: trunk/Source/_javascript_Core/runtime/JSCustomSetterFunction.cpp (0 => 272885)


--- trunk/Source/_javascript_Core/runtime/JSCustomSetterFunction.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/JSCustomSetterFunction.cpp	2021-02-15 23:08:52 UTC (rev 272885)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015-2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSCustomSetterFunction.h"
+
+#include "JSCJSValueInlines.h"
+
+namespace JSC {
+
+const ClassInfo JSCustomSetterFunction::s_info = { "Function", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCustomSetterFunction) };
+static JSC_DECLARE_HOST_FUNCTION(customSetterFunctionCall);
+
+JSC_DEFINE_HOST_FUNCTION(customSetterFunctionCall, (JSGlobalObject* globalObject, CallFrame* callFrame))
+{
+    PutValueFunc setter = jsCast<JSCustomSetterFunction*>(callFrame->jsCallee())->setter();
+    ASSERT(setter);
+    setter(globalObject, JSValue::encode(callFrame->thisValue()), JSValue::encode(callFrame->argument(0)));
+    return JSValue::encode(jsUndefined());
+}
+
+JSCustomSetterFunction::JSCustomSetterFunction(VM& vm, NativeExecutable* executable, JSGlobalObject* globalObject, Structure* structure, PutValueFunc setter)
+    : Base(vm, executable, globalObject, structure)
+    , m_setter(setter)
+{
+}
+
+JSCustomSetterFunction* JSCustomSetterFunction::create(VM& vm, JSGlobalObject* globalObject, const PropertyName& propertyName, PutValueFunc setter)
+{
+    NativeExecutable* executable = vm.getHostFunction(customSetterFunctionCall, callHostFunctionAsConstructor, String(propertyName.publicName()));
+    Structure* structure = globalObject->customSetterFunctionStructure();
+    JSCustomSetterFunction* function = new (NotNull, allocateCell<JSCustomSetterFunction>(vm.heap)) JSCustomSetterFunction(vm, executable, globalObject, structure, setter);
+
+    // Can't do this during initialization because getHostFunction might do a GC allocation.
+    String name = makeString("set ", String(propertyName.publicName()));
+    function->finishCreation(vm, executable, 1, name);
+    return function;
+}
+
+} // namespace JSC

Added: trunk/Source/_javascript_Core/runtime/JSCustomSetterFunction.h (0 => 272885)


--- trunk/Source/_javascript_Core/runtime/JSCustomSetterFunction.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/JSCustomSetterFunction.h	2021-02-15 23:08:52 UTC (rev 272885)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015-2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "JSFunction.h"
+
+namespace JSC {
+
+class JSCustomSetterFunction final : public JSFunction {
+public:
+    typedef JSFunction Base;
+    static constexpr unsigned StructureFlags = Base::StructureFlags;
+
+    template<typename CellType, SubspaceAccess mode>
+    static IsoSubspace* subspaceFor(VM& vm)
+    {
+        return vm.customSetterFunctionSpace<mode>();
+    }
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        ASSERT(globalObject);
+        return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), info());
+    }
+
+    JS_EXPORT_PRIVATE static JSCustomSetterFunction* create(VM&, JSGlobalObject*, const PropertyName&, PutValueFunc);
+
+    DECLARE_EXPORT_INFO;
+
+    PutValueFunc setter() const { return m_setter; };
+
+private:
+    JSCustomSetterFunction(VM&, NativeExecutable*, JSGlobalObject*, Structure*, PutValueFunc);
+
+    PutValueFunc m_setter;
+};
+
+} // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (272884 => 272885)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2021-02-15 23:08:52 UTC (rev 272885)
@@ -109,7 +109,8 @@
 #include "JSCallbackConstructor.h"
 #include "JSCallbackFunction.h"
 #include "JSCallbackObject.h"
-#include "JSCustomGetterSetterFunction.h"
+#include "JSCustomGetterFunction.h"
+#include "JSCustomSetterFunction.h"
 #include "JSDataView.h"
 #include "JSDataViewPrototype.h"
 #include "JSDollarVM.h"
@@ -504,6 +505,8 @@
     , m_numberToStringWatchpointSet(IsWatched)
     , m_runtimeFlags()
     , m_stackTraceLimit(Options::defaultErrorStackTraceLimit())
+    , m_customGetterFunctionMap(vm)
+    , m_customSetterFunctionMap(vm)
     , m_globalObjectMethodTable(globalObjectMethodTable ? globalObjectMethodTable : &s_globalObjectMethodTable)
 {
 }
@@ -615,10 +618,14 @@
     initFunctionStructures(m_builtinFunctions);
     initFunctionStructures(m_ordinaryFunctions);
 
-    m_customGetterSetterFunctionStructure.initLater(
+    m_customGetterFunctionStructure.initLater(
         [] (const Initializer<Structure>& init) {
-            init.set(JSCustomGetterSetterFunction::createStructure(init.vm, init.owner, init.owner->m_functionPrototype.get()));
+            init.set(JSCustomGetterFunction::createStructure(init.vm, init.owner, init.owner->m_functionPrototype.get()));
         });
+    m_customSetterFunctionStructure.initLater(
+        [] (const Initializer<Structure>& init) {
+            init.set(JSCustomSetterFunction::createStructure(init.vm, init.owner, init.owner->m_functionPrototype.get()));
+        });
     m_boundFunctionStructure.initLater(
         [] (const Initializer<Structure>& init) {
             init.set(JSBoundFunction::createStructure(init.vm, init.owner, init.owner->m_functionPrototype.get()));
@@ -2001,7 +2008,8 @@
     visitFunctionStructures(thisObject->m_builtinFunctions);
     visitFunctionStructures(thisObject->m_ordinaryFunctions);
 
-    thisObject->m_customGetterSetterFunctionStructure.visit(visitor);
+    thisObject->m_customGetterFunctionStructure.visit(visitor);
+    thisObject->m_customSetterFunctionStructure.visit(visitor);
     thisObject->m_boundFunctionStructure.visit(visitor);
     thisObject->m_nativeStdFunctionStructure.visit(visitor);
     visitor.append(thisObject->m_regExpStructure);

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (272884 => 272885)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2021-02-15 23:08:52 UTC (rev 272885)
@@ -86,6 +86,8 @@
 class JSArrayBuffer;
 class JSArrayBufferPrototype;
 class JSCallee;
+class JSCustomGetterFunction;
+class JSCustomSetterFunction;
 class JSGlobalObjectDebuggable;
 class JSInternalPromise;
 class JSModuleLoader;
@@ -396,7 +398,8 @@
     FunctionStructures m_ordinaryFunctions;
 
     LazyProperty<JSGlobalObject, Structure> m_boundFunctionStructure;
-    LazyProperty<JSGlobalObject, Structure> m_customGetterSetterFunctionStructure;
+    LazyProperty<JSGlobalObject, Structure> m_customGetterFunctionStructure;
+    LazyProperty<JSGlobalObject, Structure> m_customSetterFunctionStructure;
     LazyProperty<JSGlobalObject, Structure> m_nativeStdFunctionStructure;
     PropertyOffset m_functionNameOffset;
     WriteBarrier<Structure> m_regExpStructure;
@@ -540,6 +543,9 @@
     bool isMapPrototypeSetFastAndNonObservable();
     bool isSetPrototypeAddFastAndNonObservable();
 
+    WeakGCMap<GetValueFunc, JSCustomGetterFunction>& customGetterFunctionMap() { return m_customGetterFunctionMap; }
+    WeakGCMap<PutValueFunc, JSCustomSetterFunction>& customSetterFunctionMap() { return m_customSetterFunctionMap; }
+
 #if ENABLE(DFG_JIT)
     using ReferencedGlobalPropertyWatchpointSets = HashMap<RefPtr<UniquedStringImpl>, Ref<WatchpointSet>, IdentifierRepHash>;
     ReferencedGlobalPropertyWatchpointSets m_referencedGlobalPropertyWatchpointSets;
@@ -554,6 +560,8 @@
     RuntimeFlags m_runtimeFlags;
     ConsoleClient* m_consoleClient { nullptr };
     Optional<unsigned> m_stackTraceLimit;
+    WeakGCMap<GetValueFunc, JSCustomGetterFunction> m_customGetterFunctionMap;
+    WeakGCMap<PutValueFunc, JSCustomSetterFunction> m_customSetterFunctionMap;
 
 #if ASSERT_ENABLED
     const JSGlobalObject* m_globalObjectAtDebuggerEntry { nullptr };
@@ -799,7 +807,8 @@
     }
 
     Structure* boundFunctionStructure() const { return m_boundFunctionStructure.get(this); }
-    Structure* customGetterSetterFunctionStructure() const { return m_customGetterSetterFunctionStructure.get(this); }
+    Structure* customGetterFunctionStructure() const { return m_customGetterFunctionStructure.get(this); }
+    Structure* customSetterFunctionStructure() const { return m_customSetterFunctionStructure.get(this); }
     Structure* nativeStdFunctionStructure() const { return m_nativeStdFunctionStructure.get(this); }
     PropertyOffset functionNameOffset() const { return m_functionNameOffset; }
     Structure* numberObjectStructure() const { return m_numberObjectStructure.get(this); }

Modified: trunk/Source/_javascript_Core/runtime/JSObject.cpp (272884 => 272885)


--- trunk/Source/_javascript_Core/runtime/JSObject.cpp	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/runtime/JSObject.cpp	2021-02-15 23:08:52 UTC (rev 272885)
@@ -33,7 +33,8 @@
 #include "HeapAnalyzer.h"
 #include "IndexingHeaderInlines.h"
 #include "JSCInlines.h"
-#include "JSCustomGetterSetterFunction.h"
+#include "JSCustomGetterFunction.h"
+#include "JSCustomSetterFunction.h"
 #include "JSFunction.h"
 #include "JSImmutableButterfly.h"
 #include "Lookup.h"
@@ -3525,18 +3526,26 @@
     return Butterfly::createOrGrowPropertyStorage(butterfly(), vm, this, structure(vm), oldSize, newSize);
 }
 
-static JSCustomGetterSetterFunction* getCustomGetterSetterFunctionForGetterSetter(JSGlobalObject* globalObject, PropertyName propertyName, CustomGetterSetter* getterSetter, JSCustomGetterSetterFunction::Type type)
+static JSCustomGetterFunction* getCustomGetterFunction(JSGlobalObject* globalObject, PropertyName propertyName, GetValueFunc getValueFunc, Optional<DOMAttributeAnnotation> domAttribute)
 {
-    VM& vm = globalObject->vm();
-    auto key = std::make_pair(getterSetter, (int)type);
-    JSCustomGetterSetterFunction* customGetterSetterFunction = vm.customGetterSetterFunctionMap.get(key);
-    if (!customGetterSetterFunction) {
-        customGetterSetterFunction = JSCustomGetterSetterFunction::create(vm, globalObject, getterSetter, type, propertyName.publicName());
-        vm.customGetterSetterFunctionMap.set(key, customGetterSetterFunction);
+    JSCustomGetterFunction* customGetterFunction = globalObject->customGetterFunctionMap().get(getValueFunc);
+    if (!customGetterFunction) {
+        customGetterFunction = JSCustomGetterFunction::create(globalObject->vm(), globalObject, propertyName, getValueFunc, domAttribute);
+        globalObject->customGetterFunctionMap().set(getValueFunc, customGetterFunction);
     }
-    return customGetterSetterFunction;
+    return customGetterFunction;
 }
 
+static JSCustomSetterFunction* getCustomSetterFunction(JSGlobalObject* globalObject, PropertyName propertyName, PutValueFunc putValueFunc)
+{
+    JSCustomSetterFunction* customSetterFunction = globalObject->customSetterFunctionMap().get(putValueFunc);
+    if (!customSetterFunction) {
+        customSetterFunction = JSCustomSetterFunction::create(globalObject->vm(), globalObject, propertyName, putValueFunc);
+        globalObject->customSetterFunctionMap().set(putValueFunc, customSetterFunction);
+    }
+    return customSetterFunction;
+}
+
 bool JSObject::getOwnPropertyDescriptor(JSGlobalObject* globalObject, PropertyName propertyName, PropertyDescriptor& descriptor)
 {
     VM& vm = globalObject->vm();
@@ -3551,31 +3560,13 @@
     if (slot.isAccessor())
         descriptor.setAccessorDescriptor(slot.getterSetter(), slot.attributes());
     else if (slot.attributes() & PropertyAttribute::CustomAccessor) {
-        CustomGetterSetter* getterSetter;
-        if (slot.isCustomAccessor())
-            getterSetter = slot.customGetterSetter();
-        else {
-            ASSERT(slot.slotBase());
-            JSObject* thisObject = slot.slotBase();
-
-            JSValue maybeGetterSetter = thisObject->getDirect(vm, propertyName);
-            if (!maybeGetterSetter) {
-                thisObject->reifyAllStaticProperties(globalObject);
-                maybeGetterSetter = thisObject->getDirect(vm, propertyName);
-            }
-
-            ASSERT(maybeGetterSetter);
-            getterSetter = jsDynamicCast<CustomGetterSetter*>(vm, maybeGetterSetter);
-        }
-        ASSERT(getterSetter);
-        if (!getterSetter)
-            return false;
-
-        descriptor.setCustomDescriptor(slot.attributes());
-        if (getterSetter->getter())
-            descriptor.setGetter(getCustomGetterSetterFunctionForGetterSetter(globalObject, propertyName, getterSetter, JSCustomGetterSetterFunction::Type::Getter));
-        if (getterSetter->setter())
-            descriptor.setSetter(getCustomGetterSetterFunctionForGetterSetter(globalObject, propertyName, getterSetter, JSCustomGetterSetterFunction::Type::Setter));
+        ASSERT_WITH_MESSAGE(slot.isCustom(), "PropertySlot::TypeCustom is required in case of PropertyAttribute::CustomAccessor");
+        descriptor.setAccessorDescriptor((slot.attributes() | PropertyAttribute::Accessor) & ~PropertyAttribute::CustomAccessor);
+        JSGlobalObject* slotBaseGlobalObject = slot.slotBase()->globalObject(vm);
+        if (slot.customGetter())
+            descriptor.setGetter(getCustomGetterFunction(slotBaseGlobalObject, propertyName, slot.customGetter(), slot.domAttribute()));
+        if (slot.customSetter())
+            descriptor.setSetter(getCustomSetterFunction(slotBaseGlobalObject, propertyName, slot.customSetter()));
     } else {
         JSValue value = slot.getValue(globalObject, propertyName);
         RETURN_IF_EXCEPTION(scope, false);
@@ -3669,8 +3660,6 @@
                 return typeError(globalObject, scope, throwException, "Attempting to change the setter of an unconfigurable property."_s);
             if (descriptor.getterPresent() && descriptor.getter() != current.getter())
                 return typeError(globalObject, scope, throwException, "Attempting to change the getter of an unconfigurable property."_s);
-            if (current.attributes() & PropertyAttribute::CustomAccessor)
-                return typeError(globalObject, scope, throwException, UnconfigurablePropertyChangeAccessMechanismError);
 
             return true;
         }

Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (272884 => 272885)


--- trunk/Source/_javascript_Core/runtime/JSObject.h	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h	2021-02-15 23:08:52 UTC (rev 272885)
@@ -1415,16 +1415,16 @@
     if (customGetterSetter->inherits<DOMAttributeGetterSetter>(vm)) {
         auto* domAttribute = jsCast<DOMAttributeGetterSetter*>(customGetterSetter);
         if (structure->isUncacheableDictionary())
-            slot.setCustom(this, attributes, domAttribute->getter(), domAttribute->domAttribute());
+            slot.setCustom(this, attributes, domAttribute->getter(), domAttribute->setter(), domAttribute->domAttribute());
         else
-            slot.setCacheableCustom(this, attributes, domAttribute->getter(), domAttribute->domAttribute());
+            slot.setCacheableCustom(this, attributes, domAttribute->getter(), domAttribute->setter(), domAttribute->domAttribute());
         return;
     }
 
     if (structure->isUncacheableDictionary())
-        slot.setCustom(this, attributes, customGetterSetter->getter());
+        slot.setCustom(this, attributes, customGetterSetter->getter(), customGetterSetter->setter());
     else
-        slot.setCacheableCustom(this, attributes, customGetterSetter->getter());
+        slot.setCacheableCustom(this, attributes, customGetterSetter->getter(), customGetterSetter->setter());
 }
 
 // It may seem crazy to inline a function this large, especially a virtual function,

Modified: trunk/Source/_javascript_Core/runtime/Lookup.h (272884 => 272885)


--- trunk/Source/_javascript_Core/runtime/Lookup.h	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/runtime/Lookup.h	2021-02-15 23:08:52 UTC (rev 272885)
@@ -238,17 +238,18 @@
     }
 
     if (entry->attributes() & PropertyAttribute::DOMJITAttribute) {
+        ASSERT_WITH_MESSAGE(entry->attributes() & PropertyAttribute::ReadOnly, "DOMJITAttribute supports readonly attributes currently.");
         const DOMJIT::GetterSetter* domJIT = entry->domJIT();
-        slot.setCacheableCustom(thisObject, attributesForStructure(entry->attributes()), domJIT->getter(), DOMAttributeAnnotation { classInfo, domJIT });
+        slot.setCacheableCustom(thisObject, attributesForStructure(entry->attributes()), domJIT->getter(), nullptr, DOMAttributeAnnotation { classInfo, domJIT });
         return true;
     }
 
     if (entry->attributes() & PropertyAttribute::DOMAttribute) {
-        slot.setCacheableCustom(thisObject, attributesForStructure(entry->attributes()), entry->propertyGetter(), DOMAttributeAnnotation { classInfo, nullptr });
+        slot.setCacheableCustom(thisObject, attributesForStructure(entry->attributes()), entry->propertyGetter(), entry->propertyPutter(), DOMAttributeAnnotation { classInfo, nullptr });
         return true;
     }
 
-    slot.setCacheableCustom(thisObject, attributesForStructure(entry->attributes()), entry->propertyGetter());
+    slot.setCacheableCustom(thisObject, attributesForStructure(entry->attributes()), entry->propertyGetter(), entry->propertyPutter());
     return true;
 }
 

Modified: trunk/Source/_javascript_Core/runtime/PropertyDescriptor.cpp (272884 => 272885)


--- trunk/Source/_javascript_Core/runtime/PropertyDescriptor.cpp	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/runtime/PropertyDescriptor.cpp	2021-02-15 23:08:52 UTC (rev 272885)
@@ -125,15 +125,16 @@
     }
 }
 
-void PropertyDescriptor::setCustomDescriptor(unsigned attributes)
+void PropertyDescriptor::setAccessorDescriptor(unsigned attributes)
 {
-    ASSERT(!(attributes & PropertyAttribute::CustomValue));
-    m_attributes = attributes | PropertyAttribute::Accessor | PropertyAttribute::CustomAccessor;
-    m_attributes &= ~PropertyAttribute::ReadOnly;
+    ASSERT(attributes & PropertyAttribute::Accessor);
+    ASSERT(!(attributes & PropertyAttribute::CustomAccessorOrValue));
+    attributes &= ~PropertyAttribute::ReadOnly; // FIXME: we should be able to ASSERT this!
+
+    m_attributes = attributes;
+    m_getter = jsUndefined();
+    m_setter = jsUndefined();
     m_seenAttributes = EnumerablePresent | ConfigurablePresent;
-    setGetter(jsUndefined());
-    setSetter(jsUndefined());
-    m_value = JSValue();
 }
 
 void PropertyDescriptor::setAccessorDescriptor(GetterSetter* accessor, unsigned attributes)

Modified: trunk/Source/_javascript_Core/runtime/PropertyDescriptor.h (272884 => 272885)


--- trunk/Source/_javascript_Core/runtime/PropertyDescriptor.h	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/runtime/PropertyDescriptor.h	2021-02-15 23:08:52 UTC (rev 272885)
@@ -64,7 +64,7 @@
     JSObject* setterObject() const;
     JS_EXPORT_PRIVATE void setUndefined();
     JS_EXPORT_PRIVATE void setDescriptor(JSValue, unsigned attributes);
-    JS_EXPORT_PRIVATE void setCustomDescriptor(unsigned attributes);
+    JS_EXPORT_PRIVATE void setAccessorDescriptor(unsigned attributes);
     JS_EXPORT_PRIVATE void setAccessorDescriptor(GetterSetter* accessor, unsigned attributes);
     JS_EXPORT_PRIVATE void setWritable(bool);
     JS_EXPORT_PRIVATE void setEnumerable(bool);

Modified: trunk/Source/_javascript_Core/runtime/PropertySlot.cpp (272884 => 272885)


--- trunk/Source/_javascript_Core/runtime/PropertySlot.cpp	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/runtime/PropertySlot.cpp	2021-02-15 23:08:52 UTC (rev 272885)
@@ -46,21 +46,6 @@
     return JSValue::decode(m_data.custom.getValue(globalObject, JSValue::encode(thisValue), propertyName));
 }
 
-JSValue PropertySlot::customAccessorGetter(JSGlobalObject* globalObject, PropertyName propertyName) const
-{
-    if (!m_data.customAccessor.getterSetter->getter())
-        return jsUndefined();
-
-    if (auto domAttribute = this->domAttribute()) {
-        VM& vm = globalObject->vm();
-        if (!m_thisValue.inherits(vm, domAttribute->classInfo)) {
-            auto scope = DECLARE_THROW_SCOPE(vm);
-            return throwDOMAttributeGetterTypeError(globalObject, scope, domAttribute->classInfo, propertyName);
-        }
-    }
-    return JSValue::decode(m_data.customAccessor.getterSetter->getter()(globalObject, JSValue::encode(m_thisValue), propertyName));
-}
-
 JSValue PropertySlot::getPureResult() const
 {
     JSValue result;

Modified: trunk/Source/_javascript_Core/runtime/PropertySlot.h (272884 => 272885)


--- trunk/Source/_javascript_Core/runtime/PropertySlot.h	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/runtime/PropertySlot.h	2021-02-15 23:08:52 UTC (rev 272885)
@@ -84,11 +84,17 @@
     return static_cast<uint8_t>(attributes);
 }
 
+using GetValueFunc = EncodedJSValue(JIT_OPERATION_ATTRIBUTES*)(JSGlobalObject*, EncodedJSValue thisValue, PropertyName);
+using GetValueFuncWithPtr = EncodedJSValue(JIT_OPERATION_ATTRIBUTES*)(JSGlobalObject*, EncodedJSValue thisValue, PropertyName, void*);
+
+using PutValueFunc = bool (*)(JSGlobalObject*, EncodedJSValue baseObject, EncodedJSValue value);
+using PutValueFuncWithPtr = bool (*)(JSGlobalObject*, EncodedJSValue baseObject, EncodedJSValue value, void*);
+
 class PropertySlot {
 
     // We rely on PropertySlot being stack allocated when used. This is needed
     // because we rely on some of its fields being a GC root. For example, it
-    // may be the only thing that points to the CustomGetterSetter property it has.
+    // may be the only thing that points to the GetterSetter property it has.
     WTF_FORBID_HEAP_ALLOCATION;
 
     enum PropertyType : uint8_t {
@@ -96,7 +102,6 @@
         TypeValue,
         TypeGetter,
         TypeCustom,
-        TypeCustomAccessor,
     };
 
 public:
@@ -121,8 +126,8 @@
             disallowVMEntry.emplace(*vmForInquiry);
     }
 
-    using GetValueFunc = EncodedJSValue(JIT_OPERATION_ATTRIBUTES*)(JSGlobalObject*, EncodedJSValue thisValue, PropertyName);
-    using GetValueFuncWithPtr = EncodedJSValue(JIT_OPERATION_ATTRIBUTES*)(JSGlobalObject*, EncodedJSValue thisValue, PropertyName, void*);
+    using GetValueFunc = JSC::GetValueFunc;
+    using GetValueFuncWithPtr = JSC::GetValueFuncWithPtr;
 
     JSValue getValue(JSGlobalObject*, PropertyName) const;
     JSValue getValue(JSGlobalObject*, uint64_t propertyName) const;
@@ -133,7 +138,6 @@
     bool isValue() const { return m_propertyType == TypeValue; }
     bool isAccessor() const { return m_propertyType == TypeGetter; }
     bool isCustom() const { return m_propertyType == TypeCustom; }
-    bool isCustomAccessor() const { return m_propertyType == TypeCustomAccessor; }
     bool isCacheableValue() const { return isCacheable() && isValue(); }
     bool isCacheableGetter() const { return isCacheable() && isAccessor(); }
     bool isCacheableCustom() const { return isCacheable() && isCustom(); }
@@ -164,14 +168,14 @@
 
     GetValueFunc customGetter() const
     {
-        ASSERT(isCacheableCustom());
+        ASSERT(isCustom());
         return m_data.custom.getValue;
     }
 
-    CustomGetterSetter* customGetterSetter() const
+    PutValueFunc customSetter() const
     {
-        ASSERT(isCustomAccessor());
-        return m_data.customAccessor.getterSetter;
+        ASSERT(isCustom());
+        return m_data.custom.putValue;
     }
 
     JSObject* slotBase() const
@@ -255,7 +259,7 @@
         m_additionalData.moduleNamespaceSlot.scopeOffset = scopeOffset.offset();
     }
 
-    void setCustom(JSObject* slotBase, unsigned attributes, GetValueFunc getValue)
+    void setCustom(JSObject* slotBase, unsigned attributes, GetValueFunc getValue, PutValueFunc putValue = nullptr)
     {
         ASSERT(attributes == attributesForStructure(attributes));
         
@@ -262,6 +266,8 @@
         ASSERT(getValue);
         assertIsCFunctionPtr(getValue);
         m_data.custom.getValue = getValue;
+        assertIsNullOrCFunctionPtr(putValue);
+        m_data.custom.putValue = putValue;
         m_attributes = attributes;
 
         ASSERT(slotBase);
@@ -270,14 +276,14 @@
         ASSERT(m_cacheability == CachingDisallowed);
     }
 
-    void setCustom(JSObject* slotBase, unsigned attributes, GetValueFunc getValue, DOMAttributeAnnotation domAttribute)
+    void setCustom(JSObject* slotBase, unsigned attributes, GetValueFunc getValue, PutValueFunc putValue, DOMAttributeAnnotation domAttribute)
     {
-        setCustom(slotBase, attributes, getValue);
+        setCustom(slotBase, attributes, getValue, putValue);
         m_additionalDataType = AdditionalDataType::DOMAttribute;
         m_additionalData.domAttribute = domAttribute;
     }
     
-    void setCacheableCustom(JSObject* slotBase, unsigned attributes, GetValueFunc getValue)
+    void setCacheableCustom(JSObject* slotBase, unsigned attributes, GetValueFunc getValue, PutValueFunc putValue = nullptr)
     {
         ASSERT(attributes == attributesForStructure(attributes));
         
@@ -284,6 +290,8 @@
         ASSERT(getValue);
         assertIsCFunctionPtr(getValue);
         m_data.custom.getValue = getValue;
+        assertIsNullOrCFunctionPtr(putValue);
+        m_data.custom.putValue = putValue;
         m_attributes = attributes;
 
         ASSERT(slotBase);
@@ -293,31 +301,13 @@
         m_cacheability = CachingAllowed;
     }
 
-    void setCacheableCustom(JSObject* slotBase, unsigned attributes, GetValueFunc getValue, DOMAttributeAnnotation domAttribute)
+    void setCacheableCustom(JSObject* slotBase, unsigned attributes, GetValueFunc getValue, PutValueFunc putValue, DOMAttributeAnnotation domAttribute)
     {
-        setCacheableCustom(slotBase, attributes, getValue);
+        setCacheableCustom(slotBase, attributes, getValue, putValue);
         m_additionalDataType = AdditionalDataType::DOMAttribute;
         m_additionalData.domAttribute = domAttribute;
     }
 
-    void setCustomGetterSetter(JSObject* slotBase, unsigned attributes, CustomGetterSetter* getterSetter)
-    {
-        ASSERT(attributes == attributesForStructure(attributes));
-        ASSERT(attributes & PropertyAttribute::CustomAccessor);
-
-        disableCaching();
-
-        ASSERT(getterSetter);
-        m_data.customAccessor.getterSetter = getterSetter;
-        m_attributes = attributes;
-
-        ASSERT(slotBase);
-        m_slotBase = slotBase;
-        m_propertyType = TypeCustomAccessor;
-
-        ASSERT(m_cacheability == CachingDisallowed);
-    }
-
     void setGetterSlot(JSObject* slotBase, unsigned attributes, GetterSetter* getterSetter)
     {
         ASSERT(attributes == attributesForStructure(attributes));
@@ -377,7 +367,6 @@
 private:
     JS_EXPORT_PRIVATE JSValue functionGetter(JSGlobalObject*) const;
     JS_EXPORT_PRIVATE JSValue customGetter(JSGlobalObject*, PropertyName) const;
-    JS_EXPORT_PRIVATE JSValue customAccessorGetter(JSGlobalObject*, PropertyName) const;
 
     union {
         EncodedJSValue value;
@@ -386,10 +375,8 @@
         } getter;
         struct {
             GetValueFunc getValue;
+            PutValueFunc putValue;
         } custom;
-        struct {
-            CustomGetterSetter* getterSetter;
-        } customAccessor;
     } m_data;
 
     unsigned m_attributes { 0 };
@@ -417,8 +404,6 @@
         return JSValue::decode(m_data.value);
     if (m_propertyType == TypeGetter)
         return functionGetter(globalObject);
-    if (m_propertyType == TypeCustomAccessor)
-        return customAccessorGetter(globalObject, propertyName);
     return customGetter(globalObject, propertyName);
 }
 
@@ -429,8 +414,6 @@
         return JSValue::decode(m_data.value);
     if (m_propertyType == TypeGetter)
         return functionGetter(globalObject);
-    if (m_propertyType == TypeCustomAccessor)
-        return customAccessorGetter(globalObject, Identifier::from(vm, propertyName));
     return customGetter(globalObject, Identifier::from(vm, propertyName));
 }
 

Modified: trunk/Source/_javascript_Core/runtime/PutPropertySlot.h (272884 => 272885)


--- trunk/Source/_javascript_Core/runtime/PutPropertySlot.h	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/runtime/PutPropertySlot.h	2021-02-15 23:08:52 UTC (rev 272885)
@@ -38,8 +38,8 @@
 public:
     enum Type : uint8_t { Uncachable, ExistingProperty, NewProperty, SetterProperty, CustomValue, CustomAccessor };
     enum Context { UnknownContext, PutById, PutByIdEval };
-    using PutValueFunc = bool (*)(JSGlobalObject*, EncodedJSValue thisObject, EncodedJSValue value);
-    using PutValueFuncWithPtr = bool (*)(JSGlobalObject*, EncodedJSValue thisObject, EncodedJSValue value, void*);
+    using PutValueFunc = JSC::PutValueFunc;
+    using PutValueFuncWithPtr = JSC::PutValueFuncWithPtr;
 
     PutPropertySlot(JSValue thisValue, bool isStrictMode = false, Context context = UnknownContext, bool isInitialization = false)
         : m_base(nullptr)

Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (272884 => 272885)


--- trunk/Source/_javascript_Core/runtime/VM.cpp	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp	2021-02-15 23:08:52 UTC (rev 272885)
@@ -96,7 +96,8 @@
 #include "JSCallbackFunction.h"
 #include "JSCallbackObject.h"
 #include "JSCallee.h"
-#include "JSCustomGetterSetterFunction.h"
+#include "JSCustomGetterFunction.h"
+#include "JSCustomSetterFunction.h"
 #include "JSDestructibleObjectHeapCellType.h"
 #include "JSFinalizationRegistry.h"
 #include "JSFunction.h"
@@ -388,7 +389,6 @@
     , propertyNames(nullptr)
     , emptyList(new ArgList)
     , machineCodeBytesPerBytecodeWordForBaselineJIT(makeUnique<SimpleStats>())
-    , customGetterSetterFunctionMap(*this)
     , stringCache(*this)
     , symbolImplToSymbolMap(*this)
     , structureCache(*this)
@@ -1482,7 +1482,8 @@
 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(callbackGlobalObjectSpace, callbackGlobalObjectHeapCellType.get(), JSCallbackObject<JSGlobalObject>)
 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(callbackFunctionSpace, cellHeapCellType.get(), JSCallbackFunction) // Hash:0xe7648ebc
 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(callbackObjectSpace, callbackObjectHeapCellType.get(), JSCallbackObject<JSNonFinalObject>)
-DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(customGetterSetterFunctionSpace, cellHeapCellType.get(), JSCustomGetterSetterFunction) // Hash:0x18091000
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(customGetterFunctionSpace, cellHeapCellType.get(), JSCustomGetterFunction)
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(customSetterFunctionSpace, cellHeapCellType.get(), JSCustomSetterFunction)
 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(dataViewSpace, cellHeapCellType.get(), JSDataView)
 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(debuggerScopeSpace, cellHeapCellType.get(), DebuggerScope)
 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(errorInstanceSpace, errorInstanceHeapCellType.get(), ErrorInstance) // Hash:0x3f40d4a

Modified: trunk/Source/_javascript_Core/runtime/VM.h (272884 => 272885)


--- trunk/Source/_javascript_Core/runtime/VM.h	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/_javascript_Core/runtime/VM.h	2021-02-15 23:08:52 UTC (rev 272885)
@@ -141,7 +141,6 @@
 class JSAPIWrapperObject;
 class JSCCallbackFunction;
 class JSCallbackConstructor;
-class JSCustomGetterSetterFunction;
 class JSDestructibleObjectHeapCellType;
 class JSGlobalObject;
 class JSGlobalLexicalEnvironment;
@@ -503,7 +502,8 @@
     DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(callbackGlobalObjectSpace)
     DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(callbackFunctionSpace)
     DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(callbackObjectSpace)
-    DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(customGetterSetterFunctionSpace)
+    DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(customGetterFunctionSpace)
+    DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(customSetterFunctionSpace)
     DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(dataViewSpace)
     DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(debuggerScopeSpace)
     DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(errorInstanceSpace)
@@ -723,7 +723,6 @@
     SmallStrings smallStrings;
     NumericStrings numericStrings;
     std::unique_ptr<SimpleStats> machineCodeBytesPerBytecodeWordForBaselineJIT;
-    WeakGCMap<std::pair<CustomGetterSetter*, int>, JSCustomGetterSetterFunction> customGetterSetterFunctionMap;
     WeakGCMap<StringImpl*, JSString, PtrHash<StringImpl*>> stringCache;
     Strong<JSString> lastCachedString;
 

Modified: trunk/Source/WebCore/ChangeLog (272884 => 272885)


--- trunk/Source/WebCore/ChangeLog	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/WebCore/ChangeLog	2021-02-15 23:08:52 UTC (rev 272885)
@@ -1,3 +1,23 @@
+2021-02-15  Alexey Shvayka  <[email protected]>
+
+        [JSC] PropertySlot should allow passing custom setters
+        https://bugs.webkit.org/show_bug.cgi?id=221872
+
+        Reviewed by Yusuke Suzuki.
+
+        To prevent cross-origin accessor functions from different realms to have the same wrapper,
+        return PropertySlot::TypeGetter instead.
+
+        Tests: fast/dom/Window/getOwnPropertyDescriptor-other-window.html
+               js/instance-property-getter-other-instance.html
+               imported/w3c/web-platform-tests/dom/events/Event-isTrusted.any.js
+               imported/w3c/web-platform-tests/html/browsers/history/the-location-interface/document_location.html
+
+        * bindings/js/JSDOMWindowCustom.cpp:
+        (WebCore::jsDOMWindowGetOwnPropertySlotRestrictedAccess):
+        * bindings/js/JSLocationCustom.cpp:
+        (WebCore::getOwnPropertySlotCommon):
+
 2021-02-15  Aditya Keerthi  <[email protected]>
 
         [iOS][FCR] Add new look for input type=range with datalist

Modified: trunk/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp (272884 => 272885)


--- trunk/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp	2021-02-15 23:08:52 UTC (rev 272885)
@@ -48,9 +48,12 @@
 #include "Settings.h"
 #include "WebCoreJSClientData.h"
 #include <_javascript_Core/BuiltinNames.h>
+#include <_javascript_Core/GetterSetter.h>
 #include <_javascript_Core/HeapAnalyzer.h>
 #include <_javascript_Core/InternalFunction.h>
 #include <_javascript_Core/JSCInlines.h>
+#include <_javascript_Core/JSCustomGetterFunction.h>
+#include <_javascript_Core/JSCustomSetterFunction.h>
 #include <_javascript_Core/JSFunction.h>
 #include <_javascript_Core/JSMicrotask.h>
 #include <_javascript_Core/Lookup.h>
@@ -184,9 +187,10 @@
             || propertyName == builtinNames.openerPublicName()
             || propertyName == builtinNames.parentPublicName()
             || propertyName == builtinNames.topPublicName()) {
-            bool shouldExposeSetter = propertyName == builtinNames.locationPublicName();
-            CustomGetterSetter* customGetterSetter = CustomGetterSetter::create(vm, entry->propertyGetter(), shouldExposeSetter ? entry->propertyPutter() : nullptr);
-            slot.setCustomGetterSetter(thisObject, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DontEnum), customGetterSetter);
+            auto* getter = JSCustomGetterFunction::create(vm, &lexicalGlobalObject, propertyName, entry->propertyGetter());
+            auto* setter = propertyName == builtinNames.locationPublicName() ? JSCustomSetterFunction::create(vm, &lexicalGlobalObject, propertyName, entry->propertyPutter()) : nullptr;
+            auto* getterSetter = GetterSetter::create(vm, &lexicalGlobalObject, getter, setter);
+            slot.setGetterSlot(thisObject, PropertyAttribute::Accessor | PropertyAttribute::DontEnum, getterSetter);
             return true;
         }
     }

Modified: trunk/Source/WebCore/bindings/js/JSLocationCustom.cpp (272884 => 272885)


--- trunk/Source/WebCore/bindings/js/JSLocationCustom.cpp	2021-02-15 23:03:03 UTC (rev 272884)
+++ trunk/Source/WebCore/bindings/js/JSLocationCustom.cpp	2021-02-15 23:08:52 UTC (rev 272885)
@@ -29,6 +29,8 @@
 #include "JSDOMWindowCustom.h"
 #include "RuntimeApplicationChecks.h"
 #include "WebCoreJSClientData.h"
+#include <_javascript_Core/GetterSetter.h>
+#include <_javascript_Core/JSCustomSetterFunction.h>
 #include <_javascript_Core/JSFunction.h>
 #include <_javascript_Core/Lookup.h>
 
@@ -70,8 +72,9 @@
     // a descriptor that has a setter but no getter.
     if (slot.internalMethodType() == PropertySlot::InternalMethodType::GetOwnProperty && propertyName == static_cast<JSVMClientData*>(vm.clientData)->builtinNames().hrefPublicName()) {
         auto* entry = JSLocation::info()->staticPropHashTable->entry(propertyName);
-        CustomGetterSetter* customGetterSetter = CustomGetterSetter::create(vm, nullptr, entry->propertyPutter());
-        slot.setCustomGetterSetter(&thisObject, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontEnum), customGetterSetter);
+        auto* setter = JSCustomSetterFunction::create(vm, &lexicalGlobalObject, propertyName, entry->propertyPutter());
+        auto* getterSetter = GetterSetter::create(vm, &lexicalGlobalObject, nullptr, setter);
+        slot.setGetterSlot(&thisObject, PropertyAttribute::Accessor | PropertyAttribute::DontEnum, getterSetter);
         return true;
     }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to