Ignore:
Timestamp:
Feb 24, 2016, 12:43:21 PM (9 years ago)
Author:
[email protected]
Message:

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

Reviewed by Mark Lam.

This patch implements Proxy.Delete with respect to section 9.5.10 of the ECMAScript spec.
https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-delete-p

  • runtime/ProxyObject.cpp:

(JSC::ProxyObject::getConstructData):
(JSC::ProxyObject::performDelete):
(JSC::ProxyObject::deleteProperty):
(JSC::ProxyObject::deletePropertyByIndex):

  • runtime/ProxyObject.h:
  • tests/es6.yaml:
  • tests/stress/proxy-delete.js: Added.

(assert):
(throw.new.Error.let.handler.get deleteProperty):
(throw.new.Error):
(assert.let.handler.deleteProperty):
(let.handler.deleteProperty):

Location:
trunk/Source/JavaScriptCore/runtime
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/ProxyObject.cpp

    r196868 r197042  
    406406}
    407407
     408template <typename DefaultDeleteFunction>
     409bool ProxyObject::performDelete(ExecState* exec, PropertyName propertyName, DefaultDeleteFunction defaultDeleteFunction)
     410{
     411    VM& vm = exec->vm();
     412    JSValue handlerValue = this->handler();
     413    if (handlerValue.isNull()) {
     414        throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object."));
     415        return false;
     416    }
     417
     418    JSObject* handler = jsCast<JSObject*>(handlerValue);
     419    CallData callData;
     420    CallType callType;
     421    JSValue deletePropertyMethod = handler->getMethod(exec, callData, callType, makeIdentifier(vm, "deleteProperty"), ASCIILiteral("'deleteProperty' property of a Proxy's handler should be callable."));
     422    if (exec->hadException())
     423        return false;
     424    JSObject* target = this->target();
     425    if (deletePropertyMethod.isUndefined())
     426        return defaultDeleteFunction();
     427
     428    MarkedArgumentBuffer arguments;
     429    arguments.append(target);
     430    arguments.append(identifierToSafePublicJSValue(vm, Identifier::fromUid(&vm, propertyName.uid())));
     431    JSValue trapResult = call(exec, deletePropertyMethod, callType, callData, handler, arguments);
     432    if (exec->hadException())
     433        return false;
     434
     435    bool trapResultAsBool = trapResult.toBoolean(exec);
     436    if (exec->hadException())
     437        return false;
     438
     439    if (!trapResultAsBool)
     440        return false;
     441
     442    PropertyDescriptor descriptor;
     443    if (target->getOwnPropertyDescriptor(exec, propertyName, descriptor)) {
     444        if (!descriptor.configurable()) {
     445            throwVMTypeError(exec, ASCIILiteral("Proxy handler's 'deleteProperty' method should return false when the target's property is not configurable."));
     446            return false;
     447        }
     448    }
     449
     450    if (exec->hadException())
     451        return false;
     452
     453    return true;
     454}
     455
     456bool ProxyObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
     457{
     458    ProxyObject* thisObject = jsCast<ProxyObject*>(cell);
     459    auto defaultDelete = [&] () -> bool {
     460        JSObject* target = jsCast<JSObject*>(thisObject->target());
     461        return target->methodTable(exec->vm())->deleteProperty(target, exec, propertyName);
     462    };
     463    return thisObject->performDelete(exec, propertyName, defaultDelete);
     464}
     465
     466bool ProxyObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned propertyName)
     467{
     468    ProxyObject* thisObject = jsCast<ProxyObject*>(cell);
     469    Identifier ident = Identifier::from(exec, propertyName);
     470    if (exec->hadException())
     471        return false;
     472    auto defaultDelete = [&] () -> bool {
     473        JSObject* target = jsCast<JSObject*>(thisObject->target());
     474        return target->methodTable(exec->vm())->deletePropertyByIndex(target, exec, propertyName);
     475    };
     476    return thisObject->performDelete(exec, ident.impl(), defaultDelete);
     477}
     478
    408479} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/ProxyObject.h

    r196868 r197042  
    6464    static CallType getCallData(JSCell*, CallData&);
    6565    static ConstructType getConstructData(JSCell*, ConstructData&);
     66    static bool deleteProperty(JSCell*, ExecState*, PropertyName);
     67    static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
    6668    static void visitChildren(JSCell*, SlotVisitor&);
    6769
     
    6971    bool performInternalMethodGetOwnProperty(ExecState*, PropertyName, PropertySlot&);
    7072    bool performHasProperty(ExecState*, PropertyName, PropertySlot&);
     73    template <typename DefaultDeleteFunction>
     74    bool performDelete(ExecState*, PropertyName, DefaultDeleteFunction);
    7175
    7276    WriteBarrier<JSObject> m_target;
Note: See TracChangeset for help on using the changeset viewer.