Changeset 196836 in webkit


Ignore:
Timestamp:
Feb 19, 2016 2:56:31 PM (8 years ago)
Author:
sbarati@apple.com
Message:

[ES6] Implement Proxy.Call?
https://bugs.webkit.org/show_bug.cgi?id=154425

Reviewed by Mark Lam.

This patch is a straight forward implementation of
Proxy.Call? with respect to section 9.5.12
of the ECMAScript spec.
https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist

  • runtime/ProxyObject.cpp:

(JSC::ProxyObject::finishCreation):
(JSC::performProxyGet):
(JSC::ProxyObject::performInternalMethodGetOwnProperty):
(JSC::ProxyObject::performHasProperty):
(JSC::ProxyObject::getOwnPropertySlotByIndex):
(JSC::performProxyCall):
(JSC::ProxyObject::getCallData):
(JSC::ProxyObject::visitChildren):

  • runtime/ProxyObject.h:

(JSC::ProxyObject::create):

  • tests/es6.yaml:
  • tests/stress/proxy-call.js: Added.

(assert):
(throw.new.Error.let.target):
(throw.new.Error.let.handler.apply):
(throw.new.Error):
(assert.let.target):
(assert.let.handler.get apply):
(let.target):
(let.handler.apply):
(i.catch):
(assert.let.handler.apply):

Location:
trunk/Source/JavaScriptCore
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r196812 r196836  
     12016-02-19  Saam Barati  <sbarati@apple.com>
     2
     3        [ES6] Implement Proxy.[[Call]]
     4        https://bugs.webkit.org/show_bug.cgi?id=154425
     5
     6        Reviewed by Mark Lam.
     7
     8        This patch is a straight forward implementation of
     9        Proxy.[[Call]] with respect to section 9.5.12
     10        of the ECMAScript spec.
     11        https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist
     12
     13        * runtime/ProxyObject.cpp:
     14        (JSC::ProxyObject::finishCreation):
     15        (JSC::performProxyGet):
     16        (JSC::ProxyObject::performInternalMethodGetOwnProperty):
     17        (JSC::ProxyObject::performHasProperty):
     18        (JSC::ProxyObject::getOwnPropertySlotByIndex):
     19        (JSC::performProxyCall):
     20        (JSC::ProxyObject::getCallData):
     21        (JSC::ProxyObject::visitChildren):
     22        * runtime/ProxyObject.h:
     23        (JSC::ProxyObject::create):
     24        * tests/es6.yaml:
     25        * tests/stress/proxy-call.js: Added.
     26        (assert):
     27        (throw.new.Error.let.target):
     28        (throw.new.Error.let.handler.apply):
     29        (throw.new.Error):
     30        (assert.let.target):
     31        (assert.let.handler.get apply):
     32        (let.target):
     33        (let.handler.apply):
     34        (i.catch):
     35        (assert.let.handler.apply):
     36
    1372016-02-19  Csaba Osztrogonác  <ossy@webkit.org>
    238
  • trunk/Source/JavaScriptCore/runtime/ProxyObject.cpp

    r196789 r196836  
    6666    }
    6767
    68     m_target.set(vm, this, jsCast<JSObject*>(target));
     68    CallData ignored;
     69    JSObject* targetAsObject = jsCast<JSObject*>(target);
     70    m_isCallable = targetAsObject->methodTable(vm)->getCallData(targetAsObject, ignored) != CallTypeNone;
     71
     72    m_target.set(vm, this, targetAsObject);
    6973    m_handler.set(vm, this, handler);
    7074}
     
    106110    arguments.append(target);
    107111    arguments.append(identifierToSafePublicJSValue(vm, Identifier::fromUid(&vm, propertyName.uid())));
    108     if (exec->hadException())
    109         return JSValue::encode(jsUndefined());
    110112    arguments.append(thisObject);
    111113    JSValue trapResult = call(exec, getHandler, callType, callData, handler, arguments);
     
    153155    arguments.append(target);
    154156    arguments.append(identifierToSafePublicJSValue(vm, Identifier::fromUid(&vm, propertyName.uid())));
    155     if (exec->hadException())
    156         return false;
    157157    JSValue trapResult = call(exec, getOwnPropertyDescriptorMethod, callType, callData, handler, arguments);
    158158    if (exec->hadException())
     
    235235    arguments.append(target);
    236236    arguments.append(identifierToSafePublicJSValue(vm, Identifier::fromUid(&vm, propertyName.uid())));
    237     if (exec->hadException())
    238         return false;
    239237    JSValue trapResult = call(exec, hasMethod, callType, callData, handler, arguments);
    240238    if (exec->hadException())
     
    299297}
    300298
     299static EncodedJSValue JSC_HOST_CALL performProxyCall(ExecState* exec)
     300{
     301    VM& vm = exec->vm();
     302    ProxyObject* proxy = jsCast<ProxyObject*>(exec->callee());
     303    JSValue handlerValue = proxy->handler();
     304    if (handlerValue.isNull())
     305        return throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object."));
     306
     307    JSObject* handler = jsCast<JSObject*>(handlerValue);
     308    CallData callData;
     309    CallType callType;
     310    JSValue applyMethod = handler->getMethod(exec, callData, callType, makeIdentifier(vm, "apply"), ASCIILiteral("'apply' property of a Proxy's handler should be callable."));
     311    if (exec->hadException())
     312        return JSValue::encode(jsUndefined());
     313    JSObject* target = proxy->target();
     314    if (applyMethod.isUndefined()) {
     315        CallData callData;
     316        CallType callType = target->methodTable(vm)->getCallData(target, callData);
     317        RELEASE_ASSERT(callType != CallTypeNone);
     318        return JSValue::encode(call(exec, target, callType, callData, exec->thisValue(), ArgList(exec)));
     319    }
     320
     321    JSArray* argArray = constructArray(exec, static_cast<ArrayAllocationProfile*>(nullptr), ArgList(exec));
     322    if (exec->hadException())
     323        return JSValue::encode(jsUndefined());
     324    MarkedArgumentBuffer arguments;
     325    arguments.append(target);
     326    arguments.append(exec->thisValue());
     327    arguments.append(argArray);
     328    return JSValue::encode(call(exec, applyMethod, callType, callData, handler, arguments));
     329}
     330
     331CallType ProxyObject::getCallData(JSCell* cell, CallData& callData)
     332{
     333    ProxyObject* proxy = jsCast<ProxyObject*>(cell);
     334    if (!proxy->m_isCallable) {
     335        callData.js.functionExecutable = nullptr;
     336        callData.js.scope = nullptr;
     337        return CallTypeNone;
     338    }
     339
     340    callData.native.function = performProxyCall;
     341    return CallTypeHost;
     342}
     343
    301344void ProxyObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
    302345{
  • trunk/Source/JavaScriptCore/runtime/ProxyObject.h

    r196789 r196836  
    3636    typedef JSNonFinalObject Base;
    3737
    38     const static unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
     38    const static unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | TypeOfShouldCallGetCallData;
    3939
    4040    static ProxyObject* create(ExecState* exec, Structure* structure, JSValue target, JSValue handler)
     
    6262    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    6363    static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
     64    static CallType getCallData(JSCell*, CallData&);
    6465    static void visitChildren(JSCell*, SlotVisitor&);
    6566
     
    7071    WriteBarrier<JSObject> m_target;
    7172    WriteBarrier<Unknown> m_handler;
     73    bool m_isCallable : 1;
    7274};
    7375
  • trunk/Source/JavaScriptCore/tests/es6.yaml

    r196789 r196836  
    908908  cmd: runES6 :fail
    909909- path: es6/Proxy_apply_handler.js
    910   cmd: runES6 :fail
     910  cmd: runES6 :normal
    911911- path: es6/Proxy_Array.isArray_support.js
    912912  cmd: runES6 :fail
     
    976976  cmd: runES6 :normal
    977977- path: es6/Proxy_internal_get_calls_Function.prototype.bind.js
    978   cmd: runES6 :fail
     978  cmd: runES6 :normal
    979979- path: es6/Proxy_internal_get_calls_HasBinding.js
    980980  cmd: runES6 :normal
     
    10221022  cmd: runES6 :fail
    10231023- path: es6/Proxy_internal_getOwnPropertyDescriptor_calls_Function.prototype.bind.js
    1024   cmd: runES6 :fail
     1024  cmd: runES6 :normal
    10251025- path: es6/Proxy_internal_getOwnPropertyDescriptor_calls_Object.assign.js
    10261026  cmd: runES6 :fail
Note: See TracChangeset for help on using the changeset viewer.