Repository navigation
Commit a5cadca
committed
[JSC] OrdinarySet should invoke custom [[Set]] methods
https://bugs.webkit.org/show_bug.cgi?id=217916
Reviewed by Yusuke Suzuki.
JSTests:
* microbenchmarks/put-slow-no-cache-array.js: Added.
* microbenchmarks/put-slow-no-cache-function.js: Added.
* microbenchmarks/put-slow-no-cache-js-proxy.js: Added.
* microbenchmarks/put-slow-no-cache-long-prototype-chain.js: Added.
* microbenchmarks/put-slow-no-cache.js: Added.
* microbenchmarks/reflect-set-with-receiver.js: Added.
* stress/custom-get-set-proto-chain-put.js:
* stress/module-namespace-access-set-fails.js: Added.
* stress/put-non-reified-static-accessor-or-custom.js: Added.
* stress/put-non-reified-static-function-or-custom.js: Added.
* stress/put-to-primitive-non-reified-static-custom.js: Added.
* stress/put-to-primitive.js: Added.
* stress/put-to-proto-chain-overrides-put.js: Added.
* stress/typed-array-canonical-numeric-index-string-set.js: Added.
LayoutTests/imported/w3c:
* web-platform-tests/WebIDL/ecmascript-binding/interface-object-set-receiver-expected.txt: Added.
* web-platform-tests/WebIDL/ecmascript-binding/interface-object-set-receiver.html: Added.
* web-platform-tests/WebIDL/ecmascript-binding/interface-prototype-constructor-set-receiver-expected.txt:
* web-platform-tests/WebIDL/ecmascript-binding/interface-prototype-constructor-set-receiver.html:
Source/JavaScriptCore:
This patch fixes putInlineSlow() to handle special properties (like JSFunction's "name"
and JSArray's "length") in prototype chain. When such property is encountered, prototype
chain traversal is stopped; if it's read-only, a TypeError is thrown in strict mode.
This change adds OverridesPut out of line type info flag, and utilizes it in putInlineSlow()
to invoke overriden methods. While this approach requires put() methods to be aware of
altered receivers, it renders several benefits:
1. put() method can be used for both "real" [[Set]] overrides and special properties,
with its return value remaining `bool`;
2. it is simpler, faster, and more predictable than calling [[GetOwnProperty]] in
putInlineSlow() or adding defineOwnPropertyViaPut() to the method table.
Removes ordinarySetSlow() for non-index properties, which didn't invoke some [[Set]]
methods as well. Instead, definePropertyOnReceiver() is introduced for altered receivers,
which performs correctly when reached because:
1. all special properties were already handled (unless it's Reflect.set);
2. performing putDirectInternal() is unobservable (unless ProxyObject was seen);
3. putDirectInternal() now fully implements property definition of OrdinarySet [1];
4. put() override is required if a spec defines custom [[DefineOwnProperty]].
Since indexed puts handle overrides / altered receivers quite differently, they will
be fixed in a follow-up, completely removing ordinarySetSlow().
Also, by merging putEntry() / putToPrimitive() into putInlineSlow() and introducing
putInlineFastReplacingStaticPropertyIfNeeded() helper, this patch fixes a few bugs:
1. Direct [[Set]] to non-reified static property now preserves its attributes when replacing [[Value]].
2. Prototype chain [[Set]] to non-reified static property now throws if receiver is non-extensible.
3. Non-reified static writable property now shadows read-only one that is further in prototype chain.
4. Non-reified static properties in prototype chain of a primitive are now considered.
Fixes a few issues that were previously unobservable:
1. PropertyAttribute::CustomValue is now unset when a setter-less property is reassigned.
2. uint64_t putByIndexInline() now calls put() via method table like uint32_t counterpart.
Other notable refactors:
1. Inlines callCustomSetter(), dropping weird TriState return value.
2. Simplifies initialization of StringPrototype.
3. Simplifies isThisValueAltered() to pointer comparisons at non-JSProxy call sites.
4. Removes doPutPropertySecurityCheck() methods as the same checks are performed by put() methods.
5. Removes prototypeChainMayInterceptStoreTo(), which pretty much duplicated canPerformFastPutInline().
6. Removes dummy JSArrayBufferView::put() method.
7. Removes now unused lookupPut().
Aligns JSC with V8 and SpiderMonkey.
This patch carefully preserves the current behavior of Reflect.set with CustomValue
and prototype chain [[Set]] to a JSCallbackObject / legacy platform object.
This change is performance-neutral on /put/ microbenchmarks as it doesn't affect
caching, only the slow path. Reflect.set with JSFinalObject receiver is 130% faster.
putInlineSlow() microbenchmarks progress by 4-18%.
[1]: https://tc39.es/ecma262/#sec-ordinarysetwithowndescriptor (step 3)
* API/JSCallbackObject.h:
* API/JSCallbackObjectFunctions.h:
(JSC::JSCallbackObject<Parent>::put):
* API/tests/testapiScripts/testapi.js:
* debugger/DebuggerScope.h:
* runtime/ClassInfo.h:
* runtime/ClonedArguments.h:
* runtime/CustomGetterSetter.cpp:
(JSC::callCustomSetter): Deleted.
* runtime/CustomGetterSetter.h:
* runtime/ErrorConstructor.h:
* runtime/ErrorInstance.h:
* runtime/GenericArguments.h:
* runtime/GenericArgumentsInlines.h:
(JSC::GenericArguments<Type>::put):
* runtime/GetterSetter.h:
* runtime/JSArray.cpp:
(JSC::JSArray::put):
* runtime/JSArray.h:
* runtime/JSArrayBufferView.cpp:
(JSC::JSArrayBufferView::put): Deleted.
* runtime/JSArrayBufferView.h:
* runtime/JSCJSValue.cpp:
(JSC::JSValue::putToPrimitive):
* runtime/JSCell.cpp:
(JSC::JSCell::doPutPropertySecurityCheck): Deleted.
* runtime/JSCell.h:
* runtime/JSFunction.cpp:
(JSC::JSFunction::put):
* runtime/JSFunction.h:
* runtime/JSGenericTypedArrayView.h:
* runtime/JSGlobalLexicalEnvironment.h:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::put):
* runtime/JSGlobalObject.h:
* runtime/JSLexicalEnvironment.h:
* runtime/JSModuleEnvironment.h:
* runtime/JSModuleNamespaceObject.h:
* runtime/JSObject.cpp:
(JSC::JSObject::getOwnPropertySlot):
(JSC::JSObject::putInlineSlow):
(JSC::definePropertyOnReceiverSlow):
(JSC::JSObject::definePropertyOnReceiver):
(JSC::JSObject::putInlineFastReplacingStaticPropertyIfNeeded):
(JSC::JSObject::doPutPropertySecurityCheck): Deleted.
(JSC::JSObject::prototypeChainMayInterceptStoreTo): Deleted.
* runtime/JSObject.h:
(JSC::JSObject::putByIndexInline):
(JSC::JSObject::hasNonReifiedStaticProperties):
(JSC::JSObject::getOwnPropertySlot):
(JSC::JSObject::putDirect):
(JSC::JSObject::doPutPropertySecurityCheck): Deleted.
* runtime/JSObjectInlines.h:
(JSC::JSObject::canPerformFastPutInlineExcludingProto):
(JSC::JSObject::putInlineForJSObject):
(JSC::JSObject::putInlineFast):
(JSC::JSObject::putDirectInternal):
* runtime/JSProxy.h:
* runtime/JSTypeInfo.h:
(JSC::TypeInfo::hasStaticPropertyTable const):
(JSC::TypeInfo::overridesPut const):
(JSC::TypeInfo::getOwnPropertySlotMayBeWrongAboutDontEnum const):
(JSC::TypeInfo::hasPutPropertySecurityCheck const): Deleted.
* runtime/Lookup.h:
(JSC::putEntry): Deleted.
(JSC::lookupPut): Deleted.
* runtime/PropertySlot.h:
* runtime/ProxyObject.cpp:
(JSC::ProxyObject::put):
* runtime/ProxyObject.h:
* runtime/PutPropertySlot.h:
(JSC::PutPropertySlot::PutPropertySlot):
(JSC::PutPropertySlot::context const):
(JSC::PutPropertySlot::isTaintedByOpaqueObject const):
(JSC::PutPropertySlot::setIsTaintedByOpaqueObject):
* runtime/ReflectObject.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
* runtime/RegExpObject.cpp:
(JSC::RegExpObject::put):
* runtime/RegExpObject.h:
* runtime/StringObject.cpp:
(JSC::StringObject::put):
* runtime/StringObject.h:
* runtime/StringPrototype.cpp:
(JSC::StringPrototype::finishCreation):
(JSC::StringPrototype::create):
* runtime/StringPrototype.h:
* runtime/Structure.cpp:
(JSC::Structure::validateFlags):
* runtime/Structure.h:
(JSC::Structure::hasNonReifiedStaticProperties const):
* tools/JSDollarVM.cpp:
Source/WebCore:
Fixes:
1. Legacy platform object's [[Set]] now guards against altered receiver [1].
(aligns with Blink).
2. Direct [[Set]] to window.%Interface% constructor now preserves DontEnum attribute [2].
(aligns with Blink and Gecko).
3. Cross-origin non-index put() now throws SecurityError instead of silently failing [3].
(aligns with Blink and Gecko).
Refactors:
1. Simplifies cross-origin JSDOMWindow::put(), aligning it with JSLocation::put().
2. Replaces lookupPut() with direct setter call in JSRemoteDOMWindow::put().
3. Removes now unused doPutPropertySecurityCheck() methods.
Tests: js/dom/script-tests/reflect-set-onto-dom.js
imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/interface-object-set-receiver.html
http/tests/security/cross-frame-access-object-getPrototypeOf-in-put.html
[1] https://heycam.github.io/webidl/#legacy-platform-object-set (step 1)
[2] https://heycam.github.io/webidl/#define-the-global-property-references (step 3.1.3)
[3] https://html.spec.whatwg.org/multipage/browsers.html#crossoriginset-(-o,-p,-v,-receiver-) (step 4)
* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::JSDOMWindow::put):
(WebCore::JSDOMWindow::doPutPropertySecurityCheck): Deleted.
* bindings/js/JSLocationCustom.cpp:
(WebCore::JSLocation::doPutPropertySecurityCheck): Deleted.
* bindings/js/JSRemoteDOMWindowCustom.cpp:
(WebCore::JSRemoteDOMWindow::put):
* bindings/scripts/CodeGeneratorJS.pm:
(GeneratePut):
(GenerateHeader):
* bindings/scripts/test/JS/*: Updated.
* bridge/objc/objc_runtime.h:
* bridge/runtime_array.h:
* bridge/runtime_object.h:
Source/WebKit:
* WebProcess/Plugins/Netscape/JSNPObject.h:
LayoutTests:
* http/tests/security/cross-frame-access-object-getPrototypeOf-in-put-expected.txt:
* http/tests/security/cross-frame-access-object-getPrototypeOf-in-put.html:
* js/dom/reflect-set-onto-dom-expected.txt:
* js/dom/script-tests/reflect-set-onto-dom.js:
Canonical link: https://commits.webkit.org/237028@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@276592 268f45cc-cd09-0410-ab3c-d52691b4dbfc1 parent 2bdcfad commit a5cadca
117 files changed
Lines changed: 1355 additions & 460 deletions
File tree
- JSTests
- microbenchmarks
- stress
- LayoutTests
- http/tests/security
- imported/w3c
- web-platform-tests/WebIDL/ecmascript-binding
- js/dom
- script-tests
- Source
- JavaScriptCore
- API
- tests/testapiScripts
- debugger
- runtime
- tools
- WebCore
- bindings
- js
- scripts
- test/JS
- bridge
- objc
- WebKit
- WebProcess/Plugins/Netscape
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
1 | 23 | | |
2 | 24 | | |
3 | 25 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
40 | | - | |
41 | | - | |
| 40 | + | |
| 41 | + | |
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
| |||
85 | 85 | | |
86 | 86 | | |
87 | 87 | | |
| 88 | + | |
88 | 89 | | |
89 | 90 | | |
90 | 91 | | |
91 | 92 | | |
92 | | - | |
93 | 93 | | |
94 | | - | |
| 94 | + | |
95 | 95 | | |
96 | 96 | | |
97 | 97 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
0 commit comments