Changeset 197732 in webkit
- Timestamp:
- Mar 7, 2016, 11:16:21 PM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 added
- 11 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/CMakeLists.txt
r197489 r197732 765 765 runtime/ProxyConstructor.cpp 766 766 runtime/ProxyObject.cpp 767 runtime/ProxyRevoke.cpp 767 768 runtime/ReflectObject.cpp 768 769 runtime/RegExp.cpp -
trunk/Source/JavaScriptCore/ChangeLog
r197731 r197732 1 2016-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 1 87 2016-03-07 Csaba Osztrogonác <ossy@webkit.org> 2 88 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r197717 r197732 1270 1270 70ECA6081AFDBEA200449739 /* TemplateRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6031AFDBEA200449739 /* TemplateRegistry.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1271 1271 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, ); }; }; 1272 1274 792CB3491C4EED5C00D13AF3 /* PCToCodeOriginMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 792CB3471C4EED5C00D13AF3 /* PCToCodeOriginMap.cpp */; }; 1273 1275 792CB34A1C4EED5C00D13AF3 /* PCToCodeOriginMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 792CB3481C4EED5C00D13AF3 /* PCToCodeOriginMap.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 3429 3431 70ECA6031AFDBEA200449739 /* TemplateRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateRegistry.h; sourceTree = "<group>"; }; 3430 3432 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>"; }; 3431 3435 792CB3471C4EED5C00D13AF3 /* PCToCodeOriginMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCToCodeOriginMap.cpp; sourceTree = "<group>"; }; 3432 3436 792CB3481C4EED5C00D13AF3 /* PCToCodeOriginMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCToCodeOriginMap.h; sourceTree = "<group>"; }; … … 5856 5860 79B00CBA1C6AB07E0088C65D /* ProxyObject.cpp */, 5857 5861 79B00CBB1C6AB07E0088C65D /* ProxyObject.h */, 5862 79160DBB1C8E3EC8008C085A /* ProxyRevoke.cpp */, 5863 79160DBC1C8E3EC8008C085A /* ProxyRevoke.h */, 5858 5864 0F5780A118FE1E98001E72D9 /* PureNaN.h */, 5859 5865 0F0CD4C015F1A6040032F1C0 /* PutDirectIndexMode.h */, … … 6903 6909 799EF7C41C56ED96002B0534 /* B3PCToOriginMap.h in Headers */, 6904 6910 79B00CBF1C6AB07E0088C65D /* ProxyObject.h in Headers */, 6911 79160DBE1C8E3EC8008C085A /* ProxyRevoke.h in Headers */, 6905 6912 792CB34A1C4EED5C00D13AF3 /* PCToCodeOriginMap.h in Headers */, 6906 6913 79CFC6F01C33B10000C768EA /* LLIntPCRanges.h in Headers */, … … 9163 9170 0F338E0B1BF0276C0013C88F /* B3Compilation.cpp in Sources */, 9164 9171 14469DE0107EC7E700650446 /* NativeErrorConstructor.cpp in Sources */, 9172 79160DBD1C8E3EC8008C085A /* ProxyRevoke.cpp in Sources */, 9165 9173 14469DE1107EC7E700650446 /* NativeErrorPrototype.cpp in Sources */, 9166 9174 E33E8D201B9013DE00346B52 /* NativeStdFunctionCell.cpp in Sources */, -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r197648 r197732 131 131 #include "ProxyConstructor.h" 132 132 #include "ProxyObject.h" 133 #include "ProxyRevoke.h" 133 134 #include "ReflectObject.h" 134 135 #include "RegExpConstructor.h" … … 371 372 m_moduleNamespaceObjectStructure.set(vm, this, JSModuleNamespaceObject::createStructure(vm, this, jsNull())); 372 373 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())); 373 375 374 376 #if ENABLE(WEBASSEMBLY) … … 912 914 visitor.append(&thisObject->m_internalFunctionStructure); 913 915 visitor.append(&thisObject->m_proxyObjectStructure); 916 visitor.append(&thisObject->m_proxyRevokeStructure); 914 917 #if ENABLE(WEBASSEMBLY) 915 918 visitor.append(&thisObject->m_wasmModuleStructure); -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h
r197648 r197732 283 283 WriteBarrier<Structure> m_moduleNamespaceObjectStructure; 284 284 WriteBarrier<Structure> m_proxyObjectStructure; 285 WriteBarrier<Structure> m_proxyRevokeStructure; 285 286 #if ENABLE(WEBASSEMBLY) 286 287 WriteBarrier<Structure> m_wasmModuleStructure; … … 536 537 Structure* moduleNamespaceObjectStructure() const { return m_moduleNamespaceObjectStructure.get(); } 537 538 Structure* proxyObjectStructure() const { return m_proxyObjectStructure.get(); } 539 Structure* proxyRevokeStructure() const { return m_proxyRevokeStructure.get(); } 538 540 #if ENABLE(WEBASSEMBLY) 539 541 Structure* wasmModuleStructure() const { return m_wasmModuleStructure.get(); } -
trunk/Source/JavaScriptCore/runtime/ProxyConstructor.cpp
r197614 r197732 28 28 29 29 #include "Error.h" 30 #include "IdentifierInlines.h" 30 31 #include "JSCJSValueInlines.h" 31 32 #include "JSCellInlines.h" 33 #include "ObjectConstructor.h" 32 34 #include "ObjectPrototype.h" 33 35 #include "ProxyObject.h" 36 #include "ProxyRevoke.h" 34 37 #include "StructureInlines.h" 35 38 … … 43 46 { 44 47 ProxyConstructor* constructor = new (NotNull, allocateCell<ProxyConstructor>(vm.heap)) ProxyConstructor(vm, structure); 45 constructor->finishCreation(vm, "Proxy" );48 constructor->finishCreation(vm, "Proxy", structure->globalObject()); 46 49 return constructor; 47 50 } … … 52 55 } 53 56 54 void ProxyConstructor::finishCreation(VM& vm, const char* name) 57 static 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 82 static 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 87 void ProxyConstructor::finishCreation(VM& vm, const char* name, JSGlobalObject* globalObject) 55 88 { 56 89 Base::finishCreation(vm, name); 57 90 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)); 59 93 } 60 94 -
trunk/Source/JavaScriptCore/runtime/ProxyConstructor.h
r196722 r197732 45 45 } 46 46 47 void finishCreation(VM&, const char* name );47 void finishCreation(VM&, const char* name, JSGlobalObject*); 48 48 49 49 private: -
trunk/Source/JavaScriptCore/runtime/ProxyObject.cpp
r197711 r197732 54 54 } 55 55 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=15432158 56 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.")); 60 58 return; 61 59 } … … 77 75 m_handler.set(vm, this, handler); 78 76 } 77 78 static const char* s_proxyAlreadyRevokedErrorMessage = "Proxy has already been revoked. No more operations are allowed to be performed on it."; 79 79 80 80 static EncodedJSValue performProxyGet(ExecState* exec, EncodedJSValue thisValue, PropertyName propertyName) … … 114 114 JSValue handlerValue = proxyObject->handler(); 115 115 if (handlerValue.isNull()) 116 return throwVMTypeError(exec, ASCIILiteral( "Proxy 'handler' is null. It should be an Object."));116 return throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage)); 117 117 118 118 JSObject* handler = jsCast<JSObject*>(handlerValue); … … 165 165 JSValue handlerValue = this->handler(); 166 166 if (handlerValue.isNull()) { 167 throwVMTypeError(exec, ASCIILiteral( "Proxy 'handler' is null. It should be an Object."));167 throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage)); 168 168 return false; 169 169 } … … 268 268 JSValue handlerValue = this->handler(); 269 269 if (handlerValue.isNull()) { 270 throwVMTypeError(exec, ASCIILiteral( "Proxy 'handler' is null. It should be an Object."));270 throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage)); 271 271 return false; 272 272 } … … 361 361 JSValue handlerValue = this->handler(); 362 362 if (handlerValue.isNull()) { 363 throwVMTypeError(exec, ASCIILiteral( "Proxy 'handler' is null. It should be an Object."));363 throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage)); 364 364 return; 365 365 } … … 448 448 JSValue handlerValue = proxy->handler(); 449 449 if (handlerValue.isNull()) 450 return throwVMTypeError(exec, ASCIILiteral( "Proxy 'handler' is null. It should be an Object."));450 return throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage)); 451 451 452 452 JSObject* handler = jsCast<JSObject*>(handlerValue); … … 493 493 JSValue handlerValue = proxy->handler(); 494 494 if (handlerValue.isNull()) 495 return throwVMTypeError(exec, ASCIILiteral( "Proxy 'handler' is null. It should be an Object."));495 return throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage)); 496 496 497 497 JSObject* handler = jsCast<JSObject*>(handlerValue); … … 547 547 JSValue handlerValue = this->handler(); 548 548 if (handlerValue.isNull()) { 549 throwVMTypeError(exec, ASCIILiteral( "Proxy 'handler' is null. It should be an Object."));549 throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage)); 550 550 return false; 551 551 } … … 616 616 JSValue handlerValue = this->handler(); 617 617 if (handlerValue.isNull()) { 618 throwVMTypeError(exec, ASCIILiteral( "Proxy 'handler' is null. It should be an Object."));618 throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage)); 619 619 return false; 620 620 } … … 664 664 JSValue handlerValue = this->handler(); 665 665 if (handlerValue.isNull()) { 666 throwVMTypeError(exec, ASCIILiteral( "Proxy 'handler' is null. It should be an Object."));666 throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage)); 667 667 return false; 668 668 } … … 726 726 JSValue handlerValue = this->handler(); 727 727 if (handlerValue.isNull()) { 728 throwVMTypeError(exec, ASCIILiteral( "Proxy 'handler' is null. It should be an Object."));728 throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage)); 729 729 return false; 730 730 } … … 810 810 JSValue handlerValue = this->handler(); 811 811 if (handlerValue.isNull()) { 812 throwVMTypeError(exec, ASCIILiteral( "Proxy 'handler' is null. It should be an Object."));812 throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage)); 813 813 return; 814 814 } … … 971 971 JSValue handlerValue = this->handler(); 972 972 if (handlerValue.isNull()) { 973 throwVMTypeError(exec, ASCIILiteral( "Proxy 'handler' is null. It should be an Object."));973 throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage)); 974 974 return false; 975 975 } … … 1031 1031 JSValue handlerValue = this->handler(); 1032 1032 if (handlerValue.isNull()) { 1033 throwVMTypeError(exec, ASCIILiteral( "Proxy 'handler' is null. It should be an Object."));1033 throwVMTypeError(exec, ASCIILiteral(s_proxyAlreadyRevokedErrorMessage)); 1034 1034 return JSValue(); 1035 1035 } … … 1079 1079 } 1080 1080 1081 void 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 1081 1088 void ProxyObject::visitChildren(JSCell* cell, SlotVisitor& visitor) 1082 1089 { -
trunk/Source/JavaScriptCore/runtime/ProxyObject.h
r197711 r197732 39 39 // We lie an say we override getPropertyNames() because it prevents 40 40 // 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; 42 42 43 43 static ProxyObject* create(ExecState* exec, Structure* structure, JSValue target, JSValue handler) … … 67 67 void putByIndexCommon(ExecState*, JSValue thisValue, unsigned propertyName, JSValue putValue, bool shouldThrow); 68 68 JSValue performGetPrototype(ExecState*); 69 void revoke(VM&); 69 70 70 71 private: -
trunk/Source/JavaScriptCore/runtime/ProxyRevoke.h
r197731 r197732 24 24 */ 25 25 26 #ifndef Proxy Constructor_h27 #define Proxy Constructor_h26 #ifndef ProxyRevoke_h 27 #define ProxyRevoke_h 28 28 29 29 #include "InternalFunction.h" … … 31 31 namespace JSC { 32 32 33 class ProxyConstructor : public InternalFunction { 33 class ProxyObject; 34 35 class ProxyRevoke : public InternalFunction { 34 36 public: 35 37 typedef InternalFunction Base; 36 38 static const unsigned StructureFlags = Base::StructureFlags; 37 39 38 static Proxy Constructor* create(VM&, Structure*);40 static ProxyRevoke* create(VM&, Structure*, ProxyObject*); 39 41 40 42 DECLARE_INFO; … … 45 47 } 46 48 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()); } 48 53 49 54 private: 50 ProxyConstructor(VM&, Structure*); 51 static ConstructType getConstructData(JSCell*, ConstructData&); 55 ProxyRevoke(VM&, Structure*); 52 56 static CallType getCallData(JSCell*, CallData&); 53 57 54 static EncodedJSValue getGetter(ExecState*, EncodedJSValue thisValue, PropertyName);58 WriteBarrier<Unknown> m_proxy; 55 59 }; 56 60 57 61 } // namespace JSC 58 62 59 #endif // Proxy Constructor_h63 #endif // ProxyRevoke_h -
trunk/Source/JavaScriptCore/tests/es6.yaml
r197711 r197732 1064 1064 cmd: runES6 :normal 1065 1065 - path: es6/Proxy_Proxy.revocable.js 1066 cmd: runES6 : fail1066 cmd: runES6 :normal 1067 1067 - path: es6/Proxy_set_handler.js 1068 1068 cmd: runES6 :normal -
trunk/Source/JavaScriptCore/tests/stress/proxy-has-property.js
r197648 r197732 444 444 } 445 445 } 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.