[ES6] Reflect.set with receiver
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Mar 2016 13:59:43 +0000 (13:59 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Mar 2016 13:59:43 +0000 (13:59 +0000)
commitce9ab15b19e18c1e82312e3d9535fc5633890464
treec4d0ffd3d02f69a6fe6b883f3d62f240c8d33c16
parentad1f6e548084bf12cfc35367b77c95bdf3147819
[ES6] Reflect.set with receiver
https://bugs.webkit.org/show_bug.cgi?id=155294

Reviewed by Saam Barati.

Source/JavaScriptCore:

This patch introduces the receiver parameter support for Reflect.set.
Reflect.set can alter the receiver with arbitrary values.
Each property descriptor uses the receiver in [[Set]].

1) In the accessor descriptor case, the receiver is used as |this| value for setter calls.
2) In the data descriptor case, the actual property will be set onto the receiver objects.

The current put operation does not support the receiver that is different from the base object.
In particular, (2) case is not supported.
The naive implementation adds one more [[GetOwnProperty]] for the receiver per [[Set]] (9.1.9.1-4-c [1]), and it is unacceptable.
To keep the fast path efficiently, we fall back to the slow but generic implementation (ordinarySetSlow)
only when the receiver is altered.

We need not to change any JIT part, because the JS code cannot alter the receiver without Reflect.set.
The property accesses generated by the JIT code always have the receiver that is the same to the base object.
ProxyObject can alter the receiver, but this situation has no problem because ProxyObject disables Inline Caching.
NOTE: Generating Inline Caching for JSProxy (that is used for the Window proxy) is already disabled before this change.

[1]: https://tc39.github.io/ecma262/#sec-ordinaryset

* jsc.cpp:
(functionCreateProxy):
* runtime/GenericArgumentsInlines.h:
(JSC::GenericArguments<Type>::put):
* runtime/JSArray.cpp:
(JSC::JSArray::put):
* runtime/JSArrayBuffer.cpp:
(JSC::JSArrayBuffer::put):
* runtime/JSArrayBufferView.cpp:
(JSC::JSArrayBufferView::put):
* runtime/JSCJSValue.h:
* runtime/JSCJSValueInlines.h:
(JSC::isThisValueAltered):
* runtime/JSDataView.cpp:
(JSC::JSDataView::put):
* runtime/JSFunction.cpp:
(JSC::JSFunction::put):
* runtime/JSGenericTypedArrayViewInlines.h:
(JSC::JSGenericTypedArrayView<Adaptor>::put):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::put):
* runtime/JSObject.cpp:
(JSC::ordinarySetSlow):
(JSC::JSObject::putInlineSlow):
* runtime/JSObject.h:
* runtime/JSObjectInlines.h:
(JSC::JSObject::putInline):
* runtime/JSProxy.h:
(JSC::JSProxy::createStructure):
* runtime/Lookup.h:
(JSC::putEntry):
* runtime/PropertySlot.h:
* runtime/ProxyObject.cpp:
(JSC::ProxyObject::put):
* runtime/PutPropertySlot.h:
(JSC::PutPropertySlot::PutPropertySlot):
(JSC::PutPropertySlot::isCacheablePut):
(JSC::PutPropertySlot::isCacheableSetter):
(JSC::PutPropertySlot::isCacheableCustom):
(JSC::PutPropertySlot::isCustomAccessor):
(JSC::PutPropertySlot::disableCaching):
(JSC::PutPropertySlot::isCacheable):
* runtime/ReflectObject.cpp:
(JSC::reflectObjectSet):
* runtime/RegExpObject.cpp:
(JSC::RegExpObject::put):
(JSC::reject): Deleted.
* runtime/StringObject.cpp:
(JSC::StringObject::put):
* tests/es6.yaml:
* tests/stress/ordinary-set-exceptions.js: Added.
(shouldBe):
(shouldThrow):
(shouldThrow.set get var):
* tests/stress/proxy-set.js:
* tests/stress/reflect-set-proxy-set.js: Copied from Source/JavaScriptCore/tests/stress/proxy-set.js.
(shouldBe):
(unreachable):
(assert):
(throw.new.Error.let.handler.set 45):
(throw.new.Error):
(let.target.set x):
(let.target.get x):
(set let):
* tests/stress/reflect-set-receiver-proxy-set.js: Added.
(shouldBe):
(unreachable):
(assert):
(let.handler.set 45):
(catch):
(let.target.set x):
(let.target.get x):
(set let):
* tests/stress/reflect-set-with-global-proxy.js: Added.
(shouldBe):
(unreachable):
(get shouldBe):
(set shouldBe):
(set test1):
(set test2):
(set test3):
* tests/stress/reflect-set.js:
(shouldThrow):
(unreachable):
(get shouldBe):
(set shouldBe):
(receiverTestIndexed):
(set get Uint8Array):
(receiverCase): Deleted.
(proxyCase): Deleted.
(stringObjectCase.set get shouldBe): Deleted.
(regExpLastIndex): Deleted.

LayoutTests:

Currently, putDelegate (JSLocation is special case) and CustomIndexedSetter work as special setters.

* js/dom/reflect-set-onto-dom-expected.txt:
* js/dom/script-tests/reflect-set-onto-dom.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@198270 268f45cc-cd09-0410-ab3c-d52691b4dbfc
33 files changed:
LayoutTests/ChangeLog
LayoutTests/js/dom/reflect-set-onto-dom-expected.txt
LayoutTests/js/dom/script-tests/reflect-set-onto-dom.js
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/jsc.cpp
Source/JavaScriptCore/runtime/GenericArgumentsInlines.h
Source/JavaScriptCore/runtime/JSArray.cpp
Source/JavaScriptCore/runtime/JSArrayBuffer.cpp
Source/JavaScriptCore/runtime/JSArrayBufferView.cpp
Source/JavaScriptCore/runtime/JSCJSValue.h
Source/JavaScriptCore/runtime/JSCJSValueInlines.h
Source/JavaScriptCore/runtime/JSDataView.cpp
Source/JavaScriptCore/runtime/JSFunction.cpp
Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSObject.cpp
Source/JavaScriptCore/runtime/JSObject.h
Source/JavaScriptCore/runtime/JSObjectInlines.h
Source/JavaScriptCore/runtime/JSProxy.h
Source/JavaScriptCore/runtime/Lookup.h
Source/JavaScriptCore/runtime/PropertySlot.h
Source/JavaScriptCore/runtime/ProxyObject.cpp
Source/JavaScriptCore/runtime/PutPropertySlot.h
Source/JavaScriptCore/runtime/ReflectObject.cpp
Source/JavaScriptCore/runtime/RegExpObject.cpp
Source/JavaScriptCore/runtime/StringObject.cpp
Source/JavaScriptCore/tests/es6.yaml
Source/JavaScriptCore/tests/stress/ordinary-set-exceptions.js [new file with mode: 0644]
Source/JavaScriptCore/tests/stress/proxy-set.js
Source/JavaScriptCore/tests/stress/reflect-set-proxy-set.js [new file with mode: 0644]
Source/JavaScriptCore/tests/stress/reflect-set-receiver-proxy-set.js [new file with mode: 0644]
Source/JavaScriptCore/tests/stress/reflect-set-with-global-proxy.js [new file with mode: 0644]
Source/JavaScriptCore/tests/stress/reflect-set.js