[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/JavaScriptCore:
This patch:
- 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.
- Reworks JSObject::getOwnPropertyDescriptor() for custom accessors, making it simpler,
more robust, and no longer required to reify all static properties.
- Hoists GetValueFunc / PutValueFunc declarations to JSC namespace so they can be used
in header files.
- Moves CustomAccessor's wrapper maps to JSGlobalObject (because VM outlives it) and
simplifies their keys to C++ function pointers.
- 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.
- 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:
- JavaScriptCore.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.
(JSC::getCustomGetterFunction):
(JSC::getCustomSetterFunction):
(JSC::JSObject::getOwnPropertyDescriptor):
(JSC::validateAndApplyPropertyDescriptor):
(JSC::getCustomGetterSetterFunctionForGetterSetter): Deleted.
(JSC::JSObject::fillCustomGetterPropertySlot):
(JSC::getStaticPropertySlotFromTable):
- runtime/PropertyDescriptor.cpp:
(JSC::PropertyDescriptor::setAccessorDescriptor):
(JSC::PropertyDescriptor::setCustomDescriptor): Deleted.
- runtime/PropertyDescriptor.h:
- runtime/PropertySlot.cpp:
(JSC::PropertySlot::customAccessorGetter const): Deleted.
(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):
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: