Changeset 197732 in webkit


Ignore:
Timestamp:
Mar 7, 2016, 11:16:21 PM (9 years ago)
Author:
sbarati@apple.com
Message:

[ES6] Implement revocable proxies
https://bugs.webkit.org/show_bug.cgi?id=154321

Reviewed by Mark Lam.

This patch is a straight forward implementation of Proxy.revocable
with respect to section 26.2.2.1 of the ECMAScript spec.
https://tc39.github.io/ecma262/#sec-proxy.revocable

This patch also fixes a bug in Proxy where we
were incorrectly caching "in", i.e, "x" in proxy.
We should never blatantly cache this because caching is observable
behavior by users of the language. We could come up with
a smarter caching scheme that caches only if the Proxy's
handler doesn't have a "has" property, i.e, we don't have
to call out to JS code. But for now, it's easiest to disable
caching.

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):

  • runtime/JSGlobalObject.h:

(JSC::JSGlobalObject::moduleRecordStructure):
(JSC::JSGlobalObject::moduleNamespaceObjectStructure):
(JSC::JSGlobalObject::proxyObjectStructure):
(JSC::JSGlobalObject::proxyRevokeStructure):
(JSC::JSGlobalObject::wasmModuleStructure):

  • runtime/ProxyConstructor.cpp:

(JSC::ProxyConstructor::create):
(JSC::ProxyConstructor::ProxyConstructor):
(JSC::makeRevocableProxy):
(JSC::proxyRevocableConstructorThrowError):
(JSC::ProxyConstructor::finishCreation):
(JSC::constructProxyObject):

  • runtime/ProxyConstructor.h:

(JSC::ProxyConstructor::createStructure):

  • runtime/ProxyObject.cpp:

(JSC::ProxyObject::finishCreation):
(JSC::performProxyGet):
(JSC::ProxyObject::performInternalMethodGetOwnProperty):
(JSC::ProxyObject::performHasProperty):
(JSC::ProxyObject::performPut):
(JSC::performProxyCall):
(JSC::performProxyConstruct):
(JSC::ProxyObject::performDelete):
(JSC::ProxyObject::performPreventExtensions):
(JSC::ProxyObject::performIsExtensible):
(JSC::ProxyObject::performDefineOwnProperty):
(JSC::ProxyObject::performGetOwnPropertyNames):
(JSC::ProxyObject::performSetPrototype):
(JSC::ProxyObject::performGetPrototype):
(JSC::ProxyObject::getPrototype):
(JSC::ProxyObject::revoke):
(JSC::ProxyObject::visitChildren):

  • runtime/ProxyObject.h:

(JSC::ProxyObject::create):

  • runtime/ProxyRevoke.cpp: Added.

(JSC::ProxyRevoke::create):
(JSC::ProxyRevoke::ProxyRevoke):
(JSC::ProxyRevoke::finishCreation):
(JSC::performProxyRevoke):
(JSC::ProxyRevoke::getCallData):
(JSC::ProxyRevoke::visitChildren):

  • runtime/ProxyRevoke.h: Added.

(JSC::ProxyRevoke::createStructure):
(JSC::ProxyRevoke::proxy):
(JSC::ProxyRevoke::setProxyToNull):

  • tests/stress/proxy-has-property.js:

(assert):
(assert.let.handler.has):
(assert.let.foo):

  • tests/stress/proxy-revoke.js: Added.

(assert):
(throw.new.Error.):
(throw.new.Error):
(callAllHandlers):
(shouldThrowNullHandler):
(allHandlersShouldThrow):
(i.let.trap.of.traps.trap.string_appeared_here.func):
(i.let.trap.of.traps.else.func):
(i.Proxy.revocable):

Location:
trunk/Source/JavaScriptCore
Files:
2 added
11 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r197489 r197732  
    765765    runtime/ProxyConstructor.cpp
    766766    runtime/ProxyObject.cpp
     767    runtime/ProxyRevoke.cpp
    767768    runtime/ReflectObject.cpp
    768769    runtime/RegExp.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r197731 r197732  
     12016-03-07  Saam barati  <sbarati@apple.com>
     2
     3        [ES6] Implement revocable proxies
     4        https://bugs.webkit.org/show_bug.cgi?id=154321
     5
     6        Reviewed by Mark Lam.
     7
     8        This patch is a straight forward implementation of Proxy.revocable
     9        with respect to section 26.2.2.1 of the ECMAScript spec.
     10        https://tc39.github.io/ecma262/#sec-proxy.revocable
     11
     12        This patch also fixes a bug in Proxy where we
     13        were incorrectly caching "in", i.e, `"x" in proxy`.
     14        We should never blatantly cache this because caching is observable
     15        behavior by users of the language. We could come up with
     16        a smarter caching scheme that caches only if the Proxy's
     17        handler doesn't have a "has" property, i.e, we don't have
     18        to call out to JS code. But for now, it's easiest to disable
     19        caching.
     20
     21        * CMakeLists.txt:
     22        * JavaScriptCore.xcodeproj/project.pbxproj:
     23        * runtime/JSGlobalObject.cpp:
     24        (JSC::JSGlobalObject::init):
     25        (JSC::JSGlobalObject::visitChildren):
     26        * runtime/JSGlobalObject.h:
     27        (JSC::JSGlobalObject::moduleRecordStructure):
     28        (JSC::JSGlobalObject::moduleNamespaceObjectStructure):
     29        (JSC::JSGlobalObject::proxyObjectStructure):
     30        (JSC::JSGlobalObject::proxyRevokeStructure):
     31        (JSC::JSGlobalObject::wasmModuleStructure):
     32        * runtime/ProxyConstructor.cpp:
     33        (JSC::ProxyConstructor::create):
     34        (JSC::ProxyConstructor::ProxyConstructor):
     35        (JSC::makeRevocableProxy):
     36        (JSC::proxyRevocableConstructorThrowError):
     37        (JSC::ProxyConstructor::finishCreation):
     38        (JSC::constructProxyObject):
     39        * runtime/ProxyConstructor.h:
     40        (JSC::ProxyConstructor::createStructure):
     41        * runtime/ProxyObject.cpp:
     42        (JSC::ProxyObject::finishCreation):
     43        (JSC::performProxyGet):
     44        (JSC::ProxyObject::performInternalMethodGetOwnProperty):
     45        (JSC::ProxyObject::performHasProperty):
     46        (JSC::ProxyObject::performPut):
     47        (JSC::performProxyCall):
     48        (JSC::performProxyConstruct):
     49        (JSC::ProxyObject::performDelete):
     50        (JSC::ProxyObject::performPreventExtensions):
     51        (JSC::ProxyObject::performIsExtensible):
     52        (JSC::ProxyObject::performDefineOwnProperty):
     53        (JSC::ProxyObject::performGetOwnPropertyNames):
     54        (JSC::ProxyObject::performSetPrototype):
     55        (JSC::ProxyObject::performGetPrototype):
     56        (JSC::ProxyObject::getPrototype):
     57        (JSC::ProxyObject::revoke):
     58        (JSC::ProxyObject::visitChildren):
     59        * runtime/ProxyObject.h:
     60        (JSC::ProxyObject::create):
     61        * runtime/ProxyRevoke.cpp: Added.
     62        (JSC::ProxyRevoke::create):
     63        (JSC::ProxyRevoke::ProxyRevoke):
     64        (JSC::ProxyRevoke::finishCreation):
     65        (JSC::performProxyRevoke):
     66        (JSC::ProxyRevoke::getCallData):
     67        (JSC::ProxyRevoke::visitChildren):
     68        * runtime/ProxyRevoke.h: Added.
     69        (JSC::ProxyRevoke::createStructure):
     70        (JSC::ProxyRevoke::proxy):
     71        (JSC::ProxyRevoke::setProxyToNull):
     72        * tests/stress/proxy-has-property.js:
     73        (assert):
     74        (assert.let.handler.has):
     75        (assert.let.foo):
     76        * tests/stress/proxy-revoke.js: Added.
     77        (assert):
     78        (throw.new.Error.):
     79        (throw.new.Error):
     80        (callAllHandlers):
     81        (shouldThrowNullHandler):
     82        (allHandlersShouldThrow):
     83        (i.let.trap.of.traps.trap.string_appeared_here.func):
     84        (i.let.trap.of.traps.else.func):
     85        (i.Proxy.revocable):
     86
    1872016-03-07  Csaba Osztrogonác  <ossy@webkit.org>
    288
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r197717 r197732  
    12701270                70ECA6081AFDBEA200449739 /* TemplateRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6031AFDBEA200449739 /* TemplateRegistry.h */; settings = {ATTRIBUTES = (Private, ); }; };
    12711271                70ECA6091AFDBEA200449739 /* TemplateRegistryKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6041AFDBEA200449739 /* TemplateRegistryKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1272                79160DBD1C8E3EC8008C085A /* ProxyRevoke.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79160DBB1C8E3EC8008C085A /* ProxyRevoke.cpp */; };
     1273                79160DBE1C8E3EC8008C085A /* ProxyRevoke.h in Headers */ = {isa = PBXBuildFile; fileRef = 79160DBC1C8E3EC8008C085A /* ProxyRevoke.h */; settings = {ATTRIBUTES = (Private, ); }; };
    12721274                792CB3491C4EED5C00D13AF3 /* PCToCodeOriginMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 792CB3471C4EED5C00D13AF3 /* PCToCodeOriginMap.cpp */; };
    12731275                792CB34A1C4EED5C00D13AF3 /* PCToCodeOriginMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 792CB3481C4EED5C00D13AF3 /* PCToCodeOriginMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    34293431                70ECA6031AFDBEA200449739 /* TemplateRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateRegistry.h; sourceTree = "<group>"; };
    34303432                70ECA6041AFDBEA200449739 /* TemplateRegistryKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateRegistryKey.h; sourceTree = "<group>"; };
     3433                79160DBB1C8E3EC8008C085A /* ProxyRevoke.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProxyRevoke.cpp; sourceTree = "<group>"; };
     3434                79160DBC1C8E3EC8008C085A /* ProxyRevoke.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProxyRevoke.h; sourceTree = "<group>"; };
    34313435                792CB3471C4EED5C00D13AF3 /* PCToCodeOriginMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCToCodeOriginMap.cpp; sourceTree = "<group>"; };
    34323436                792CB3481C4EED5C00D13AF3 /* PCToCodeOriginMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCToCodeOriginMap.h; sourceTree = "<group>"; };
     
    58565860                                79B00CBA1C6AB07E0088C65D /* ProxyObject.cpp */,
    58575861                                79B00CBB1C6AB07E0088C65D /* ProxyObject.h */,
     5862                                79160DBB1C8E3EC8008C085A /* ProxyRevoke.cpp */,
     5863                                79160DBC1C8E3EC8008C085A /* ProxyRevoke.h */,
    58585864                                0F5780A118FE1E98001E72D9 /* PureNaN.h */,
    58595865                                0F0CD4C015F1A6040032F1C0 /* PutDirectIndexMode.h */,
     
    69036909                                799EF7C41C56ED96002B0534 /* B3PCToOriginMap.h in Headers */,
    69046910                                79B00CBF1C6AB07E0088C65D /* ProxyObject.h in Headers */,
     6911                                79160DBE1C8E3EC8008C085A /* ProxyRevoke.h in Headers */,
    69056912                                792CB34A1C4EED5C00D13AF3 /* PCToCodeOriginMap.h in Headers */,
    69066913                                79CFC6F01C33B10000C768EA /* LLIntPCRanges.h in Headers */,
     
    91639170                                0F338E0B1BF0276C0013C88F /* B3Compilation.cpp in Sources */,
    91649171                                14469DE0107EC7E700650446 /* NativeErrorConstructor.cpp in Sources */,
     9172                                79160DBD1C8E3EC8008C085A /* ProxyRevoke.cpp in Sources */,
    91659173                                14469DE1107EC7E700650446 /* NativeErrorPrototype.cpp in Sources */,
    91669174                                E33E8D201B9013DE00346B52 /* NativeStdFunctionCell.cpp in Sources */,
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r197648 r197732  
    131131#include "ProxyConstructor.h"
    132132#include "ProxyObject.h"
     133#include "ProxyRevoke.h"
    133134#include "ReflectObject.h"
    134135#include "RegExpConstructor.h"
     
    371372    m_moduleNamespaceObjectStructure.set(vm, this, JSModuleNamespaceObject::createStructure(vm, this, jsNull()));
    372373    m_proxyObjectStructure.set(vm, this, ProxyObject::createStructure(vm, this, m_objectPrototype.get()));
     374    m_proxyRevokeStructure.set(vm, this, ProxyRevoke::createStructure(vm, this, m_functionPrototype.get()));
    373375   
    374376#if ENABLE(WEBASSEMBLY)
     
    912914    visitor.append(&thisObject->m_internalFunctionStructure);
    913915    visitor.append(&thisObject->m_proxyObjectStructure);
     916    visitor.append(&thisObject->m_proxyRevokeStructure);
    914917#if ENABLE(WEBASSEMBLY)
    915918    visitor.append(&thisObject->m_wasmModuleStructure);
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h

    r197648 r197732  
    283283    WriteBarrier<Structure> m_moduleNamespaceObjectStructure;
    284284    WriteBarrier<Structure> m_proxyObjectStructure;
     285    WriteBarrier<Structure> m_proxyRevokeStructure;
    285286#if ENABLE(WEBASSEMBLY)
    286287    WriteBarrier<Structure> m_wasmModuleStructure;
     
    536537    Structure* moduleNamespaceObjectStructure() const { return m_moduleNamespaceObjectStructure.get(); }
    537538    Structure* proxyObjectStructure() const { return m_proxyObjectStructure.get(); }
     539    Structure* proxyRevokeStructure() const { return m_proxyRevokeStructure.get(); }
    538540#if ENABLE(WEBASSEMBLY)
    539541    Structure* wasmModuleStructure() const { return m_wasmModuleStructure.get(); }
  • trunk/Source/JavaScriptCore/runtime/ProxyConstructor.cpp

    r197614 r197732  
    2828
    2929#include "Error.h"
     30#include "IdentifierInlines.h"
    3031#include "JSCJSValueInlines.h"
    3132#include "JSCellInlines.h"
     33#include "ObjectConstructor.h"
    3234#include "ObjectPrototype.h"
    3335#include "ProxyObject.h"
     36#include "ProxyRevoke.h"
    3437#include "StructureInlines.h"
    3538
     
    4346{
    4447    ProxyConstructor* constructor = new (NotNull, allocateCell<ProxyConstructor>(vm.heap)) ProxyConstructor(vm, structure);
    45     constructor->finishCreation(vm, "Proxy");
     48    constructor->finishCreation(vm, "Proxy", structure->globalObject());
    4649    return constructor;
    4750}
     
    5255}
    5356
    54 void ProxyConstructor::finishCreation(VM& vm, const char* name)
     57static EncodedJSValue JSC_HOST_CALL makeRevocableProxy(ExecState* exec)
     58{
     59    if (exec->argumentCount() < 2)
     60        return throwVMTypeError(exec, ASCIILiteral("Proxy.revocable needs to be called with two arguments: the target and the handler."));
     61
     62    VM& vm = exec->vm();
     63    ArgList args(exec);
     64    JSValue target = args.at(0);
     65    JSValue handler = args.at(1);
     66    ProxyObject* proxy = ProxyObject::create(exec, exec->lexicalGlobalObject()->proxyObjectStructure(), target, handler);
     67    if (vm.exception())
     68        return JSValue::encode(JSValue());
     69    ProxyRevoke* revoke = ProxyRevoke::create(vm, exec->lexicalGlobalObject()->proxyRevokeStructure(), proxy);
     70    if (vm.exception())
     71        return JSValue::encode(JSValue());
     72
     73    JSObject* result = constructEmptyObject(exec);
     74    if (vm.exception())
     75        return JSValue::encode(JSValue());
     76    result->putDirect(vm, makeIdentifier(vm, "proxy"), proxy, None);
     77    result->putDirect(vm, makeIdentifier(vm, "revoke"), revoke, None);
     78
     79    return JSValue::encode(result);
     80}
     81
     82static EncodedJSValue JSC_HOST_CALL proxyRevocableConstructorThrowError(ExecState* exec)
     83{
     84    return throwVMTypeError(exec, ASCIILiteral("Proxy.revocable can not be constructed. It can only be called."));
     85}
     86
     87void ProxyConstructor::finishCreation(VM& vm, const char* name, JSGlobalObject* globalObject)
    5588{
    5689    Base::finishCreation(vm, name);
    5790
    58     putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(2), ReadOnly | DontDelete | DontEnum);
     91    putDirect(vm, vm.propertyNames->length, jsNumber(2), ReadOnly | DontDelete | DontEnum);
     92    putDirect(vm, makeIdentifier(vm, "revocable"), JSFunction::create(vm, globalObject, 2, ASCIILiteral("revocable"), makeRevocableProxy, NoIntrinsic, proxyRevocableConstructorThrowError));
    5993}
    6094
  • trunk/Source/JavaScriptCore/runtime/ProxyConstructor.h

    r196722 r197732  
    4545    }
    4646
    47     void finishCreation(VM&, const char* name);
     47    void finishCreation(VM&, const char* name, JSGlobalObject*);
    4848
    4949private:
  • trunk/Source/JavaScriptCore/runtime/ProxyObject.cpp

    r197711 r197732  
    5454    }
    5555    if (ProxyObject* targetAsProxy = jsDynamicCast<ProxyObject*>(target)) {
    56         // FIXME: Add tests for this once we implement Proxy.revoke(.).
    57         // https://bugs.webkit.org/show_bug.cgi?id=154321
    5856        if (targetAsProxy->handler().isNull()) {
    59             throwTypeError(exec, ASCIILiteral("If a Proxy's handler is another Proxy object, the other Proxy object must have a non-null handler."));
     57            throwTypeError(exec, ASCIILiteral("If a Proxy's handler is another Proxy object, the other Proxy should not have been revoked."));
    6058            return;
    6159        }
     
    7775    m_handler.set(vm, this, handler);
    7876}
     77
     78static const char* s_proxyAlreadyRevokedErrorMessage = "Proxy has already been revoked. No more operations are allowed to be performed on it.";
    7979
    8080static EncodedJSValue performProxyGet(ExecState* exec, EncodedJSValue thisValue, PropertyName propertyName)
     
    114114    JSValue handlerValue = proxyObject->handler();
    115115    if (handlerValue.isNull())
    116         return throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object."));
     116        return throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage));
    117117
    118118    JSObject* handler = jsCast<JSObject*>(handlerValue);
     
    165165    JSValue handlerValue = this->handler();
    166166    if (handlerValue.isNull()) {
    167         throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object."));
     167        throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage));
    168168        return false;
    169169    }
     
    268268    JSValue handlerValue = this->handler();
    269269    if (handlerValue.isNull()) {
    270         throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object."));
     270        throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage));
    271271        return false;
    272272    }
     
    361361    JSValue handlerValue = this->handler();
    362362    if (handlerValue.isNull()) {
    363         throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object."));
     363        throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage));
    364364        return;
    365365    }
     
    448448    JSValue handlerValue = proxy->handler();
    449449    if (handlerValue.isNull())
    450         return throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object."));
     450        return throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage));
    451451
    452452    JSObject* handler = jsCast<JSObject*>(handlerValue);
     
    493493    JSValue handlerValue = proxy->handler();
    494494    if (handlerValue.isNull())
    495         return throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object."));
     495        return throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage));
    496496
    497497    JSObject* handler = jsCast<JSObject*>(handlerValue);
     
    547547    JSValue handlerValue = this->handler();
    548548    if (handlerValue.isNull()) {
    549         throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object."));
     549        throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage));
    550550        return false;
    551551    }
     
    616616    JSValue handlerValue = this->handler();
    617617    if (handlerValue.isNull()) {
    618         throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object."));
     618        throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage));
    619619        return false;
    620620    }
     
    664664    JSValue handlerValue = this->handler();
    665665    if (handlerValue.isNull()) {
    666         throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object."));
     666        throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage));
    667667        return false;
    668668    }
     
    726726    JSValue handlerValue = this->handler();
    727727    if (handlerValue.isNull()) {
    728         throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object."));
     728        throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage));
    729729        return false;
    730730    }
     
    810810    JSValue handlerValue = this->handler();
    811811    if (handlerValue.isNull()) {
    812         throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object."));
     812        throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage));
    813813        return;
    814814    }
     
    971971    JSValue handlerValue = this->handler();
    972972    if (handlerValue.isNull()) {
    973         throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object."));
     973        throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage));
    974974        return false;
    975975    }
     
    10311031    JSValue handlerValue = this->handler();
    10321032    if (handlerValue.isNull()) {
    1033         throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object."));
     1033        throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage));
    10341034        return JSValue();
    10351035    }
     
    10791079}
    10801080
     1081void ProxyObject::revoke(VM& vm)
     1082{
     1083    // This should only ever be called once and we should strictly transition from Object to null.
     1084    RELEASE_ASSERT(!m_handler.get().isNull() && m_handler.get().isObject());
     1085    m_handler.set(vm, this, jsNull());
     1086}
     1087
    10811088void ProxyObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
    10821089{
  • trunk/Source/JavaScriptCore/runtime/ProxyObject.h

    r197711 r197732  
    3939    // We lie an say we override getPropertyNames() because it prevents
    4040    // property name enumeration caching.
    41     const static unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | TypeOfShouldCallGetCallData | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames;
     41    const static unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | TypeOfShouldCallGetCallData | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | ProhibitsPropertyCaching;
    4242
    4343    static ProxyObject* create(ExecState* exec, Structure* structure, JSValue target, JSValue handler)
     
    6767    void putByIndexCommon(ExecState*, JSValue thisValue, unsigned propertyName, JSValue putValue, bool shouldThrow);
    6868    JSValue performGetPrototype(ExecState*);
     69    void revoke(VM&);
    6970
    7071private:
  • trunk/Source/JavaScriptCore/runtime/ProxyRevoke.h

    r197731 r197732  
    2424 */
    2525
    26 #ifndef ProxyConstructor_h
    27 #define ProxyConstructor_h
     26#ifndef ProxyRevoke_h
     27#define ProxyRevoke_h
    2828
    2929#include "InternalFunction.h"
     
    3131namespace JSC {
    3232
    33 class ProxyConstructor : public InternalFunction {
     33class ProxyObject;
     34
     35class ProxyRevoke : public InternalFunction {
    3436public:
    3537    typedef InternalFunction Base;
    3638    static const unsigned StructureFlags = Base::StructureFlags;
    3739
    38     static ProxyConstructor* create(VM&, Structure*);
     40    static ProxyRevoke* create(VM&, Structure*, ProxyObject*);
    3941
    4042    DECLARE_INFO;
     
    4547    }
    4648
    47     void finishCreation(VM&, const char* name);
     49    void finishCreation(VM&, const char* name, ProxyObject*);
     50    static void visitChildren(JSCell*, SlotVisitor&);
     51    JSValue proxy() { return m_proxy.get(); }
     52    void setProxyToNull(VM& vm) { return m_proxy.set(vm, this, jsNull()); }
    4853
    4954private:
    50     ProxyConstructor(VM&, Structure*);
    51     static ConstructType getConstructData(JSCell*, ConstructData&);
     55    ProxyRevoke(VM&, Structure*);
    5256    static CallType getCallData(JSCell*, CallData&);
    5357
    54     static EncodedJSValue getGetter(ExecState*, EncodedJSValue thisValue, PropertyName);
     58    WriteBarrier<Unknown> m_proxy;
    5559};
    5660
    5761} // namespace JSC
    5862
    59 #endif // ProxyConstructor_h
     63#endif // ProxyRevoke_h
  • trunk/Source/JavaScriptCore/tests/es6.yaml

    r197711 r197732  
    10641064  cmd: runES6 :normal
    10651065- path: es6/Proxy_Proxy.revocable.js
    1066   cmd: runES6 :fail
     1066  cmd: runES6 :normal
    10671067- path: es6/Proxy_set_handler.js
    10681068  cmd: runES6 :normal
  • trunk/Source/JavaScriptCore/tests/stress/proxy-has-property.js

    r197648 r197732  
    444444    }
    445445}
     446
     447{
     448    let called = false;
     449    let handler = {
     450        has: function(...args) {
     451            called = true;
     452            return Reflect.has(...args);
     453        }
     454    };
     455    let proxy = new Proxy({}, handler);
     456    let foo = function() {
     457        assert(!Reflect.has(proxy, "x"));
     458        assert(called);
     459        called = false;
     460    }
     461    noInline(foo)
     462    for (let i = 0; i < 10000; i++) {
     463        foo();
     464    }
     465}
Note: See TracChangeset for help on using the changeset viewer.