WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
patch
c-backup.diff (text/plain), 84.68 KB, created by
Saam Barati
on 2016-02-16 15:21:07 PST
(
hide
)
Description:
patch
Filename:
MIME Type:
Creator:
Saam Barati
Created:
2016-02-16 15:21:07 PST
Size:
84.68 KB
patch
obsolete
>Index: Source/JavaScriptCore/ChangeLog >=================================================================== >--- Source/JavaScriptCore/ChangeLog (revision 196663) >+++ Source/JavaScriptCore/ChangeLog (working copy) >@@ -1,3 +1,149 @@ >+2016-02-16 Saam barati <sbarati@apple.com> >+ >+ Implement Proxy [[Get]] >+ https://bugs.webkit.org/show_bug.cgi?id=154081 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch implements ProxyObject and ProxyConstructor. Their >+ implementations are straight forward and follow the spec. >+ The largest change in this patch is adding a second parameter >+ to PropertySlot's constructor that specifies the trap type of >+ the getOwnPropertySlot inquiry. Because we overload getOwnPropertySlot >+ to mean more than operation in the spec, having TrapType gives >+ getOwnPropertySlot context about the context it's being called in. >+ TrapType is an enum with the following values: >+ - Get >+ This corresponds to [[Get]] in the spec. >+ - GetOwnProperty >+ This corresponds to [[GetOwnProperty]] in the spec. >+ - HasProperty >+ This corresponds to [[HasProperty]] in the spec. >+ - VMInquiry >+ This is basically everything else that isn't one of the above >+ traps. This value also mandates that getOwnPropertySlot does >+ not perform any user observable effects. I.e, it can't call >+ a JS function. >+ >+ The other non-VMInquiry TrapTypes are allowed to perform user >+ observable effects. I.e, in future patches, ProxyObject will implement >+ TrapType::Has and TrapType::GetOwnProperty, which will both be defined >+ to call user defined JS functions, which clearly have the right to perform >+ user oversable effects. >+ >+ We need TrapType to implement the Proxy object because >+ the Proxy will need to perform different operations depending >+ on the PropertySlot's TrapType value. >+ >+ This patch implements getOwnPropertySlot of ProxyObject under >+ TrapType::Get. >+ >+ * API/JSCallbackObjectFunctions.h: >+ (JSC::JSCallbackObject<Parent>::put): >+ (JSC::JSCallbackObject<Parent>::staticFunctionGetter): >+ * CMakeLists.txt: >+ * JavaScriptCore.xcodeproj/project.pbxproj: >+ * debugger/DebuggerScope.cpp: >+ (JSC::DebuggerScope::caughtValue): >+ * interpreter/Interpreter.cpp: >+ (JSC::Interpreter::execute): >+ * jit/JITOperations.cpp: >+ * llint/LLIntSlowPaths.cpp: >+ (JSC::LLInt::LLINT_SLOW_PATH_DECL): >+ * runtime/ArrayPrototype.cpp: >+ (JSC::getProperty): >+ * runtime/CommonIdentifiers.h: >+ * runtime/JSCJSValueInlines.h: >+ (JSC::JSValue::get): >+ * runtime/JSFunction.cpp: >+ (JSC::JSFunction::getOwnNonIndexPropertyNames): >+ (JSC::JSFunction::put): >+ (JSC::JSFunction::defineOwnProperty): >+ * runtime/JSGenericTypedArrayViewConstructorInlines.h: >+ (JSC::constructGenericTypedArrayViewWithArguments): >+ * runtime/JSGlobalObject.cpp: >+ (JSC::JSGlobalObject::init): >+ (JSC::JSGlobalObject::defineOwnProperty): >+ * runtime/JSGlobalObject.h: >+ (JSC::JSGlobalObject::regExpMatchesArrayStructure): >+ (JSC::JSGlobalObject::moduleRecordStructure): >+ (JSC::JSGlobalObject::moduleNamespaceObjectStructure): >+ (JSC::JSGlobalObject::proxyObjectStructure): >+ (JSC::JSGlobalObject::wasmModuleStructure): >+ (JSC::JSGlobalObject::hasOwnPropertyForWrite): >+ * runtime/JSModuleEnvironment.cpp: >+ (JSC::JSModuleEnvironment::getOwnPropertySlot): >+ * runtime/JSModuleNamespaceObject.cpp: >+ (JSC::callbackGetter): >+ * runtime/JSONObject.cpp: >+ (JSC::Stringifier::Holder::appendNextProperty): >+ (JSC::Walker::walk): >+ * runtime/JSObject.cpp: >+ (JSC::JSObject::calculatedClassName): >+ (JSC::JSObject::putDirectNonIndexAccessor): >+ (JSC::JSObject::hasProperty): >+ (JSC::JSObject::deleteProperty): >+ (JSC::JSObject::hasOwnProperty): >+ (JSC::JSObject::getOwnPropertyDescriptor): >+ * runtime/JSObject.h: >+ (JSC::JSObject::getDirectIndex): >+ (JSC::JSObject::get): >+ * runtime/JSScope.cpp: >+ (JSC::abstractAccess): >+ * runtime/ObjectConstructor.cpp: >+ (JSC::toPropertyDescriptor): >+ * runtime/ObjectPrototype.cpp: >+ (JSC::objectProtoFuncLookupGetter): >+ (JSC::objectProtoFuncLookupSetter): >+ (JSC::objectProtoFuncToString): >+ * runtime/PropertySlot.h: >+ (JSC::PropertySlot::PropertySlot): >+ (JSC::PropertySlot::isCacheableGetter): >+ (JSC::PropertySlot::isCacheableCustom): >+ (JSC::PropertySlot::trapType): >+ (JSC::PropertySlot::disableCaching): >+ (JSC::PropertySlot::getValue): >+ * runtime/ProxyConstructor.cpp: Added. >+ (JSC::ProxyConstructor::create): >+ (JSC::ProxyConstructor::ProxyConstructor): >+ (JSC::ProxyConstructor::finishCreation): >+ (JSC::constructProxyObject): >+ (JSC::ProxyConstructor::getConstructData): >+ (JSC::ProxyConstructor::getCallData): >+ * runtime/ProxyConstructor.h: Added. >+ (JSC::ProxyConstructor::createStructure): >+ * runtime/ProxyObject.cpp: Added. >+ (JSC::ProxyObject::ProxyObject): >+ (JSC::ProxyObject::finishCreation): >+ (JSC::performProxyGet): >+ (JSC::ProxyObject::getOwnPropertySlotCommon): >+ (JSC::ProxyObject::getOwnPropertySlot): >+ (JSC::ProxyObject::getOwnPropertySlotByIndex): >+ (JSC::ProxyObject::visitChildren): >+ * runtime/ProxyObject.h: Added. >+ (JSC::ProxyObject::create): >+ (JSC::ProxyObject::createStructure): >+ (JSC::ProxyObject::target): >+ (JSC::ProxyObject::handler): >+ * runtime/ReflectObject.cpp: >+ (JSC::reflectObjectGet): >+ * runtime/SamplingProfiler.cpp: >+ (JSC::SamplingProfiler::StackFrame::nameFromCallee): >+ * tests/es6.yaml: >+ * tests/stress/proxy-basic.js: Added. >+ (assert): >+ (let.handler.get null): >+ (get let): >+ (let.handler.get switch): >+ (let.handler): >+ * tests/stress/proxy-in-proto-chain.js: Added. >+ (assert): >+ * tests/stress/proxy-property-descriptor.js: Added. >+ (assert): >+ (set Object): >+ * wasm/WASMModuleParser.cpp: >+ (JSC::WASMModuleParser::getImportedValue): >+ > 2016-02-16 Saam barati <sbarati@apple.com> > > SamplingProfiler still fails with ASan enabled >Index: Source/JavaScriptCore/CMakeLists.txt >=================================================================== >--- Source/JavaScriptCore/CMakeLists.txt (revision 196658) >+++ Source/JavaScriptCore/CMakeLists.txt (working copy) >@@ -736,6 +736,8 @@ set(JavaScriptCore_RUNTIME_SOURCES > runtime/PropertySlot.cpp > runtime/PropertyTable.cpp > runtime/PrototypeMap.cpp >+ runtime/ProxyConstructor.cpp >+ runtime/ProxyObject.cpp > runtime/ReflectObject.cpp > runtime/RegExp.cpp > runtime/RegExpCache.cpp >Index: Source/JavaScriptCore/API/JSCallbackObjectFunctions.h >=================================================================== >--- Source/JavaScriptCore/API/JSCallbackObjectFunctions.h (revision 196658) >+++ Source/JavaScriptCore/API/JSCallbackObjectFunctions.h (working copy) >@@ -268,7 +268,7 @@ void JSCallbackObject<Parent>::put(JSCel > > if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) { > if (StaticFunctionEntry* entry = staticFunctions->get(name)) { >- PropertySlot getSlot(thisObject); >+ PropertySlot getSlot(thisObject, PropertySlot::TrapType::VMInquiry); > if (Parent::getOwnPropertySlot(thisObject, exec, propertyName, getSlot)) > return Parent::put(thisObject, exec, propertyName, value, slot); > if (entry->attributes & kJSPropertyAttributeReadOnly) >@@ -605,7 +605,7 @@ EncodedJSValue JSCallbackObject<Parent>: > JSCallbackObject* thisObj = asCallbackObject(thisValue); > > // Check for cached or override property. >- PropertySlot slot2(thisObj); >+ PropertySlot slot2(thisObj, PropertySlot::TrapType::VMInquiry); > if (Parent::getOwnPropertySlot(thisObj, exec, propertyName, slot2)) > return JSValue::encode(slot2.getValue(exec, propertyName)); > >Index: Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >=================================================================== >--- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (revision 196658) >+++ Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (working copy) >@@ -1318,6 +1318,10 @@ > 797E07A91B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 797E07A71B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp */; }; > 797E07AA1B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 799EF7C41C56ED96002B0534 /* B3PCToOriginMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 799EF7C31C56ED96002B0534 /* B3PCToOriginMap.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 79B00CBC1C6AB07E0088C65D /* ProxyConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79B00CB81C6AB07E0088C65D /* ProxyConstructor.cpp */; }; >+ 79B00CBD1C6AB07E0088C65D /* ProxyConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 79B00CB91C6AB07E0088C65D /* ProxyConstructor.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 79B00CBE1C6AB07E0088C65D /* ProxyObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79B00CBA1C6AB07E0088C65D /* ProxyObject.cpp */; }; >+ 79B00CBF1C6AB07E0088C65D /* ProxyObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 79B00CBB1C6AB07E0088C65D /* ProxyObject.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 79C4B15D1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79C4B15B1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp */; }; > 79C4B15E1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 79C4B15C1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 79CFC6F01C33B10000C768EA /* LLIntPCRanges.h in Headers */ = {isa = PBXBuildFile; fileRef = 79CFC6EF1C33B10000C768EA /* LLIntPCRanges.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -3525,6 +3529,10 @@ > 797E07A71B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalLexicalEnvironment.cpp; sourceTree = "<group>"; }; > 797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalLexicalEnvironment.h; sourceTree = "<group>"; }; > 799EF7C31C56ED96002B0534 /* B3PCToOriginMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3PCToOriginMap.h; path = b3/B3PCToOriginMap.h; sourceTree = "<group>"; }; >+ 79B00CB81C6AB07E0088C65D /* ProxyConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProxyConstructor.cpp; sourceTree = "<group>"; }; >+ 79B00CB91C6AB07E0088C65D /* ProxyConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProxyConstructor.h; sourceTree = "<group>"; }; >+ 79B00CBA1C6AB07E0088C65D /* ProxyObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProxyObject.cpp; sourceTree = "<group>"; }; >+ 79B00CBB1C6AB07E0088C65D /* ProxyObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProxyObject.h; sourceTree = "<group>"; }; > 79C4B15B1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGLiveCatchVariablePreservationPhase.cpp; path = dfg/DFGLiveCatchVariablePreservationPhase.cpp; sourceTree = "<group>"; }; > 79C4B15C1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGLiveCatchVariablePreservationPhase.h; path = dfg/DFGLiveCatchVariablePreservationPhase.h; sourceTree = "<group>"; }; > 79CFC6EF1C33B10000C768EA /* LLIntPCRanges.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntPCRanges.h; path = llint/LLIntPCRanges.h; sourceTree = "<group>"; }; >@@ -6008,6 +6016,10 @@ > 65C02FBB0637462A003E7EE6 /* Protect.h */, > 14D844A216AA2C7000A65AF0 /* PrototypeMap.cpp */, > 14D844A316AA2C7000A65AF0 /* PrototypeMap.h */, >+ 79B00CB81C6AB07E0088C65D /* ProxyConstructor.cpp */, >+ 79B00CB91C6AB07E0088C65D /* ProxyConstructor.h */, >+ 79B00CBA1C6AB07E0088C65D /* ProxyObject.cpp */, >+ 79B00CBB1C6AB07E0088C65D /* ProxyObject.h */, > 0F5780A118FE1E98001E72D9 /* PureNaN.h */, > 0F0CD4C015F1A6040032F1C0 /* PutDirectIndexMode.h */, > 147B84620E6DE6B1004775A4 /* PutPropertySlot.h */, >@@ -7061,7 +7073,9 @@ > 0FEC85761BDACDC70080FF74 /* AirCode.h in Headers */, > 0F3730931C0D67EE00052BFA /* AirUseCounts.h in Headers */, > 0F4570391BE44C910062A629 /* AirEliminateDeadCode.h in Headers */, >+ 79B00CBD1C6AB07E0088C65D /* ProxyConstructor.h in Headers */, > 799EF7C41C56ED96002B0534 /* B3PCToOriginMap.h in Headers */, >+ 79B00CBF1C6AB07E0088C65D /* ProxyObject.h in Headers */, > 792CB34A1C4EED5C00D13AF3 /* PCToCodeOriginMap.h in Headers */, > 79CFC6F01C33B10000C768EA /* LLIntPCRanges.h in Headers */, > 79D5CD5B1C1106A900CECA07 /* SamplingProfiler.h in Headers */, >@@ -8953,6 +8967,7 @@ > A77A423F17A0BBFD00A8DB81 /* DFGClobberize.cpp in Sources */, > A77A424117A0BBFD00A8DB81 /* DFGClobberSet.cpp in Sources */, > 0F3C1F1A1B868E7900ABB08B /* DFGClobbersExitState.cpp in Sources */, >+ 79B00CBC1C6AB07E0088C65D /* ProxyConstructor.cpp in Sources */, > 0F04396D1B03DC0B009598B7 /* DFGCombinedLiveness.cpp in Sources */, > 0FF0F19D16B72A08005DF95B /* DFGCommon.cpp in Sources */, > 0FEA0A31170D40BF00BB722C /* DFGCommonData.cpp in Sources */, >@@ -9014,6 +9029,7 @@ > 46D4DCBD1C5AB2D500D8D321 /* JSBoundSlotBaseFunction.cpp in Sources */, > 0FF2CD5B1B61A4F8004955A8 /* DFGMultiGetByOffsetData.cpp in Sources */, > A737810D1799EA2E00817533 /* DFGNaturalLoops.cpp in Sources */, >+ 79B00CBE1C6AB07E0088C65D /* ProxyObject.cpp in Sources */, > 792CB3491C4EED5C00D13AF3 /* PCToCodeOriginMap.cpp in Sources */, > 0FF0F19C16B72A03005DF95B /* DFGNode.cpp in Sources */, > 0FB3878F1BFBC44D00E3AB1E /* AirOptimizeBlockOrder.cpp in Sources */, >Index: Source/JavaScriptCore/debugger/DebuggerScope.cpp >=================================================================== >--- Source/JavaScriptCore/debugger/DebuggerScope.cpp (revision 196658) >+++ Source/JavaScriptCore/debugger/DebuggerScope.cpp (working copy) >@@ -209,7 +209,7 @@ JSValue DebuggerScope::caughtValue(ExecS > SymbolTable* catchSymbolTable = catchEnvironment->symbolTable(); > RELEASE_ASSERT(catchSymbolTable->size() == 1); > PropertyName errorName(catchSymbolTable->begin(catchSymbolTable->m_lock)->key.get()); >- PropertySlot slot(m_scope.get()); >+ PropertySlot slot(m_scope.get(), PropertySlot::TrapType::Get); > bool success = catchEnvironment->getOwnPropertySlot(catchEnvironment, exec, errorName, slot); > RELEASE_ASSERT(success && slot.isValue()); > return slot.getValue(exec, errorName); >Index: Source/JavaScriptCore/interpreter/Interpreter.cpp >=================================================================== >--- Source/JavaScriptCore/interpreter/Interpreter.cpp (revision 196658) >+++ Source/JavaScriptCore/interpreter/Interpreter.cpp (working copy) >@@ -877,7 +877,7 @@ JSValue Interpreter::execute(ProgramExec > switch (JSONPPath[i].m_type) { > case JSONPPathEntryTypeDot: { > if (i == 0) { >- PropertySlot slot(globalObject); >+ PropertySlot slot(globalObject, PropertySlot::TrapType::Get); > if (!globalObject->getPropertySlot(callFrame, JSONPPath[i].m_pathEntryName, slot)) { > if (entry) > return callFrame->vm().throwException(callFrame, createUndefinedVariableError(callFrame, JSONPPath[i].m_pathEntryName)); >@@ -1225,7 +1225,7 @@ JSValue Interpreter::execute(EvalExecuta > JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsCast<JSGlobalObject*>(variableObject)->globalLexicalEnvironment(); > for (unsigned i = 0; i < numVariables; ++i) { > const Identifier& ident = codeBlock->variable(i); >- PropertySlot slot(globalLexicalEnvironment); >+ PropertySlot slot(globalLexicalEnvironment, PropertySlot::TrapType::VMInquiry); > if (JSGlobalLexicalEnvironment::getOwnPropertySlot(globalLexicalEnvironment, callFrame, ident, slot)) { > return checkedReturn(callFrame->vm().throwException(callFrame, > createTypeError(callFrame, makeString("Can't create duplicate global variable in eval: '", String(ident.impl()), "'")))); >@@ -1234,7 +1234,7 @@ JSValue Interpreter::execute(EvalExecuta > > for (int i = 0; i < numFunctions; ++i) { > FunctionExecutable* function = codeBlock->functionDecl(i); >- PropertySlot slot(globalLexicalEnvironment); >+ PropertySlot slot(globalLexicalEnvironment, PropertySlot::TrapType::VMInquiry); > if (JSGlobalLexicalEnvironment::getOwnPropertySlot(globalLexicalEnvironment, callFrame, function->name(), slot)) { > return checkedReturn(callFrame->vm().throwException(callFrame, > createTypeError(callFrame, makeString("Can't create duplicate global variable in eval: '", String(function->name().impl()), "'")))); >Index: Source/JavaScriptCore/jit/JITOperations.cpp >=================================================================== >--- Source/JavaScriptCore/jit/JITOperations.cpp (revision 196658) >+++ Source/JavaScriptCore/jit/JITOperations.cpp (working copy) >@@ -158,7 +158,7 @@ EncodedJSValue JIT_OPERATION operationGe > stubInfo->tookSlowPath = true; > > JSValue baseValue = JSValue::decode(base); >- PropertySlot slot(baseValue); >+ PropertySlot slot(baseValue, PropertySlot::TrapType::Get); > Identifier ident = Identifier::fromUid(vm, uid); > return JSValue::encode(baseValue.get(exec, ident, slot)); > } >@@ -169,7 +169,7 @@ EncodedJSValue JIT_OPERATION operationGe > NativeCallFrameTracer tracer(vm, exec); > > JSValue baseValue = JSValue::decode(base); >- PropertySlot slot(baseValue); >+ PropertySlot slot(baseValue, PropertySlot::TrapType::Get); > Identifier ident = Identifier::fromUid(vm, uid); > return JSValue::encode(baseValue.get(exec, ident, slot)); > } >@@ -181,7 +181,7 @@ EncodedJSValue JIT_OPERATION operationGe > Identifier ident = Identifier::fromUid(vm, uid); > > JSValue baseValue = JSValue::decode(base); >- PropertySlot slot(baseValue); >+ PropertySlot slot(baseValue, PropertySlot::TrapType::Get); > > bool hasResult = baseValue.getPropertySlot(exec, ident, slot); > if (stubInfo->considerCaching()) >@@ -203,7 +203,7 @@ EncodedJSValue JIT_OPERATION operationIn > AccessType accessType = static_cast<AccessType>(stubInfo->accessType); > > Identifier ident = Identifier::fromUid(vm, key); >- PropertySlot slot(base); >+ PropertySlot slot(base, PropertySlot::TrapType::HasProperty); > bool result = asObject(base)->getPropertySlot(exec, ident, slot); > > RELEASE_ASSERT(accessType == stubInfo->accessType); >@@ -1885,7 +1885,7 @@ EncodedJSValue JIT_OPERATION operationGe > // ModuleVar is always converted to ClosureVar for get_from_scope. > ASSERT(getPutInfo.resolveType() != ModuleVar); > >- PropertySlot slot(scope); >+ PropertySlot slot(scope, PropertySlot::TrapType::Get); > if (!scope->getPropertySlot(exec, ident, slot)) { > if (getPutInfo.resolveMode() == ThrowIfNotFound) > vm.throwException(exec, createUndefinedVariableError(exec, ident)); >@@ -1937,7 +1937,7 @@ void JIT_OPERATION operationPutToScope(E > && jsDynamicCast<JSGlobalLexicalEnvironment*>(scope) > && getPutInfo.initializationMode() != Initialization) { > // When we can't statically prove we need a TDZ check, we must perform the check on the slow path. >- PropertySlot slot(scope); >+ PropertySlot slot(scope, PropertySlot::TrapType::Get); > JSGlobalLexicalEnvironment::getOwnPropertySlot(scope, exec, ident, slot); > if (slot.getValue(exec, ident) == jsTDZValue()) { > exec->vm().throwException(exec, createTDZError(exec)); >Index: Source/JavaScriptCore/llint/LLIntSlowPaths.cpp >=================================================================== >--- Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (revision 196658) >+++ Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (working copy) >@@ -551,7 +551,7 @@ LLINT_SLOW_PATH_DECL(slow_path_get_by_id > CodeBlock* codeBlock = exec->codeBlock(); > const Identifier& ident = codeBlock->identifier(pc[3].u.operand); > JSValue baseValue = LLINT_OP_C(2).jsValue(); >- PropertySlot slot(baseValue); >+ PropertySlot slot(baseValue, PropertySlot::PropertySlot::TrapType::Get); > > JSValue result = baseValue.get(exec, ident, slot); > LLINT_CHECK_EXCEPTION(); >@@ -602,7 +602,7 @@ LLINT_SLOW_PATH_DECL(slow_path_get_argum > CodeBlock* codeBlock = exec->codeBlock(); > const Identifier& ident = codeBlock->identifier(pc[3].u.operand); > JSValue baseValue = LLINT_OP(2).jsValue(); >- PropertySlot slot(baseValue); >+ PropertySlot slot(baseValue, PropertySlot::TrapType::Get); > LLINT_RETURN(baseValue.get(exec, ident, slot)); > } > >@@ -1413,7 +1413,7 @@ LLINT_SLOW_PATH_DECL(slow_path_get_from_ > // ModuleVar is always converted to ClosureVar for get_from_scope. > ASSERT(getPutInfo.resolveType() != ModuleVar); > >- PropertySlot slot(scope); >+ PropertySlot slot(scope, PropertySlot::TrapType::Get); > if (!scope->getPropertySlot(exec, ident, slot)) { > if (getPutInfo.resolveMode() == ThrowIfNotFound) > LLINT_RETURN(exec->vm().throwException(exec, createUndefinedVariableError(exec, ident))); >@@ -1461,7 +1461,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_to_sc > && jsDynamicCast<JSGlobalLexicalEnvironment*>(scope) > && getPutInfo.initializationMode() != Initialization) { > // When we can't statically prove we need a TDZ check, we must perform the check on the slow path. >- PropertySlot slot(scope); >+ PropertySlot slot(scope, PropertySlot::TrapType::Get); > JSGlobalLexicalEnvironment::getOwnPropertySlot(scope, exec, ident, slot); > if (slot.getValue(exec, ident) == jsTDZValue()) > LLINT_THROW(createTDZError(exec)); >Index: Source/JavaScriptCore/runtime/ArrayPrototype.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/ArrayPrototype.cpp (revision 196658) >+++ Source/JavaScriptCore/runtime/ArrayPrototype.cpp (working copy) >@@ -151,7 +151,7 @@ static ALWAYS_INLINE JSValue getProperty > { > if (JSValue result = object->tryGetIndexQuickly(index)) > return result; >- PropertySlot slot(object); >+ PropertySlot slot(object, PropertySlot::TrapType::Get); > if (!object->getPropertySlot(exec, index, slot)) > return JSValue(); > return slot.getValue(exec, index); >Index: Source/JavaScriptCore/runtime/CommonIdentifiers.h >=================================================================== >--- Source/JavaScriptCore/runtime/CommonIdentifiers.h (revision 196658) >+++ Source/JavaScriptCore/runtime/CommonIdentifiers.h (working copy) >@@ -52,6 +52,7 @@ > macro(NumberFormat) \ > macro(Object) \ > macro(Promise) \ >+ macro(Proxy) \ > macro(RangeError) \ > macro(ReferenceError) \ > macro(Reflect) \ >Index: Source/JavaScriptCore/runtime/JSCJSValueInlines.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSCJSValueInlines.h (revision 196658) >+++ Source/JavaScriptCore/runtime/JSCJSValueInlines.h (working copy) >@@ -705,7 +705,7 @@ inline JSValue JSValue::toThis(ExecState > > ALWAYS_INLINE JSValue JSValue::get(ExecState* exec, PropertyName propertyName) const > { >- PropertySlot slot(asValue()); >+ PropertySlot slot(asValue(), PropertySlot::TrapType::Get); > return get(exec, propertyName, slot); > } > >@@ -732,7 +732,7 @@ ALWAYS_INLINE bool JSValue::getPropertyS > > ALWAYS_INLINE JSValue JSValue::get(ExecState* exec, unsigned propertyName) const > { >- PropertySlot slot(asValue()); >+ PropertySlot slot(asValue(), PropertySlot::TrapType::Get); > return get(exec, propertyName, slot); > } > >Index: Source/JavaScriptCore/runtime/JSFunction.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSFunction.cpp (revision 196658) >+++ Source/JavaScriptCore/runtime/JSFunction.cpp (working copy) >@@ -430,7 +430,7 @@ void JSFunction::getOwnNonIndexPropertyN > if (!thisObject->isHostOrBuiltinFunction() && mode.includeDontEnumProperties()) { > VM& vm = exec->vm(); > // Make sure prototype has been reified. >- PropertySlot slot(thisObject); >+ PropertySlot slot(thisObject, PropertySlot::TrapType::VMInquiry); > thisObject->methodTable(vm)->getOwnPropertySlot(thisObject, exec, vm.propertyNames->prototype, slot); > > propertyNames.add(vm.propertyNames->arguments); >@@ -451,7 +451,7 @@ void JSFunction::put(JSCell* cell, ExecS > if (propertyName == exec->propertyNames().prototype) { > // Make sure prototype has been reified, such that it can only be overwritten > // following the rules set out in ECMA-262 8.12.9. >- PropertySlot slot(thisObject); >+ PropertySlot slot(thisObject, PropertySlot::TrapType::VMInquiry); > thisObject->methodTable(exec->vm())->getOwnPropertySlot(thisObject, exec, propertyName, slot); > if (thisObject->m_rareData) > thisObject->m_rareData->clear("Store to prototype property of a function"); >@@ -501,7 +501,7 @@ bool JSFunction::defineOwnProperty(JSObj > if (propertyName == exec->propertyNames().prototype) { > // Make sure prototype has been reified, such that it can only be overwritten > // following the rules set out in ECMA-262 8.12.9. >- PropertySlot slot(thisObject); >+ PropertySlot slot(thisObject, PropertySlot::TrapType::VMInquiry); > thisObject->methodTable(exec->vm())->getOwnPropertySlot(thisObject, exec, propertyName, slot); > if (thisObject->m_rareData) > thisObject->m_rareData->clear("Store to prototype property of a function"); >@@ -511,7 +511,7 @@ bool JSFunction::defineOwnProperty(JSObj > bool valueCheck; > if (propertyName == exec->propertyNames().arguments) { > if (thisObject->jsExecutable()->isStrictMode()) { >- PropertySlot slot(thisObject); >+ PropertySlot slot(thisObject, PropertySlot::TrapType::VMInquiry); > if (!Base::getOwnPropertySlot(thisObject, exec, propertyName, slot)) > thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec->vm()), DontDelete | DontEnum | Accessor); > return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException); >@@ -519,7 +519,7 @@ bool JSFunction::defineOwnProperty(JSObj > valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), retrieveArguments(exec, thisObject)); > } else if (propertyName == exec->propertyNames().caller) { > if (thisObject->jsExecutable()->isStrictMode()) { >- PropertySlot slot(thisObject); >+ PropertySlot slot(thisObject, PropertySlot::TrapType::VMInquiry); > if (!Base::getOwnPropertySlot(thisObject, exec, propertyName, slot)) > thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec->vm()), DontDelete | DontEnum | Accessor); > return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException); >Index: Source/JavaScriptCore/runtime/JSGenericTypedArrayViewConstructorInlines.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSGenericTypedArrayViewConstructorInlines.h (revision 196658) >+++ Source/JavaScriptCore/runtime/JSGenericTypedArrayViewConstructorInlines.h (working copy) >@@ -150,7 +150,7 @@ static JSObject* constructGenericTypedAr > if (isTypedView(object->classInfo()->typedArrayStorageType)) > length = jsCast<JSArrayBufferView*>(object)->length(); > else { >- PropertySlot lengthSlot(object); >+ PropertySlot lengthSlot(object, PropertySlot::TrapType::Get); > object->getPropertySlot(exec, vm.propertyNames->length, lengthSlot); > > JSValue iteratorFunc = object->get(exec, vm.propertyNames->iteratorSymbol); >Index: Source/JavaScriptCore/runtime/JSGlobalObject.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSGlobalObject.cpp (revision 196658) >+++ Source/JavaScriptCore/runtime/JSGlobalObject.cpp (working copy) >@@ -128,6 +128,8 @@ > #include "ObjectConstructor.h" > #include "ObjectPrototype.h" > #include "ParserError.h" >+#include "ProxyConstructor.h" >+#include "ProxyObject.h" > #include "ReflectObject.h" > #include "RegExpConstructor.h" > #include "RegExpMatchesArray.h" >@@ -366,6 +368,7 @@ void JSGlobalObject::init(VM& vm) > > m_moduleRecordStructure.set(vm, this, JSModuleRecord::createStructure(vm, this, m_objectPrototype.get())); > m_moduleNamespaceObjectStructure.set(vm, this, JSModuleNamespaceObject::createStructure(vm, this, jsNull())); >+ m_proxyObjectStructure.set(vm, this, ProxyObject::createStructure(vm, this, m_objectPrototype.get())); > > #if ENABLE(WEBASSEMBLY) > m_wasmModuleStructure.set(vm, this, JSWASMModule::createStructure(vm, this)); >@@ -454,6 +457,8 @@ m_ ## lowerName ## Prototype->putDirectW > putDirectWithoutTransition(vm, vm.propertyNames->SyntaxError, m_syntaxErrorConstructor.get(), DontEnum); > putDirectWithoutTransition(vm, vm.propertyNames->TypeError, m_typeErrorConstructor.get(), DontEnum); > putDirectWithoutTransition(vm, vm.propertyNames->URIError, m_URIErrorConstructor.get(), DontEnum); >+ >+ putDirectWithoutTransition(vm, vm.propertyNames->Proxy, ProxyConstructor::create(vm, ProxyConstructor::createStructure(vm, this, m_functionPrototype.get())), DontEnum); > > > #define PUT_CONSTRUCTOR_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName) \ >@@ -626,7 +631,7 @@ void JSGlobalObject::put(JSCell* cell, E > bool JSGlobalObject::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow) > { > JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(object); >- PropertySlot slot(thisObject); >+ PropertySlot slot(thisObject, PropertySlot::TrapType::VMInquiry); > // silently ignore attempts to add accessors aliasing vars. > if (descriptor.isAccessorDescriptor() && symbolTableGet(thisObject, propertyName, slot)) > return false; >Index: Source/JavaScriptCore/runtime/JSGlobalObject.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSGlobalObject.h (revision 196658) >+++ Source/JavaScriptCore/runtime/JSGlobalObject.h (working copy) >@@ -277,6 +277,7 @@ protected: > WriteBarrier<Structure> m_regExpMatchesArrayStructure; > WriteBarrier<Structure> m_moduleRecordStructure; > WriteBarrier<Structure> m_moduleNamespaceObjectStructure; >+ WriteBarrier<Structure> m_proxyObjectStructure; > #if ENABLE(WEBASSEMBLY) > WriteBarrier<Structure> m_wasmModuleStructure; > #endif >@@ -529,6 +530,7 @@ public: > Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); } > Structure* moduleRecordStructure() const { return m_moduleRecordStructure.get(); } > Structure* moduleNamespaceObjectStructure() const { return m_moduleNamespaceObjectStructure.get(); } >+ Structure* proxyObjectStructure() const { return m_proxyObjectStructure.get(); } > #if ENABLE(WEBASSEMBLY) > Structure* wasmModuleStructure() const { return m_wasmModuleStructure.get(); } > #endif >@@ -719,7 +721,7 @@ inline JSGlobalObject* asGlobalObject(JS > > inline bool JSGlobalObject::hasOwnPropertyForWrite(ExecState* exec, PropertyName propertyName) > { >- PropertySlot slot(this); >+ PropertySlot slot(this, PropertySlot::TrapType::VMInquiry); > if (Base::getOwnPropertySlot(this, exec, propertyName, slot)) > return true; > bool slotIsWriteable; >Index: Source/JavaScriptCore/runtime/JSModuleEnvironment.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSModuleEnvironment.cpp (revision 196658) >+++ Source/JavaScriptCore/runtime/JSModuleEnvironment.cpp (working copy) >@@ -83,7 +83,7 @@ bool JSModuleEnvironment::getOwnProperty > if (resolution.type == JSModuleRecord::Resolution::Type::Resolved) { > // When resolveImport resolves the resolution, the imported module environment must have the binding. > JSModuleEnvironment* importedModuleEnvironment = resolution.moduleRecord->moduleEnvironment(); >- PropertySlot redirectSlot(importedModuleEnvironment); >+ PropertySlot redirectSlot(importedModuleEnvironment, PropertySlot::TrapType::Get); > bool result = importedModuleEnvironment->methodTable(exec->vm())->getOwnPropertySlot(importedModuleEnvironment, exec, resolution.localName, redirectSlot); > ASSERT_UNUSED(result, result); > ASSERT(redirectSlot.isValue()); >Index: Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp (revision 196658) >+++ Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp (working copy) >@@ -106,7 +106,7 @@ static EncodedJSValue callbackGetter(Exe > JSModuleRecord* targetModule = resolution.moduleRecord; > JSModuleEnvironment* targetEnvironment = targetModule->moduleEnvironment(); > >- PropertySlot trampolineSlot(targetEnvironment); >+ PropertySlot trampolineSlot(targetEnvironment, PropertySlot::TrapType::Get); > if (!targetEnvironment->methodTable(exec->vm())->getOwnPropertySlot(targetEnvironment, exec, resolution.localName, trampolineSlot)) > return JSValue::encode(jsUndefined()); > >Index: Source/JavaScriptCore/runtime/JSONObject.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSONObject.cpp (revision 196658) >+++ Source/JavaScriptCore/runtime/JSONObject.cpp (working copy) >@@ -466,7 +466,7 @@ bool Stringifier::Holder::appendNextProp > if (m_isJSArray && asArray(m_object.get())->canGetIndexQuickly(index)) > value = asArray(m_object.get())->getIndexQuickly(index); > else { >- PropertySlot slot(m_object.get()); >+ PropertySlot slot(m_object.get(), PropertySlot::TrapType::Get); > if (m_object->methodTable()->getOwnPropertySlotByIndex(m_object.get(), exec, index, slot)) { > value = slot.getValue(exec, index); > if (exec->hadException()) >@@ -484,7 +484,7 @@ bool Stringifier::Holder::appendNextProp > stringifyResult = stringifier.appendStringifiedValue(builder, value, m_object.get(), index); > } else { > // Get the value. >- PropertySlot slot(m_object.get()); >+ PropertySlot slot(m_object.get(), PropertySlot::TrapType::Get); > Identifier& propertyName = m_propertyNames->propertyNameVector()[index]; > if (!m_object->methodTable()->getOwnPropertySlot(m_object.get(), exec, propertyName, slot)) > return true; >@@ -618,7 +618,7 @@ NEVER_INLINE JSValue Walker::walk(JSValu > if (isJSArray(array) && array->canGetIndexQuickly(index)) > inValue = array->getIndexQuickly(index); > else { >- PropertySlot slot(array); >+ PropertySlot slot(array, PropertySlot::TrapType::Get); > if (array->methodTable()->getOwnPropertySlotByIndex(array, m_exec, index, slot)) > inValue = slot.getValue(m_exec, index); > else >@@ -670,7 +670,7 @@ NEVER_INLINE JSValue Walker::walk(JSValu > propertyStack.removeLast(); > break; > } >- PropertySlot slot(object); >+ PropertySlot slot(object, PropertySlot::TrapType::Get); > if (object->methodTable()->getOwnPropertySlot(object, m_exec, properties[index], slot)) > inValue = slot.getValue(m_exec, properties[index]); > else >Index: Source/JavaScriptCore/runtime/JSObject.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSObject.cpp (revision 196658) >+++ Source/JavaScriptCore/runtime/JSObject.cpp (working copy) >@@ -264,7 +264,7 @@ String JSObject::calculatedClassName(JSO > { > String prototypeFunctionName; > ExecState* exec = object->globalObject()->globalExec(); >- PropertySlot slot(object->structure()->storedPrototype()); >+ PropertySlot slot(object->structure()->storedPrototype(), PropertySlot::TrapType::VMInquiry); > PropertyName constructor(exec->propertyNames().constructor); > if (object->getPropertySlot(exec, constructor, slot)) { > if (slot.isValue()) { >@@ -1270,15 +1270,17 @@ void JSObject::putDirectNonIndexAccessor > structure->setHasGetterSetterPropertiesWithProtoCheck(propertyName == vm.propertyNames->underscoreProto); > } > >+// HasProperty(O, P) from Section 7.3.10 of the spec. >+// http://www.ecma-international.org/ecma-262/6.0/index.html#sec-hasproperty > bool JSObject::hasProperty(ExecState* exec, PropertyName propertyName) const > { >- PropertySlot slot(this); >+ PropertySlot slot(this, PropertySlot::TrapType::HasProperty); > return const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot); > } > > bool JSObject::hasProperty(ExecState* exec, unsigned propertyName) const > { >- PropertySlot slot(this); >+ PropertySlot slot(this, PropertySlot::TrapType::HasProperty); > return const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot); > } > >@@ -1304,15 +1306,17 @@ bool JSObject::deleteProperty(JSCell* ce > return true; > } > >+// HasOwnProperty(O, P) from section 7.3.11 in the spec. >+// http://www.ecma-international.org/ecma-262/6.0/index.html#sec-hasownproperty > bool JSObject::hasOwnProperty(ExecState* exec, PropertyName propertyName) const > { >- PropertySlot slot(this); >+ PropertySlot slot(this, PropertySlot::TrapType::GetOwnProperty); > return const_cast<JSObject*>(this)->methodTable(exec->vm())->getOwnPropertySlot(const_cast<JSObject*>(this), exec, propertyName, slot); > } > > bool JSObject::hasOwnProperty(ExecState* exec, unsigned propertyName) const > { >- PropertySlot slot(this); >+ PropertySlot slot(this, PropertySlot::TrapType::GetOwnProperty); > return const_cast<JSObject*>(this)->methodTable(exec->vm())->getOwnPropertySlotByIndex(const_cast<JSObject*>(this), exec, propertyName, slot); > } > >@@ -2548,7 +2552,7 @@ static JSBoundSlotBaseFunction* getBound > > bool JSObject::getOwnPropertyDescriptor(ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor) > { >- JSC::PropertySlot slot(this); >+ JSC::PropertySlot slot(this, PropertySlot::TrapType::GetOwnProperty); > if (!methodTable(exec->vm())->getOwnPropertySlot(this, exec, propertyName, slot)) > return false; > >Index: Source/JavaScriptCore/runtime/JSObject.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSObject.h (revision 196658) >+++ Source/JavaScriptCore/runtime/JSObject.h (working copy) >@@ -266,7 +266,7 @@ public: > { > if (JSValue result = tryGetIndexQuickly(i)) > return result; >- PropertySlot slot(this); >+ PropertySlot slot(this, PropertySlot::TrapType::Get); > if (methodTable(exec->vm())->getOwnPropertySlotByIndex(this, exec, i, slot)) > return slot.getValue(exec, i); > return JSValue(); >@@ -1190,7 +1190,7 @@ ALWAYS_INLINE bool JSObject::getProperty > > inline JSValue JSObject::get(ExecState* exec, PropertyName propertyName) const > { >- PropertySlot slot(this); >+ PropertySlot slot(this, PropertySlot::TrapType::Get); > if (const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot)) > return slot.getValue(exec, propertyName); > >@@ -1199,7 +1199,7 @@ inline JSValue JSObject::get(ExecState* > > inline JSValue JSObject::get(ExecState* exec, unsigned propertyName) const > { >- PropertySlot slot(this); >+ PropertySlot slot(this, PropertySlot::TrapType::Get); > if (const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot)) > return slot.getValue(exec, propertyName); > >Index: Source/JavaScriptCore/runtime/JSScope.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSScope.cpp (revision 196658) >+++ Source/JavaScriptCore/runtime/JSScope.cpp (working copy) >@@ -127,7 +127,7 @@ static inline bool abstractAccess(ExecSt > return true; > } > >- PropertySlot slot(globalObject); >+ PropertySlot slot(globalObject, PropertySlot::TrapType::VMInquiry); > bool hasOwnProperty = globalObject->getOwnPropertySlot(globalObject, exec, ident, slot); > if (!hasOwnProperty) { > op = ResolveOp(makeType(UnresolvedProperty, needsVarInjectionChecks), 0, 0, 0, 0, 0); >Index: Source/JavaScriptCore/runtime/ObjectConstructor.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/ObjectConstructor.cpp (revision 196658) >+++ Source/JavaScriptCore/runtime/ObjectConstructor.cpp (working copy) >@@ -331,14 +331,14 @@ bool toPropertyDescriptor(ExecState* exe > } > JSObject* description = asObject(in); > >- PropertySlot enumerableSlot(description); >+ PropertySlot enumerableSlot(description, PropertySlot::TrapType::HasProperty); > if (description->getPropertySlot(exec, exec->propertyNames().enumerable, enumerableSlot)) { > desc.setEnumerable(enumerableSlot.getValue(exec, exec->propertyNames().enumerable).toBoolean(exec)); > if (exec->hadException()) > return false; > } > >- PropertySlot configurableSlot(description); >+ PropertySlot configurableSlot(description, PropertySlot::TrapType::HasProperty); > if (description->getPropertySlot(exec, exec->propertyNames().configurable, configurableSlot)) { > desc.setConfigurable(configurableSlot.getValue(exec, exec->propertyNames().configurable).toBoolean(exec)); > if (exec->hadException()) >@@ -346,21 +346,21 @@ bool toPropertyDescriptor(ExecState* exe > } > > JSValue value; >- PropertySlot valueSlot(description); >+ PropertySlot valueSlot(description, PropertySlot::TrapType::HasProperty); > if (description->getPropertySlot(exec, exec->propertyNames().value, valueSlot)) { > desc.setValue(valueSlot.getValue(exec, exec->propertyNames().value)); > if (exec->hadException()) > return false; > } > >- PropertySlot writableSlot(description); >+ PropertySlot writableSlot(description, PropertySlot::TrapType::HasProperty); > if (description->getPropertySlot(exec, exec->propertyNames().writable, writableSlot)) { > desc.setWritable(writableSlot.getValue(exec, exec->propertyNames().writable).toBoolean(exec)); > if (exec->hadException()) > return false; > } > >- PropertySlot getSlot(description); >+ PropertySlot getSlot(description, PropertySlot::TrapType::HasProperty); > if (description->getPropertySlot(exec, exec->propertyNames().get, getSlot)) { > JSValue get = getSlot.getValue(exec, exec->propertyNames().get); > if (exec->hadException()) >@@ -375,7 +375,7 @@ bool toPropertyDescriptor(ExecState* exe > desc.setGetter(get); > } > >- PropertySlot setSlot(description); >+ PropertySlot setSlot(description, PropertySlot::TrapType::HasProperty); > if (description->getPropertySlot(exec, exec->propertyNames().set, setSlot)) { > JSValue set = setSlot.getValue(exec, exec->propertyNames().set); > if (exec->hadException()) >Index: Source/JavaScriptCore/runtime/ObjectPrototype.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/ObjectPrototype.cpp (revision 196658) >+++ Source/JavaScriptCore/runtime/ObjectPrototype.cpp (working copy) >@@ -174,7 +174,7 @@ EncodedJSValue JSC_HOST_CALL objectProto > if (exec->hadException()) > return JSValue::encode(jsUndefined()); > >- PropertySlot slot(thisObject); >+ PropertySlot slot(thisObject, PropertySlot::TrapType::VMInquiry); > if (thisObject->getPropertySlot(exec, propertyName, slot)) { > if (slot.isAccessor()) { > GetterSetter* getterSetter = slot.getterSetter(); >@@ -201,7 +201,7 @@ EncodedJSValue JSC_HOST_CALL objectProto > if (exec->hadException()) > return JSValue::encode(jsUndefined()); > >- PropertySlot slot(thisObject); >+ PropertySlot slot(thisObject, PropertySlot::TrapType::VMInquiry); > if (thisObject->getPropertySlot(exec, propertyName, slot)) { > if (slot.isAccessor()) { > GetterSetter* getterSetter = slot.getterSetter(); >@@ -264,7 +264,7 @@ EncodedJSValue JSC_HOST_CALL objectProto > JSString* result = thisObject->structure(vm)->objectToStringValue(); > if (!result) { > PropertyName toStringTagSymbol = exec->propertyNames().toStringTagSymbol; >- PropertySlot toStringTagSlot(thisObject); >+ PropertySlot toStringTagSlot(thisObject, PropertySlot::TrapType::Get); > if (thisObject->getPropertySlot(exec, toStringTagSymbol, toStringTagSlot)) { > JSValue stringTag = toStringTagSlot.getValue(exec, toStringTagSymbol); > if (stringTag.isString()) { >Index: Source/JavaScriptCore/runtime/PropertySlot.h >=================================================================== >--- Source/JavaScriptCore/runtime/PropertySlot.h (revision 196658) >+++ Source/JavaScriptCore/runtime/PropertySlot.h (working copy) >@@ -72,13 +72,21 @@ class PropertySlot { > }; > > public: >- explicit PropertySlot(const JSValue thisValue) >- : m_propertyType(TypeUnset) >- , m_offset(invalidOffset) >+ enum class TrapType : uint8_t { >+ Get, // [[Get]] in the spec. >+ HasProperty, // [[HasProperty]] in the spec. >+ GetOwnProperty, // [[GetOwnProperty]] in the spec. >+ VMInquiry, // Our VM is just poking around. When this is the TrapType, getOwnPropertySlot is not allowed to do user observable actions. >+ }; >+ >+ explicit PropertySlot(const JSValue thisValue, TrapType trapType) >+ : m_offset(invalidOffset) > , m_thisValue(thisValue) > , m_slotBase(nullptr) > , m_watchpointSet(nullptr) > , m_cacheability(CachingAllowed) >+ , m_propertyType(TypeUnset) >+ , m_trapType(trapType) > { > } > >@@ -96,6 +104,8 @@ public: > bool isCacheableGetter() const { return isCacheable() && isAccessor(); } > bool isCacheableCustom() const { return isCacheable() && isCustom(); } > >+ TrapType trapType() const { return m_trapType; } >+ > void disableCaching() > { > m_cacheability = CachingDisallowed; >@@ -262,12 +272,13 @@ private: > } custom; > } m_data; > >- PropertyType m_propertyType; > PropertyOffset m_offset; > JSValue m_thisValue; > JSObject* m_slotBase; > WatchpointSet* m_watchpointSet; > CacheabilityType m_cacheability; >+ PropertyType m_propertyType; >+ TrapType m_trapType; > }; > > ALWAYS_INLINE JSValue PropertySlot::getValue(ExecState* exec, PropertyName propertyName) const >Index: Source/JavaScriptCore/runtime/ProxyConstructor.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/ProxyConstructor.cpp (revision 0) >+++ Source/JavaScriptCore/runtime/ProxyConstructor.cpp (working copy) >@@ -0,0 +1,87 @@ >+/* >+ * Copyright (C) 2016 Apple Inc. All Rights Reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "ProxyConstructor.h" >+ >+#include "Error.h" >+#include "JSCJSValueInlines.h" >+#include "JSCellInlines.h" >+#include "ObjectPrototype.h" >+#include "ProxyObject.h" >+#include "StructureInlines.h" >+ >+namespace JSC { >+ >+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ProxyConstructor); >+ >+const ClassInfo ProxyConstructor::s_info = { "Proxy", &Base::s_info, 0, CREATE_METHOD_TABLE(ProxyConstructor) }; >+ >+ProxyConstructor* ProxyConstructor::create(VM& vm, Structure* structure) >+{ >+ ProxyConstructor* constructor = new (NotNull, allocateCell<ProxyConstructor>(vm.heap)) ProxyConstructor(vm, structure); >+ constructor->finishCreation(vm, "Proxy"); >+ return constructor; >+} >+ >+ProxyConstructor::ProxyConstructor(VM& vm, Structure* structure) >+ : Base(vm, structure) >+{ >+} >+ >+void ProxyConstructor::finishCreation(VM& vm, const char* name) >+{ >+ Base::finishCreation(vm, name); >+ >+ putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(2), ReadOnly | DontDelete | DontEnum); >+} >+ >+static EncodedJSValue JSC_HOST_CALL constructProxyObject(ExecState* exec) >+{ >+ if (exec->newTarget().isUndefined()) >+ return throwVMTypeError(exec, ASCIILiteral("new.target of Proxy construct should not be undefined.")); >+ >+ ArgList args(exec); >+ JSValue target = args.at(0); >+ JSValue handler = args.at(1); >+ return JSValue::encode(ProxyObject::create(exec, exec->lexicalGlobalObject()->proxyObjectStructure(), target, handler)); >+} >+ >+ConstructType ProxyConstructor::getConstructData(JSCell*, ConstructData& constructData) >+{ >+ constructData.native.function = constructProxyObject; >+ return ConstructTypeHost; >+} >+ >+CallType ProxyConstructor::getCallData(JSCell*, CallData& callData) >+{ >+ // Proxy should throw a TypeError when called as a function. >+ callData.js.functionExecutable = 0; >+ callData.js.scope = 0; >+ callData.native.function = 0; >+ return CallTypeNone; >+} >+ >+} // namespace JSC >Index: Source/JavaScriptCore/runtime/ProxyConstructor.h >=================================================================== >--- Source/JavaScriptCore/runtime/ProxyConstructor.h (revision 0) >+++ Source/JavaScriptCore/runtime/ProxyConstructor.h (working copy) >@@ -0,0 +1,59 @@ >+/* >+ * Copyright (C) 2016 Apple Inc. All Rights Reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef ProxyConstructor_h >+#define ProxyConstructor_h >+ >+#include "InternalFunction.h" >+ >+namespace JSC { >+ >+class ProxyConstructor : public InternalFunction { >+public: >+ typedef InternalFunction Base; >+ static const unsigned StructureFlags = Base::StructureFlags; >+ >+ static ProxyConstructor* create(VM&, Structure*); >+ >+ DECLARE_INFO; >+ >+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) >+ { >+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); >+ } >+ >+ void finishCreation(VM&, const char* name); >+ >+private: >+ ProxyConstructor(VM&, Structure*); >+ static ConstructType getConstructData(JSCell*, ConstructData&); >+ static CallType getCallData(JSCell*, CallData&); >+ >+ static EncodedJSValue getGetter(ExecState*, EncodedJSValue thisValue, PropertyName); >+}; >+ >+} // namespace JSC >+ >+#endif // ProxyConstructor_h >Index: Source/JavaScriptCore/runtime/ProxyObject.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/ProxyObject.cpp (revision 0) >+++ Source/JavaScriptCore/runtime/ProxyObject.cpp (working copy) >@@ -0,0 +1,168 @@ >+/* >+ * Copyright (C) 2016 Apple Inc. All Rights Reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "ProxyObject.h" >+ >+#include "Error.h" >+#include "JSCJSValueInlines.h" >+#include "JSCellInlines.h" >+#include "SlotVisitorInlines.h" >+#include "StructureInlines.h" >+ >+namespace JSC { >+ >+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ProxyObject); >+ >+const ClassInfo ProxyObject::s_info = { "ProxyObject", &Base::s_info, 0, CREATE_METHOD_TABLE(ProxyObject) }; >+ >+ProxyObject::ProxyObject(VM& vm, Structure* structure) >+ : Base(vm, structure) >+{ >+} >+ >+void ProxyObject::finishCreation(VM& vm, ExecState* exec, JSValue target, JSValue handler) >+{ >+ Base::finishCreation(vm); >+ if (!target.isObject()) { >+ throwTypeError(exec, ASCIILiteral("A Proxy's 'target' should be an Object")); >+ return; >+ } >+ if (ProxyObject* targetAsProxy = jsDynamicCast<ProxyObject*>(target)) { >+ // FIXME: Add tests for this once we implement Proxy.revoke(.). >+ if (targetAsProxy->handler().isNull()) { >+ throwTypeError(exec, ASCIILiteral("If a Proxy's handler is another Proxy object, the other Proxy object must have a non-null handler.")); >+ return; >+ } >+ } >+ if (!handler.isObject()) { >+ throwTypeError(exec, ASCIILiteral("A Proxy's 'handler' should be an Object")); >+ return; >+ } >+ >+ m_target.set(vm, this, jsCast<JSObject*>(target)); >+ m_handler.set(vm, this, handler); >+} >+ >+static EncodedJSValue performProxyGet(ExecState* exec, EncodedJSValue thisValue, PropertyName propertyName) >+{ >+ VM& vm = exec->vm(); >+ JSObject* thisObject = jsCast<JSObject*>(JSValue::decode(thisValue)); // This might be a value where somewhere in __proto__ chain lives a ProxyObject. >+ JSObject* proxyObjectAsObject = thisObject; >+ // FIXME: make it so that custom getters take both the |this| value and the slotBase (property holder). >+ while (true) { >+ if (LIKELY(proxyObjectAsObject->inherits(ProxyObject::info()))) >+ break; >+ >+ Structure& structure = *vm.heap.structureIDTable().get(proxyObjectAsObject->structureID()); >+ JSValue prototype = structure.storedPrototype(); >+ RELEASE_ASSERT(prototype.isObject()); >+ proxyObjectAsObject = asObject(prototype); >+ } >+ >+ ProxyObject* proxyObject = jsCast<ProxyObject*>(proxyObjectAsObject); >+ JSValue handlerValue = proxyObject->handler(); >+ if (handlerValue.isNull()) >+ return throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object.")); >+ >+ JSObject* handler = jsCast<JSObject*>(handlerValue); >+ JSObject* target = proxyObject->target(); >+ JSValue getHandler = handler->get(exec, vm.propertyNames->get); >+ if (exec->hadException()) >+ return JSValue::encode(jsUndefined()); >+ >+ if (getHandler.isUndefined()) >+ return JSValue::encode(target->get(exec, propertyName)); >+ >+ if (!getHandler.isCell()) >+ return throwVMTypeError(exec, ASCIILiteral("'get' property of Proxy's handler should be callable.")); >+ >+ CallData callData; >+ CallType callType = getHandler.asCell()->methodTable()->getCallData(getHandler.asCell(), callData); >+ if (callType == CallTypeNone) >+ return throwVMTypeError(exec, ASCIILiteral("'get' property of Proxy's handler should be callable.")); >+ >+ MarkedArgumentBuffer arguments; >+ arguments.append(target); >+ arguments.append(jsString(exec, propertyName.uid())); >+ arguments.append(thisObject); >+ JSValue trapResult = call(exec, getHandler, callType, callData, handler, arguments); >+ if (exec->hadException()) >+ return JSValue::encode(jsUndefined()); >+ >+ PropertyDescriptor descriptor; >+ if (target->getOwnPropertyDescriptor(exec, propertyName, descriptor)) { >+ if (descriptor.isDataDescriptor() && !descriptor.configurable() && !descriptor.writable()) { >+ if (!sameValue(exec, descriptor.value(), trapResult)) >+ return throwVMTypeError(exec, ASCIILiteral("Proxy handler's 'get' result of a non-configurable and non-writable property should be the same value as the target's property.")); >+ } else if (descriptor.isAccessorDescriptor() && !descriptor.configurable() && descriptor.getter().isUndefined()) { >+ if (!trapResult.isUndefined()) >+ return throwVMTypeError(exec, ASCIILiteral("Proxy handler's 'get' result of a non-configurable accessor property without a getter should be undefined.")); >+ } >+ } >+ >+ // FIXME: when implementing Proxy.[[GetOwnProperty]] it would be a good test to >+ // have handler be another Proxy where its handler throws on [[GetOwnProperty]] >+ // right here. >+ if (exec->hadException()) >+ return JSValue::encode(jsUndefined()); >+ >+ return JSValue::encode(trapResult); >+} >+ >+bool ProxyObject::getOwnPropertySlotCommon(ExecState*, PropertySlot& slot) >+{ >+ if (slot.trapType() == PropertySlot::TrapType::Get) { >+ slot.setCustom(this, CustomAccessor, performProxyGet); >+ slot.disableCaching(); >+ return true; >+ } >+ >+ // FIXME: Implement other proxy traps. >+ return false; >+} >+bool ProxyObject::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName, PropertySlot& slot) >+{ >+ ProxyObject* thisObject = jsCast<ProxyObject*>(object); >+ return thisObject->getOwnPropertySlotCommon(exec, slot); >+} >+ >+bool ProxyObject::getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned, PropertySlot& slot) >+{ >+ ProxyObject* thisObject = jsCast<ProxyObject*>(object); >+ return thisObject->getOwnPropertySlotCommon(exec, slot); >+} >+ >+void ProxyObject::visitChildren(JSCell* cell, SlotVisitor& visitor) >+{ >+ ProxyObject* thisObject = jsCast<ProxyObject*>(cell); >+ ASSERT_GC_OBJECT_INHERITS(thisObject, info()); >+ Base::visitChildren(thisObject, visitor); >+ >+ visitor.append(&thisObject->m_target); >+ visitor.append(&thisObject->m_handler); >+} >+ >+} // namespace JSC >Index: Source/JavaScriptCore/runtime/ProxyObject.h >=================================================================== >--- Source/JavaScriptCore/runtime/ProxyObject.h (revision 0) >+++ Source/JavaScriptCore/runtime/ProxyObject.h (working copy) >@@ -0,0 +1,74 @@ >+/* >+ * Copyright (C) 2016 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef ProxyObject_h >+#define ProxyObject_h >+ >+#include "JSGlobalObject.h" >+#include "JSObject.h" >+ >+namespace JSC { >+ >+class ProxyObject : public JSNonFinalObject { >+public: >+ typedef JSNonFinalObject Base; >+ >+ const static unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot; >+ >+ static ProxyObject* create(ExecState* exec, Structure* structure, JSValue target, JSValue handler) >+ { >+ VM& vm = exec->vm(); >+ ProxyObject* proxy = new (NotNull, allocateCell<ProxyObject>(vm.heap)) ProxyObject(vm, structure); >+ proxy->finishCreation(vm, exec, target, handler); >+ return proxy; >+ } >+ >+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) >+ { >+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); >+ } >+ >+ DECLARE_EXPORT_INFO; >+ >+ JSObject* target() { return m_target.get(); } >+ JSValue handler() { return m_handler.get(); } >+ >+private: >+ ProxyObject(VM&, Structure*); >+ void finishCreation(VM&, ExecState*, JSValue target, JSValue handler); >+ >+ static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); >+ static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&); >+ static void visitChildren(JSCell*, SlotVisitor&); >+ >+ bool getOwnPropertySlotCommon(ExecState*, PropertySlot&); >+ >+ WriteBarrier<JSObject> m_target; >+ WriteBarrier<Unknown> m_handler; >+}; >+ >+} // namespace JSC >+ >+#endif // JSPromise_h >Index: Source/JavaScriptCore/runtime/ReflectObject.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/ReflectObject.cpp (revision 196658) >+++ Source/JavaScriptCore/runtime/ReflectObject.cpp (working copy) >@@ -135,7 +135,7 @@ EncodedJSValue JSC_HOST_CALL reflectObje > if (exec->argumentCount() >= 3) > receiver = exec->argument(2); > >- PropertySlot slot(receiver); >+ PropertySlot slot(receiver, PropertySlot::TrapType::Get); > return JSValue::encode(target.get(exec, propertyName, slot)); > } > >Index: Source/JavaScriptCore/runtime/SamplingProfiler.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/SamplingProfiler.cpp (revision 196658) >+++ Source/JavaScriptCore/runtime/SamplingProfiler.cpp (working copy) >@@ -581,7 +581,7 @@ String SamplingProfiler::StackFrame::nam > > ExecState* exec = callee->globalObject()->globalExec(); > auto getPropertyIfPureOperation = [&] (const Identifier& ident) -> String { >- PropertySlot slot(callee); >+ PropertySlot slot(callee, PropertySlot::TrapType::VMInquiry); > PropertyName propertyName(ident); > if (callee->getPropertySlot(exec, propertyName, slot)) { > if (slot.isValue()) { >Index: Source/JavaScriptCore/tests/es6.yaml >=================================================================== >--- Source/JavaScriptCore/tests/es6.yaml (revision 196658) >+++ Source/JavaScriptCore/tests/es6.yaml (working copy) >@@ -913,7 +913,7 @@ > - path: es6/Proxy_construct_handler.js > cmd: runES6 :fail > - path: es6/Proxy_constructor_requires_new.js >- cmd: runES6 :fail >+ cmd: runES6 :normal > - path: es6/Proxy_defineProperty_handler.js > cmd: runES6 :fail > - path: es6/Proxy_deleteProperty_handler.js >@@ -921,9 +921,9 @@ > - path: es6/Proxy_enumerate_handler.js > cmd: runES6 :fail > - path: es6/Proxy_get_handler.js >- cmd: runES6 :fail >+ cmd: runES6 :normal > - path: es6/Proxy_get_handler_instances_of_proxies.js >- cmd: runES6 :fail >+ cmd: runES6 :normal > - path: es6/Proxy_getOwnPropertyDescriptor_handler.js > cmd: runES6 :fail > - path: es6/Proxy_getPrototypeOf_handler.js >@@ -953,27 +953,27 @@ > - path: es6/Proxy_internal_get_calls_Array.prototype.concat.js > cmd: runES6 :fail > - path: es6/Proxy_internal_get_calls_Array.prototype.pop.js >- cmd: runES6 :fail >+ cmd: runES6 :normal > - path: es6/Proxy_internal_get_calls_Array.prototype.reverse.js > cmd: runES6 :fail > - path: es6/Proxy_internal_get_calls_Array.prototype.shift.js >- cmd: runES6 :fail >+ cmd: runES6 :normal > - path: es6/Proxy_internal_get_calls_Array.prototype.splice.js > cmd: runES6 :fail > - path: es6/Proxy_internal_get_calls_Array.prototype.toString.js >- cmd: runES6 :fail >+ cmd: runES6 :normal > - path: es6/Proxy_internal_get_calls_Array.prototype_iteration_methods.js > cmd: runES6 :fail > - path: es6/Proxy_internal_get_calls_ClassDefinitionEvaluation.js >- cmd: runES6 :fail >+ cmd: runES6 :normal > - path: es6/Proxy_internal_get_calls_CreateDynamicFunction.js > cmd: runES6 :fail > - path: es6/Proxy_internal_get_calls_CreateListFromArrayLike.js >- cmd: runES6 :fail >+ cmd: runES6 :normal > - path: es6/Proxy_internal_get_calls_Date.prototype.toJSON.js > cmd: runES6 :fail > - path: es6/Proxy_internal_get_calls_Error.prototype.toString.js >- cmd: runES6 :fail >+ cmd: runES6 :normal > - path: es6/Proxy_internal_get_calls_Function.prototype.bind.js > cmd: runES6 :fail > - path: es6/Proxy_internal_get_calls_HasBinding.js >@@ -981,7 +981,7 @@ > - path: es6/Proxy_internal_get_calls_instanceof_operator.js > cmd: runES6 :fail > - path: es6/Proxy_internal_get_calls_IteratorComplete_IteratorValue.js >- cmd: runES6 :fail >+ cmd: runES6 :normal > - path: es6/Proxy_internal_get_calls_JSON.stringify.js > cmd: runES6 :fail > - path: es6/Proxy_internal_get_calls_Object.assign.js >@@ -989,7 +989,7 @@ > - path: es6/Proxy_internal_get_calls_Object.defineProperties.js > cmd: runES6 :fail > - path: es6/Proxy_internal_get_calls_Promise_resolve_functions.js >- cmd: runES6 :fail >+ cmd: runES6 :normal > - path: es6/Proxy_internal_get_calls_RegExp.prototype.flags.js > cmd: runES6 :fail > - path: es6/Proxy_internal_get_calls_RegExp.prototype.test.js >@@ -1013,7 +1013,7 @@ > - path: es6/Proxy_internal_get_calls_String.prototype.split.js > cmd: runES6 :fail > - path: es6/Proxy_internal_get_calls_String.raw.js >- cmd: runES6 :fail >+ cmd: runES6 :normal > - path: es6/Proxy_internal_get_calls_ToPrimitive.js > cmd: runES6 :fail > - path: es6/Proxy_internal_get_calls_ToPropertyDescriptor.js >@@ -1221,4 +1221,4 @@ > - path: es6/Object_static_methods_Object.getOwnPropertyDescriptors.js > cmd: runES6 :normal > - path: es6/Object_static_methods_Object.getOwnPropertyDescriptors-proxy.js >- cmd: runES6 :fail >\ No newline at end of file >+ cmd: runES6 :fail >Index: Source/JavaScriptCore/tests/stress/proxy-basic.js >=================================================================== >--- Source/JavaScriptCore/tests/stress/proxy-basic.js (revision 0) >+++ Source/JavaScriptCore/tests/stress/proxy-basic.js (working copy) >@@ -0,0 +1,135 @@ >+function assert(b) { >+ if (!b) >+ throw new Error("Bad assertion"); >+} >+ >+assert(Proxy instanceof Function); >+assert(Proxy.length === 2); >+assert(Proxy.prototype === undefined); >+ >+{ >+ for (let i = 0; i < 1000; i++) >+ assert((new Proxy({}, {})).__proto__ === Object.prototype); >+} >+ >+{ >+ // When we call Proxy it should throw >+ for (let i = 0; i < 100; i++) { >+ let threw = false; >+ try { >+ Proxy({}, {}); >+ } catch(e) { >+ threw = true; >+ assert(e.toString() === "TypeError: Proxy is not a function. (In 'Proxy({}, {})', 'Proxy' is an instance of Function)"); >+ } >+ assert(threw === true); >+ } >+ >+ let theTarget = { >+ x: 30 >+ }; >+ >+ let handler = { >+ get: function(target, propName, proxyArg) { >+ assert(target === theTarget); >+ assert(proxyArg === proxy); >+ if (propName === "y") >+ return 45; >+ assert(propName === "x"); >+ return target[propName]; >+ } >+ }; >+ >+ let proxy = new Proxy(theTarget, handler); >+ for (let i = 0; i < 1000; i++) { >+ assert(proxy.x === 30); >+ assert(proxy.y === 45); >+ assert(proxy["x"] === 30); >+ assert(proxy["y"] === 45); >+ } >+ >+} >+ >+{ >+ let handler = {get: null}; >+ let target = {x: 20}; >+ let proxy = new Proxy(target, handler); >+ for (let i = 0; i < 500; i++) { >+ let threw = false; >+ try { >+ if (i % 2) >+ proxy.foo; >+ else >+ proxy["foo"]; >+ } catch(e) { >+ threw = true; >+ assert(e.toString() === "TypeError: 'get' property of Proxy's handler should be callable."); >+ } >+ assert(threw); >+ } >+} >+ >+{ >+ let handler = {get: {}}; >+ let target = {x: 20}; >+ let proxy = new Proxy(target, handler); >+ for (let i = 0; i < 500; i++) { >+ let threw = false; >+ try { >+ if (i % 2) >+ proxy.foo; >+ else >+ proxy["foo"]; >+ } catch(e) { >+ threw = true; >+ assert(e.toString() === "TypeError: 'get' property of Proxy's handler should be callable."); >+ } >+ assert(threw); >+ } >+} >+ >+{ >+ let handler = {}; >+ let target = {x: 20}; >+ let proxy = new Proxy(target, handler); >+ for (let i = 0; i < 500; i++) { >+ assert(proxy.x === 20); >+ assert(proxy.y === undefined); >+ } >+} >+ >+{ >+ let handler = {}; >+ let target = [1, 2, 3]; >+ let proxy = new Proxy(target, handler); >+ for (let i = 0; i < 500; i++) { >+ assert(proxy[0] === 1); >+ assert(proxy[1] === 2); >+ assert(proxy[2] === 3); >+ } >+} >+ >+{ >+ let theTarget = [1, 2, 3]; >+ let handler = { >+ get: function(target, propName, proxyArg) { >+ switch (propName) { >+ case "0": >+ case "1": >+ return 100; >+ case "2": >+ case "length": >+ return target[propName]; >+ } >+ assert(false); >+ } >+ }; >+ let proxy = new Proxy(theTarget, handler); >+ for (let i = 0; i < 500; i++) { >+ assert(proxy[0] === 100); >+ assert(proxy[1] === 100); >+ assert(proxy[2] === 3); >+ assert(proxy.length === 3); >+ assert(proxy["length"] === 3); >+ } >+} >Index: Source/JavaScriptCore/tests/stress/proxy-in-proto-chain.js >=================================================================== >--- Source/JavaScriptCore/tests/stress/proxy-in-proto-chain.js (revision 0) >+++ Source/JavaScriptCore/tests/stress/proxy-in-proto-chain.js (working copy) >@@ -0,0 +1,28 @@ >+function assert(b) { >+ if (!b) >+ throw new Error("Bad assertion"); >+} >+ >+let theTarget = { >+ x: 30 >+}; >+ >+let handler = { >+ get: function(target, propName, proxyArg) { >+ assert(target === theTarget); >+ assert(proxyArg === obj); >+ if (propName === "y") >+ return 45; >+ assert(propName === "x"); >+ return target[propName]; >+ } >+}; >+ >+let proxy = new Proxy(theTarget, handler); >+ >+let obj = Object.create(proxy); >+ >+for (let i = 0; i < 1000; i++) { >+ assert(obj.x === 30); >+ assert(obj.y === 45); >+} >Index: Source/JavaScriptCore/tests/stress/proxy-property-descriptor.js >=================================================================== >--- Source/JavaScriptCore/tests/stress/proxy-property-descriptor.js (revision 0) >+++ Source/JavaScriptCore/tests/stress/proxy-property-descriptor.js (working copy) >@@ -0,0 +1,83 @@ >+function assert(b) { >+ if (!b) >+ throw new Error("Bad assertion"); >+} >+ >+let theTarget = {}; >+Object.defineProperty(theTarget, "x", { >+ writable: false, >+ configurable: false, >+ value: 45 >+}); >+ >+Object.defineProperty(theTarget, "y", { >+ writable: false, >+ configurable: false, >+ value: 45 >+}); >+ >+Object.defineProperty(theTarget, "getter", { >+ configurable: false, >+ set: function(x) { } >+}); >+ >+Object.defineProperty(theTarget, "badGetter", { >+ configurable: false, >+ set: function(x) { } >+}); >+ >+let handler = { >+ get: function(target, propName, proxyArg) { >+ assert(target === theTarget); >+ assert(proxyArg === proxy); >+ if (propName === "x") >+ return 45; >+ else if (propName === "y") >+ return 30; >+ else if (propName === "getter") >+ return undefined; >+ else { >+ assert(propName === "badGetter"); >+ return 25; >+ } >+ } >+}; >+ >+let proxy = new Proxy(theTarget, handler); >+ >+for (let i = 0; i < 1000; i++) { >+ assert(proxy.x === 45); >+ assert(proxy["x"] === 45); >+} >+ >+for (let i = 0; i < 1000; i++) { >+ try { >+ if (i % 2) >+ proxy.y; >+ else >+ proxy["y"]; >+ } catch(e) { >+ threw = true; >+ assert(e.toString() === "TypeError: Proxy handler's 'get' result of a non-configurable and non-writable property should be the same value as the target's property."); >+ } >+ assert(threw === true); >+} >+ >+for (let i = 0; i < 1000; i++) { >+ assert(proxy.getter === undefined); >+ assert(proxy["getter"] === undefined); >+} >+ >+for (let i = 0; i < 1000; i++) { >+ try { >+ if (i % 2) >+ proxy.badGetter; >+ else >+ proxy["badGetter"]; >+ >+ } catch(e) { >+ threw = true; >+ assert(e.toString() === "TypeError: Proxy handler's 'get' result of a non-configurable accessor property without a getter should be undefined."); >+ } >+ assert(threw === true); >+} >Index: Source/JavaScriptCore/wasm/WASMModuleParser.cpp >=================================================================== >--- Source/JavaScriptCore/wasm/WASMModuleParser.cpp (revision 196658) >+++ Source/JavaScriptCore/wasm/WASMModuleParser.cpp (working copy) >@@ -358,7 +358,7 @@ void WASMModuleParser::getImportedValue( > { > FAIL_IF_FALSE(m_imports, "Accessing property of non-object."); > Identifier identifier = Identifier::fromString(&m_vm, importName); >- PropertySlot slot(m_imports.get()); >+ PropertySlot slot(m_imports.get(), PropertySlot::TrapType::Get); > if (!m_imports->getPropertySlot(exec, identifier, slot)) > FAIL_WITH_MESSAGE("Can't find a property named \"" + importName + '"'); > FAIL_IF_FALSE(slot.isValue(), "\"" + importName + "\" is not a data property."); >Index: Source/WebCore/ChangeLog >=================================================================== >--- Source/WebCore/ChangeLog (revision 196658) >+++ Source/WebCore/ChangeLog (working copy) >@@ -1,3 +1,30 @@ >+2016-02-16 Saam barati <sbarati@apple.com> >+ >+ Implement Proxy [[Get]] >+ https://bugs.webkit.org/show_bug.cgi?id=154081 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * bindings/js/JSCryptoAlgorithmDictionary.cpp: >+ (WebCore::getProperty): >+ (WebCore::getHashAlgorithm): >+ * bindings/js/JSCryptoKeySerializationJWK.cpp: >+ (WebCore::getJSArrayFromJSON): >+ (WebCore::getStringFromJSON): >+ (WebCore::getBooleanFromJSON): >+ * bindings/js/JSDOMWindowCustom.cpp: >+ (WebCore::DialogHandler::returnValue): >+ * bindings/js/JSDictionary.cpp: >+ (WebCore::JSDictionary::tryGetProperty): >+ * bindings/js/JSStorageCustom.cpp: >+ (WebCore::JSStorage::deleteProperty): >+ (WebCore::JSStorage::deletePropertyByIndex): >+ (WebCore::JSStorage::putDelegate): >+ * bindings/js/SerializedScriptValue.cpp: >+ (WebCore::CloneSerializer::getProperty): >+ * testing/Internals.cpp: >+ (WebCore::Internals::isReadableStreamDisturbed): >+ > 2016-02-16 Alex Christensen <achristensen@webkit.org> > > Add checks before redirecting with NetworkSession >Index: Source/WebCore/bindings/js/JSCryptoAlgorithmDictionary.cpp >=================================================================== >--- Source/WebCore/bindings/js/JSCryptoAlgorithmDictionary.cpp (revision 196658) >+++ Source/WebCore/bindings/js/JSCryptoAlgorithmDictionary.cpp (working copy) >@@ -95,7 +95,7 @@ bool JSCryptoAlgorithmDictionary::getAlg > static JSValue getProperty(ExecState* exec, JSObject* object, const char* name) > { > Identifier identifier = Identifier::fromString(exec, name); >- PropertySlot slot(object); >+ PropertySlot slot(object, PropertySlot::TrapType::Get); > > if (object->getPropertySlot(exec, identifier, slot)) > return slot.getValue(exec, identifier); >@@ -111,7 +111,6 @@ static bool getHashAlgorithm(JSDictionar > JSObject* object = dictionary.initializerObject(); > > Identifier identifier = Identifier::fromString(exec, "hash"); >- PropertySlot slot(object); > > JSValue hash = getProperty(exec, object, "hash"); > if (exec->hadException()) >Index: Source/WebCore/bindings/js/JSCryptoKeySerializationJWK.cpp >=================================================================== >--- Source/WebCore/bindings/js/JSCryptoKeySerializationJWK.cpp (revision 196658) >+++ Source/WebCore/bindings/js/JSCryptoKeySerializationJWK.cpp (working copy) >@@ -53,7 +53,7 @@ namespace WebCore { > static bool getJSArrayFromJSON(ExecState* exec, JSObject* json, const char* key, JSArray*& result) > { > Identifier identifier = Identifier::fromString(exec, key); >- PropertySlot slot(json); >+ PropertySlot slot(json, PropertySlot::TrapType::Get); > > if (!json->getPropertySlot(exec, identifier, slot)) > return false; >@@ -73,7 +73,7 @@ static bool getJSArrayFromJSON(ExecState > static bool getStringFromJSON(ExecState* exec, JSObject* json, const char* key, String& result) > { > Identifier identifier = Identifier::fromString(exec, key); >- PropertySlot slot(json); >+ PropertySlot slot(json, PropertySlot::TrapType::Get); > > if (!json->getPropertySlot(exec, identifier, slot)) > return false; >@@ -94,7 +94,7 @@ static bool getStringFromJSON(ExecState* > static bool getBooleanFromJSON(ExecState* exec, JSObject* json, const char* key, bool& result) > { > Identifier identifier = Identifier::fromString(exec, key); >- PropertySlot slot(json); >+ PropertySlot slot(json, PropertySlot::TrapType::Get); > > if (!json->getPropertySlot(exec, identifier, slot)) > return false; >Index: Source/WebCore/bindings/js/JSDOMWindowCustom.cpp >=================================================================== >--- Source/WebCore/bindings/js/JSDOMWindowCustom.cpp (revision 196658) >+++ Source/WebCore/bindings/js/JSDOMWindowCustom.cpp (working copy) >@@ -573,7 +573,7 @@ inline JSValue DialogHandler::returnValu > if (!globalObject) > return jsUndefined(); > Identifier identifier = Identifier::fromString(&m_exec, "returnValue"); >- PropertySlot slot(globalObject); >+ PropertySlot slot(globalObject, PropertySlot::TrapType::Get); > if (!JSGlobalObject::getOwnPropertySlot(globalObject, &m_exec, identifier, slot)) > return jsUndefined(); > return slot.getValue(&m_exec, identifier); >Index: Source/WebCore/bindings/js/JSDictionary.cpp >=================================================================== >--- Source/WebCore/bindings/js/JSDictionary.cpp (revision 196658) >+++ Source/WebCore/bindings/js/JSDictionary.cpp (working copy) >@@ -70,7 +70,7 @@ JSDictionary::GetPropertyResult JSDictio > { > ASSERT(isValid()); > Identifier identifier = Identifier::fromString(m_exec, propertyName); >- PropertySlot slot(m_initializerObject.get()); >+ PropertySlot slot(m_initializerObject.get(), PropertySlot::TrapType::Get); > > if (!m_initializerObject.get()->getPropertySlot(m_exec, identifier, slot)) > return NoPropertyFound; >Index: Source/WebCore/bindings/js/JSStorageCustom.cpp >=================================================================== >--- Source/WebCore/bindings/js/JSStorageCustom.cpp (revision 196658) >+++ Source/WebCore/bindings/js/JSStorageCustom.cpp (working copy) >@@ -57,7 +57,7 @@ bool JSStorage::deleteProperty(JSCell* c > // Only perform the custom delete if the object doesn't have a native property by this name. > // Since hasProperty() would end up calling canGetItemsForName() and be fooled, we need to check > // the native property slots manually. >- PropertySlot slot(thisObject); >+ PropertySlot slot(thisObject, PropertySlot::TrapType::GetOwnProperty); > > static_assert(!hasStaticPropertyTable, "This function does not handle static instance properties"); > >@@ -76,8 +76,6 @@ bool JSStorage::deleteProperty(JSCell* c > > bool JSStorage::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned propertyName) > { >- JSStorage* thisObject = jsCast<JSStorage*>(cell); >- PropertySlot slot(thisObject); > static_assert(!hasStaticPropertyTable, "This function does not handle static instance properties"); > return deleteProperty(cell, exec, Identifier::from(exec, propertyName)); > } >@@ -105,7 +103,7 @@ bool JSStorage::putDelegate(ExecState* e > // Only perform the custom put if the object doesn't have a native property by this name. > // Since hasProperty() would end up calling canGetItemsForName() and be fooled, we need to check > // the native property slots manually. >- PropertySlot slot(this); >+ PropertySlot slot(this, PropertySlot::TrapType::GetOwnProperty); > static_assert(!hasStaticPropertyTable, "This function does not handle static instance properties"); > > JSValue prototype = this->prototype(); >Index: Source/WebCore/bindings/js/SerializedScriptValue.cpp >=================================================================== >--- Source/WebCore/bindings/js/SerializedScriptValue.cpp (revision 196658) >+++ Source/WebCore/bindings/js/SerializedScriptValue.cpp (working copy) >@@ -641,7 +641,7 @@ private: > > JSValue getProperty(JSObject* object, const Identifier& propertyName) > { >- PropertySlot slot(object); >+ PropertySlot slot(object, PropertySlot::TrapType::Get); > if (object->methodTable()->getOwnPropertySlot(object, m_exec, propertyName, slot)) > return slot.getValue(m_exec, propertyName); > return JSValue(); >Index: Source/WebCore/testing/Internals.cpp >=================================================================== >--- Source/WebCore/testing/Internals.cpp (revision 196658) >+++ Source/WebCore/testing/Internals.cpp (working copy) >@@ -3443,7 +3443,7 @@ bool Internals::isReadableStreamDisturbe > JSVMClientData* clientData = static_cast<JSVMClientData*>(state.vm().clientData); > const Identifier& privateName = clientData->builtinFunctions().readableStreamInternalsBuiltins().isReadableStreamDisturbedPrivateName(); > JSValue value; >- PropertySlot propertySlot(value); >+ PropertySlot propertySlot(value, PropertySlot::TrapType::Get); > globalObject->fastGetOwnPropertySlot(&state, state.vm(), *globalObject->structure(), privateName, propertySlot); > value = propertySlot.getValue(&state, privateName); > ASSERT(value.isFunction());
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
buildbot
:
commit-queue-
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 154081
:
271313
|
271397
|
271444
|
271448
|
271454
|
271473
|
271493
|
271507
|
271518