Ignore:
Timestamp:
Feb 15, 2021, 3:08:52 PM (5 years ago)
Author:
Alexey Shvayka
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/JavaScriptCore:

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:
  • 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.

  • 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:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/PutPropertySlot.h

    r270764 r272885  
    3939    enum Type : uint8_t { Uncachable, ExistingProperty, NewProperty, SetterProperty, CustomValue, CustomAccessor };
    4040    enum Context { UnknownContext, PutById, PutByIdEval };
    41     using PutValueFunc = bool (*)(JSGlobalObject*, EncodedJSValue thisObject, EncodedJSValue value);
    42     using PutValueFuncWithPtr = bool (*)(JSGlobalObject*, EncodedJSValue thisObject, EncodedJSValue value, void*);
     41    using PutValueFunc = JSC::PutValueFunc;
     42    using PutValueFuncWithPtr = JSC::PutValueFuncWithPtr;
    4343
    4444    PutPropertySlot(JSValue thisValue, bool isStrictMode = false, Context context = UnknownContext, bool isInitialization = false)
Note: See TracChangeset for help on using the changeset viewer.