Ignore:
Timestamp:
Mar 16, 2016, 6:59:43 AM (9 years ago)
Author:
Yusuke Suzuki
Message:

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

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/jsc.cpp

    r198023 r198270  
    12301230        return JSValue::encode(jsUndefined());
    12311231    JSObject* jsTarget = asObject(target.asCell());
    1232     Structure* structure = JSProxy::createStructure(exec->vm(), exec->lexicalGlobalObject(), jsTarget->getPrototypeDirect());
     1232    Structure* structure = JSProxy::createStructure(exec->vm(), exec->lexicalGlobalObject(), jsTarget->getPrototypeDirect(), ImpureProxyType);
    12331233    JSProxy* proxy = JSProxy::create(exec->vm(), structure, jsTarget);
    12341234    return JSValue::encode(proxy);
Note: See TracChangeset for help on using the changeset viewer.