Commit 6884841a authored by oliver@apple.com's avatar oliver@apple.com

Refactor PutPropertySlot to be aware of custom properties

https://bugs.webkit.org/show_bug.cgi?id=126187

Reviewed by Antti Koivisto.

Source/JavaScriptCore:

Refactor PutPropertySlot, making the constructor take the thisValue
used as a target.  This results in a wide range of boilerplate changes
to pass the new parameter.

* API/JSObjectRef.cpp:
(JSObjectSetProperty):
* dfg/DFGOperations.cpp:
(JSC::DFG::operationPutByValInternal):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
* jit/JITOperations.cpp:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* runtime/Arguments.cpp:
(JSC::Arguments::putByIndex):
* runtime/ArrayPrototype.cpp:
(JSC::putProperty):
(JSC::arrayProtoFuncPush):
* runtime/JSCJSValue.cpp:
(JSC::JSValue::putToPrimitiveByIndex):
* runtime/JSCell.cpp:
(JSC::JSCell::putByIndex):
* runtime/JSFunction.cpp:
(JSC::JSFunction::put):
* runtime/JSGenericTypedArrayViewInlines.h:
(JSC::JSGenericTypedArrayView<Adaptor>::putByIndex):
* runtime/JSONObject.cpp:
(JSC::Walker::walk):
* runtime/JSObject.cpp:
(JSC::JSObject::putByIndex):
(JSC::JSObject::putDirectNonIndexAccessor):
(JSC::JSObject::deleteProperty):
* runtime/JSObject.h:
(JSC::JSObject::putDirect):
* runtime/Lookup.h:
(JSC::putEntry):
(JSC::lookupPut):
* runtime/PutPropertySlot.h:
(JSC::PutPropertySlot::PutPropertySlot):
(JSC::PutPropertySlot::setCustomProperty):
(JSC::PutPropertySlot::thisValue):
(JSC::PutPropertySlot::isCacheable):

Source/WebCore:

Update the bindings code generation and custom objects
to the new function signatures

* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::JSDOMWindow::put):
* bindings/objc/WebScriptObject.mm:
(-[WebScriptObject setValue:forKey:]):
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateImplementation):
* bindings/scripts/test/JS/JSTestInterface.cpp:
(WebCore::JSTestInterface::putByIndex):
* bridge/NP_jsobject.cpp:
(_NPN_SetProperty):

Source/WebKit/mac:

Update for new method signatures.

* Plugins/Hosted/NetscapePluginInstanceProxy.mm:
(WebKit::NetscapePluginInstanceProxy::setProperty):

Source/WebKit2:

Update for new method signatures.

* WebProcess/Plugins/Netscape/NPJSObject.cpp:
(WebKit::NPJSObject::setProperty):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@161220 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 9775655d
......@@ -331,7 +331,7 @@ void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope
PropertyDescriptor desc(jsValue, attributes);
jsObject->methodTable()->defineOwnProperty(jsObject, exec, name, desc, false);
} else {
PutPropertySlot slot;
PutPropertySlot slot(jsObject);
jsObject->methodTable()->put(jsObject, exec, name, jsValue, slot);
}
......
2013-12-23 Oliver Hunt <oliver@apple.com>
Refactor PutPropertySlot to be aware of custom properties
https://bugs.webkit.org/show_bug.cgi?id=126187
Reviewed by Antti Koivisto.
Refactor PutPropertySlot, making the constructor take the thisValue
used as a target. This results in a wide range of boilerplate changes
to pass the new parameter.
* API/JSObjectRef.cpp:
(JSObjectSetProperty):
* dfg/DFGOperations.cpp:
(JSC::DFG::operationPutByValInternal):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
* jit/JITOperations.cpp:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* runtime/Arguments.cpp:
(JSC::Arguments::putByIndex):
* runtime/ArrayPrototype.cpp:
(JSC::putProperty):
(JSC::arrayProtoFuncPush):
* runtime/JSCJSValue.cpp:
(JSC::JSValue::putToPrimitiveByIndex):
* runtime/JSCell.cpp:
(JSC::JSCell::putByIndex):
* runtime/JSFunction.cpp:
(JSC::JSFunction::put):
* runtime/JSGenericTypedArrayViewInlines.h:
(JSC::JSGenericTypedArrayView<Adaptor>::putByIndex):
* runtime/JSONObject.cpp:
(JSC::Walker::walk):
* runtime/JSObject.cpp:
(JSC::JSObject::putByIndex):
(JSC::JSObject::putDirectNonIndexAccessor):
(JSC::JSObject::deleteProperty):
* runtime/JSObject.h:
(JSC::JSObject::putDirect):
* runtime/Lookup.h:
(JSC::putEntry):
(JSC::lookupPut):
* runtime/PutPropertySlot.h:
(JSC::PutPropertySlot::PutPropertySlot):
(JSC::PutPropertySlot::setCustomProperty):
(JSC::PutPropertySlot::thisValue):
(JSC::PutPropertySlot::isCacheable):
2014-01-01 Filip Pizlo <fpizlo@apple.com>
Rationalize DFG DCE
......
......@@ -110,7 +110,7 @@ ALWAYS_INLINE static void JIT_OPERATION operationPutByValInternal(ExecState* exe
}
if (isName(property)) {
PutPropertySlot slot(strict);
PutPropertySlot slot(baseValue, strict);
if (direct) {
RELEASE_ASSERT(baseValue.isObject());
asObject(baseValue)->putDirect(*vm, jsCast<NameInstance*>(property.asCell())->privateName(), value, slot);
......@@ -122,7 +122,7 @@ ALWAYS_INLINE static void JIT_OPERATION operationPutByValInternal(ExecState* exe
// Don't put to an object if toString throws an exception.
Identifier ident(exec, property.toString(exec)->value(exec));
if (!vm->exception()) {
PutPropertySlot slot(strict);
PutPropertySlot slot(baseValue, strict);
if (direct) {
RELEASE_ASSERT(baseValue.isObject());
asObject(baseValue)->putDirect(*vm, jsCast<NameInstance*>(property.asCell())->privateName(), value, slot);
......@@ -399,7 +399,7 @@ void JIT_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSO
return;
}
PutPropertySlot slot(true);
PutPropertySlot slot(array, true);
array->methodTable()->put(
array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
}
......@@ -414,7 +414,7 @@ void JIT_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec,
return;
}
PutPropertySlot slot(false);
PutPropertySlot slot(array, false);
array->methodTable()->put(
array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
}
......@@ -431,7 +431,7 @@ void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState* exe
return;
}
PutPropertySlot slot(true);
PutPropertySlot slot(array, true);
array->methodTable()->put(
array, exec, Identifier::from(exec, index), jsValue, slot);
}
......@@ -448,7 +448,7 @@ void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState*
return;
}
PutPropertySlot slot(false);
PutPropertySlot slot(array, false);
array->methodTable()->put(
array, exec, Identifier::from(exec, index), jsValue, slot);
}
......@@ -494,7 +494,7 @@ void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsStrict(ExecState* exe
return;
}
PutPropertySlot slot(true);
PutPropertySlot slot(array, true);
array->putDirect(exec->vm(), Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
}
......@@ -508,7 +508,7 @@ void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsNonStrict(ExecState*
return;
}
PutPropertySlot slot(false);
PutPropertySlot slot(array, false);
array->putDirect(exec->vm(), Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
}
......
......@@ -798,7 +798,7 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, J
JSValue JSONPValue = JSONPData[entry].m_value.get();
if (JSONPPath.size() == 1 && JSONPPath[0].m_type == JSONPPathEntryTypeDeclare) {
globalObject->addVar(callFrame, JSONPPath[0].m_pathEntryName);
PutPropertySlot slot;
PutPropertySlot slot(globalObject);
globalObject->methodTable()->put(globalObject, callFrame, JSONPPath[0].m_pathEntryName, JSONPValue, slot);
result = jsUndefined();
continue;
......@@ -833,7 +833,7 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, J
return jsUndefined();
}
}
PutPropertySlot slot;
PutPropertySlot slot(baseObject);
switch (JSONPPath.last().m_type) {
case JSONPPathEntryTypeCall: {
JSValue function = baseObject.get(callFrame, JSONPPath.last().m_pathEntryName);
......@@ -1162,14 +1162,14 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
for (unsigned i = 0; i < numVariables; ++i) {
const Identifier& ident = codeBlock->variable(i);
if (!variableObject->hasProperty(callFrame, ident)) {
PutPropertySlot slot;
PutPropertySlot slot(variableObject);
variableObject->methodTable()->put(variableObject, callFrame, ident, jsUndefined(), slot);
}
}
for (int i = 0; i < numFunctions; ++i) {
FunctionExecutable* function = codeBlock->functionDecl(i);
PutPropertySlot slot;
PutPropertySlot slot(variableObject);
variableObject->methodTable()->put(variableObject, callFrame, function->name(), JSFunction::create(vm, function, scope), slot);
}
}
......
......@@ -239,7 +239,7 @@ void JIT_OPERATION operationPutByIdStrict(ExecState* exec, StructureStubInfo*, E
NativeCallFrameTracer tracer(vm, exec);
Identifier ident(vm, uid);
PutPropertySlot slot(true, exec->codeBlock()->putByIdContext());
PutPropertySlot slot(JSValue::decode(encodedBase), true, exec->codeBlock()->putByIdContext());
JSValue::decode(encodedBase).put(exec, ident, JSValue::decode(encodedValue), slot);
}
......@@ -249,7 +249,7 @@ void JIT_OPERATION operationPutByIdNonStrict(ExecState* exec, StructureStubInfo*
NativeCallFrameTracer tracer(vm, exec);
Identifier ident(vm, uid);
PutPropertySlot slot(false, exec->codeBlock()->putByIdContext());
PutPropertySlot slot(JSValue::decode(encodedBase), false, exec->codeBlock()->putByIdContext());
JSValue::decode(encodedBase).put(exec, ident, JSValue::decode(encodedValue), slot);
}
......@@ -259,7 +259,7 @@ void JIT_OPERATION operationPutByIdDirectStrict(ExecState* exec, StructureStubIn
NativeCallFrameTracer tracer(vm, exec);
Identifier ident(vm, uid);
PutPropertySlot slot(true, exec->codeBlock()->putByIdContext());
PutPropertySlot slot(JSValue::decode(encodedBase), true, exec->codeBlock()->putByIdContext());
asObject(JSValue::decode(encodedBase))->putDirect(exec->vm(), ident, JSValue::decode(encodedValue), slot);
}
......@@ -269,7 +269,7 @@ void JIT_OPERATION operationPutByIdDirectNonStrict(ExecState* exec, StructureStu
NativeCallFrameTracer tracer(vm, exec);
Identifier ident(vm, uid);
PutPropertySlot slot(false, exec->codeBlock()->putByIdContext());
PutPropertySlot slot(JSValue::decode(encodedBase), false, exec->codeBlock()->putByIdContext());
asObject(JSValue::decode(encodedBase))->putDirect(exec->vm(), ident, JSValue::decode(encodedValue), slot);
}
......@@ -283,7 +283,7 @@ void JIT_OPERATION operationPutByIdStrictOptimize(ExecState* exec, StructureStub
JSValue value = JSValue::decode(encodedValue);
JSValue baseValue = JSValue::decode(encodedBase);
PutPropertySlot slot(true, exec->codeBlock()->putByIdContext());
PutPropertySlot slot(baseValue, true, exec->codeBlock()->putByIdContext());
baseValue.put(exec, ident, value, slot);
......@@ -306,7 +306,7 @@ void JIT_OPERATION operationPutByIdNonStrictOptimize(ExecState* exec, StructureS
JSValue value = JSValue::decode(encodedValue);
JSValue baseValue = JSValue::decode(encodedBase);
PutPropertySlot slot(false, exec->codeBlock()->putByIdContext());
PutPropertySlot slot(baseValue, false, exec->codeBlock()->putByIdContext());
baseValue.put(exec, ident, value, slot);
......@@ -329,7 +329,7 @@ void JIT_OPERATION operationPutByIdDirectStrictOptimize(ExecState* exec, Structu
JSValue value = JSValue::decode(encodedValue);
JSObject* baseObject = asObject(JSValue::decode(encodedBase));
PutPropertySlot slot(true, exec->codeBlock()->putByIdContext());
PutPropertySlot slot(baseObject, true, exec->codeBlock()->putByIdContext());
baseObject->putDirect(exec->vm(), ident, value, slot);
......@@ -352,7 +352,7 @@ void JIT_OPERATION operationPutByIdDirectNonStrictOptimize(ExecState* exec, Stru
JSValue value = JSValue::decode(encodedValue);
JSObject* baseObject = asObject(JSValue::decode(encodedBase));
PutPropertySlot slot(false, exec->codeBlock()->putByIdContext());
PutPropertySlot slot(baseObject, false, exec->codeBlock()->putByIdContext());
baseObject->putDirect(exec->vm(), ident, value, slot);
......@@ -375,7 +375,7 @@ void JIT_OPERATION operationPutByIdStrictBuildList(ExecState* exec, StructureStu
JSValue value = JSValue::decode(encodedValue);
JSValue baseValue = JSValue::decode(encodedBase);
PutPropertySlot slot(true, exec->codeBlock()->putByIdContext());
PutPropertySlot slot(baseValue, true, exec->codeBlock()->putByIdContext());
baseValue.put(exec, ident, value, slot);
......@@ -395,7 +395,7 @@ void JIT_OPERATION operationPutByIdNonStrictBuildList(ExecState* exec, Structure
JSValue value = JSValue::decode(encodedValue);
JSValue baseValue = JSValue::decode(encodedBase);
PutPropertySlot slot(false, exec->codeBlock()->putByIdContext());
PutPropertySlot slot(baseValue, false, exec->codeBlock()->putByIdContext());
baseValue.put(exec, ident, value, slot);
......@@ -415,7 +415,7 @@ void JIT_OPERATION operationPutByIdDirectStrictBuildList(ExecState* exec, Struct
JSValue value = JSValue::decode(encodedValue);
JSObject* baseObject = asObject(JSValue::decode(encodedBase));
PutPropertySlot slot(true, exec->codeBlock()->putByIdContext());
PutPropertySlot slot(baseObject, true, exec->codeBlock()->putByIdContext());
baseObject->putDirect(exec->vm(), ident, value, slot);
......@@ -435,7 +435,7 @@ void JIT_OPERATION operationPutByIdDirectNonStrictBuildList(ExecState* exec, Str
JSValue value = JSValue::decode(encodedValue);
JSObject* baseObject = asObject(JSValue::decode(encodedBase));
PutPropertySlot slot(false, exec->codeBlock()->putByIdContext());
PutPropertySlot slot(baseObject, false, exec->codeBlock()->putByIdContext());
baseObject ->putDirect(exec->vm(), ident, value, slot);
......@@ -469,12 +469,12 @@ static void putByVal(CallFrame* callFrame, JSValue baseValue, JSValue subscript,
} else
baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
} else if (isName(subscript)) {
PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
PutPropertySlot slot(baseValue, callFrame->codeBlock()->isStrictMode());
baseValue.put(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
} else {
Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
if (!callFrame->vm().exception()) { // Don't put to an object if toString threw an exception.
PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
PutPropertySlot slot(baseValue, callFrame->codeBlock()->isStrictMode());
baseValue.put(callFrame, property, value, slot);
}
}
......@@ -486,12 +486,12 @@ static void directPutByVal(CallFrame* callFrame, JSObject* baseObject, JSValue s
uint32_t i = subscript.asUInt32();
baseObject->putDirectIndex(callFrame, i, value);
} else if (isName(subscript)) {
PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
PutPropertySlot slot(baseObject, callFrame->codeBlock()->isStrictMode());
baseObject->putDirect(callFrame->vm(), jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
} else {
Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
if (!callFrame->vm().exception()) { // Don't put to an object if toString threw an exception.
PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
PutPropertySlot slot(baseObject, callFrame->codeBlock()->isStrictMode());
baseObject->putDirect(callFrame->vm(), property, value, slot);
}
}
......@@ -1668,7 +1668,7 @@ void JIT_OPERATION operationPutToScope(ExecState* exec, Instruction* bytecodePC)
return;
}
PutPropertySlot slot(codeBlock->isStrictMode());
PutPropertySlot slot(scope, codeBlock->isStrictMode());
scope->methodTable()->put(scope, exec, ident, value, slot);
if (exec->vm().exception())
......
......@@ -578,7 +578,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
JSValue baseValue = LLINT_OP_C(1).jsValue();
PutPropertySlot slot(codeBlock->isStrictMode(), codeBlock->putByIdContext());
PutPropertySlot slot(baseValue, codeBlock->isStrictMode(), codeBlock->putByIdContext());
if (pc[8].u.operand)
asObject(baseValue)->putDirect(vm, ident, LLINT_OP_C(3).jsValue(), slot);
else
......@@ -734,14 +734,14 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
}
if (isName(subscript)) {
PutPropertySlot slot(exec->codeBlock()->isStrictMode());
PutPropertySlot slot(baseValue, exec->codeBlock()->isStrictMode());
baseValue.put(exec, jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
LLINT_END();
}
Identifier property(exec, subscript.toString(exec)->value(exec));
LLINT_CHECK_EXCEPTION();
PutPropertySlot slot(exec->codeBlock()->isStrictMode());
PutPropertySlot slot(baseValue, exec->codeBlock()->isStrictMode());
baseValue.put(exec, property, value, slot);
LLINT_END();
}
......@@ -759,12 +759,12 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_val_direct)
uint32_t i = subscript.asUInt32();
baseObject->putDirectIndex(exec, i, value);
} else if (isName(subscript)) {
PutPropertySlot slot(exec->codeBlock()->isStrictMode());
PutPropertySlot slot(baseObject, exec->codeBlock()->isStrictMode());
baseObject->putDirect(exec->vm(), jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
} else {
Identifier property(exec, subscript.toString(exec)->value(exec));
if (!exec->vm().exception()) { // Don't put to an object if toString threw an exception.
PutPropertySlot slot(exec->codeBlock()->isStrictMode());
PutPropertySlot slot(baseObject, exec->codeBlock()->isStrictMode());
baseObject->putDirect(exec->vm(), property, value, slot);
}
}
......@@ -1368,7 +1368,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident))
LLINT_THROW(createUndefinedVariableError(exec, ident));
PutPropertySlot slot(codeBlock->isStrictMode());
PutPropertySlot slot(scope, codeBlock->isStrictMode());
scope->methodTable()->put(scope, exec, ident, value, slot);
// Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
......
......@@ -187,7 +187,7 @@ void Arguments::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue va
if (thisObject->trySetArgument(exec->vm(), i, value))
return;
PutPropertySlot slot(shouldThrow);
PutPropertySlot slot(thisObject, shouldThrow);
JSObject::put(thisObject, exec, Identifier::from(exec, i), value, slot);
}
......
......@@ -160,7 +160,7 @@ static JSValue getProperty(ExecState* exec, JSObject* obj, unsigned index)
static void putProperty(ExecState* exec, JSObject* obj, PropertyName propertyName, JSValue value)
{
PutPropertySlot slot;
PutPropertySlot slot(obj);
obj->methodTable()->put(obj, exec, propertyName, value, slot);
}
......@@ -501,7 +501,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec)
if (length + n >= length)
thisObj->methodTable()->putByIndex(thisObj, exec, length + n, exec->uncheckedArgument(n), true);
else {
PutPropertySlot slot;
PutPropertySlot slot(thisObj);
Identifier propertyName(exec, JSValue(static_cast<int64_t>(length) + static_cast<int64_t>(n)).toWTFString(exec));
thisObj->methodTable()->put(thisObj, exec, propertyName, exec->uncheckedArgument(n), slot);
}
......
......@@ -172,7 +172,7 @@ void JSValue::putToPrimitive(ExecState* exec, PropertyName propertyName, JSValue
void JSValue::putToPrimitiveByIndex(ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
{
if (propertyName > MAX_ARRAY_INDEX) {
PutPropertySlot slot(shouldThrow);
PutPropertySlot slot(*this, shouldThrow);
putToPrimitive(exec, Identifier::from(exec, propertyName), value, slot);
return;
}
......
......@@ -96,7 +96,7 @@ void JSCell::put(JSCell* cell, ExecState* exec, PropertyName identifier, JSValue
void JSCell::putByIndex(JSCell* cell, ExecState* exec, unsigned identifier, JSValue value, bool shouldThrow)
{
if (cell->isString()) {
PutPropertySlot slot(shouldThrow);
PutPropertySlot slot(cell, shouldThrow);
JSValue(cell).putToPrimitive(exec, Identifier::from(exec, identifier), value, slot);
return;
}
......
......@@ -389,7 +389,7 @@ void JSFunction::put(JSCell* cell, ExecState* exec, PropertyName propertyName, J
thisObject->m_allocationProfile.clear();
thisObject->m_allocationProfileWatchpoint.fireAll();
// Don't allow this to be cached, since a [[Put]] must clear m_allocationProfile.
PutPropertySlot dontCache;
PutPropertySlot dontCache(thisObject);
Base::put(thisObject, exec, propertyName, value, dontCache);
return;
}
......
......@@ -383,7 +383,7 @@ void JSGenericTypedArrayView<Adaptor>::putByIndex(
JSGenericTypedArrayView* thisObject = jsCast<JSGenericTypedArrayView*>(cell);
if (propertyName > MAX_ARRAY_INDEX) {
PutPropertySlot slot(shouldThrow);
PutPropertySlot slot(JSValue(thisObject), shouldThrow);
thisObject->methodTable()->put(
thisObject, exec, Identifier::from(exec, propertyName), value, slot);
return;
......
......@@ -746,7 +746,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
case ObjectEndVisitMember: {
JSObject* object = objectStack.peek();
Identifier prop = propertyStack.last()[indexStack.last()];
PutPropertySlot slot;
PutPropertySlot slot(object);
JSValue filteredValue = callReviver(object, jsString(m_exec, prop.string()), outValue);
if (filteredValue.isUndefined())
object->methodTable()->deleteProperty(object, m_exec, prop);
......@@ -775,7 +775,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
stateStack.removeLast();
}
JSObject* finalHolder = constructEmptyObject(m_exec);
PutPropertySlot slot;
PutPropertySlot slot(finalHolder);
finalHolder->methodTable()->put(finalHolder, m_exec, m_exec->vm().propertyNames->emptyIdentifier, outValue, slot);
return callReviver(finalHolder, jsEmptyString(m_exec), outValue);
}
......
......@@ -411,7 +411,7 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName,
JSObject* thisObject = jsCast<JSObject*>(cell);
if (propertyName > MAX_ARRAY_INDEX) {
PutPropertySlot slot(shouldThrow);
PutPropertySlot slot(cell, shouldThrow);
thisObject->methodTable()->put(thisObject, exec, Identifier::from(exec, propertyName), value, slot);
return;
}
......@@ -1215,7 +1215,7 @@ void JSObject::putDirectAccessor(ExecState* exec, PropertyName propertyName, JSV
void JSObject::putDirectNonIndexAccessor(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes)
{
PutPropertySlot slot;
PutPropertySlot slot(this);
putDirectInternal<PutModeDefineOwnProperty>(vm, propertyName, value, attributes, slot, getCallableObject(value));
// putDirect will change our Structure if we add a new property. For
......@@ -1269,7 +1269,8 @@ bool JSObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName proper
if (entry->attributes() & DontDelete && !exec->vm().isInDefineOwnProperty())
return false; // this builtin property can't be deleted
putEntry(exec, entry, propertyName, jsUndefined(), thisObject);
PutPropertySlot slot(thisObject);
putEntry(exec, entry, propertyName, jsUndefined(), slot);
}
return true;
......
......@@ -1422,7 +1422,7 @@ inline bool JSObject::putOwnDataProperty(VM& vm, PropertyName propertyName, JSVa
inline void JSObject::putDirect(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes)
{
ASSERT(!value.isGetterSetter() && !(attributes & Accessor));
PutPropertySlot slot;
PutPropertySlot slot(this);
putDirectInternal<PutModeDefineOwnProperty>(vm, propertyName, value, attributes, slot, getCallableObject(value));
}
......
......@@ -26,6 +26,7 @@
#include "Identifier.h"
#include "JSGlobalObject.h"
#include "PropertySlot.h"
#include "PutPropertySlot.h"
#include <wtf/Assertions.h>
namespace JSC {
......@@ -41,7 +42,7 @@ namespace JSC {
// FIXME: There is no reason this get function can't be simpler.
// ie. typedef JSValue (*GetFunction)(ExecState*, JSObject* baseObject)
typedef PropertySlot::GetValueFunc GetFunction;
typedef void (*PutFunction)(ExecState*, EncodedJSValue base, EncodedJSValue value);
typedef PutPropertySlot::PutValueFunc PutFunction;
class HashEntry {
WTF_MAKE_FAST_ALLOCATED;
......@@ -290,15 +291,15 @@ namespace JSC {
return true;
}
template <class ThisImp>
inline void putEntry(ExecState* exec, const HashEntry* entry, PropertyName propertyName, JSValue value, ThisImp* thisObj, bool shouldThrow = false)
inline void putEntry(ExecState* exec, const HashEntry* entry, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
{
// If this is a function put it as an override property.
if (entry->attributes() & Function)
thisObj->putDirect(exec->vm(), propertyName, value);
else if (!(entry->attributes() & ReadOnly))
entry->propertyPutter()(exec, JSValue::encode(thisObj), JSValue::encode(value));
else if (shouldThrow)
slot.base()->putDirect(exec->vm(), propertyName, value);
else if (!(entry->attributes() & ReadOnly)) {
entry->propertyPutter()(exec, JSValue::encode(slot.thisValue()), JSValue::encode(value));
slot.setCustomProperty(slot.base(), entry->propertyPutter());
} else if (slot.isStrictMode())
throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
}
......@@ -307,15 +308,14 @@ namespace JSC {
* It looks up a hash entry for the property to be set. If an entry
* is found it sets the value and returns true, else it returns false.
*/
template <class ThisImp>
inline bool lookupPut(ExecState* exec, PropertyName propertyName, JSValue value, const HashTable& table, ThisImp* thisObj, bool shouldThrow = false)
inline bool lookupPut(ExecState* exec, PropertyName propertyName, JSValue value, const HashTable& table, PutPropertySlot& slot)
{
const HashEntry* entry = table.entry(exec, propertyName);
if (!entry)
return false;
putEntry<ThisImp>(exec, entry, propertyName, value, thisObj, shouldThrow);
putEntry(exec, entry, propertyName, value, slot);
return true;
}
......@@ -328,7 +328,7 @@ namespace JSC {
template <class ThisImp, class ParentImp>
inline void lookupPut(ExecState* exec, PropertyName propertyName, JSValue value, const HashTable& table, ThisImp* thisObj, PutPropertySlot& slot)
{
if (!lookupPut<ThisImp>(exec, propertyName, value, table, thisObj, slot.isStrictMode()))
if (!lookupPut(exec, propertyName, value, table, slot))
ParentImp::put(thisObj, exec, propertyName, value, slot); // not found: forward to parent
}
......
......@@ -27,6 +27,8 @@
#ifndef PutPropertySlot_h
#define PutPropertySlot_h
#include "JSCJSValue.h"
#include <wtf/Assertions.h>
namespace JSC {
......@@ -36,14 +38,17 @@ namespace JSC {
class PutPropertySlot {
public:
enum Type { Uncachable, ExistingProperty, NewProperty };
enum Type { Uncachable, ExistingProperty, NewProperty, CustomProperty };
enum Context { UnknownContext, PutById, PutByIdEval };
typedef void (*PutValueFunc)(ExecState*, EncodedJSValue base, EncodedJSValue value);
PutPropertySlot(bool isStrictMode = false, Context context = UnknownContext)
PutPropertySlot(JSValue thisValue, bool isStrictMode = false, Context context = UnknownContext)
: m_type(Uncachable)
, m_base(0)
, m_thisValue(thisValue)
, m_isStrictMode(isStrictMode)
, m_context(context)
, m_putFunction(nullptr)
{
}
......@@ -60,14 +65,22 @@ namespace JSC {
m_base = base;
m_offset = offset;
}
void setCustomProperty(JSObject* base, PutValueFunc function)
{
m_type = CustomProperty;
m_base = base;
m_putFunction = function;
}
Context context() const { return static_cast<Context>(m_context); }
Type type() const { return m_type; }
JSObject* base() const { return m_base; }
JSValue thisValue() const { return m_thisValue; }
bool isStrictMode() const { return m_isStrictMode; }
bool isCacheable() const { return m_type != Uncachable; }
bool isCacheable() const { return m_type != Uncachable && m_type != CustomProperty; }
PropertyOffset cachedOffset() const
{
ASSERT(isCacheable());
......@@ -77,9 +90,12 @@ namespace JSC {
private:
Type m_type;
JSObject* m_base;
JSValue m_thisValue;
PropertyOffset m_offset;
bool m_isStrictMode;
uint8_t m_context;
PutValueFunc m_putFunction;
};
} // namespace JSC
......
2013-12-23 Oliver Hunt <oliver@apple.com>
Refactor PutPropertySlot to be aware of custom properties
https://bugs.webkit.org/show_bug.cgi?id=126187
Reviewed by Antti Koivisto.
Update the bindings code generation and custom objects
to the new function signatures
* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::JSDOMWindow::put):
* bindings/objc/WebScriptObject.mm:
(-[WebScriptObject setValue:forKey:]):
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateImplementation):
* bindings/scripts/test/JS/JSTestInterface.cpp:
(WebCore::JSTestInterface::putByIndex):
* bridge/NP_jsobject.cpp:
(_NPN_SetProperty):
2014-01-02 Simon Fraser <simon.fraser@apple.com>
Add AsyncScrollingCoordinator, which is a base class for threaded and future remote ScrollingCoordinators
......@@ -339,7 +339,7 @@ void JSDOMWindow::put(JSCell* cell, ExecState* exec, PropertyName propertyName,
return;
}
if (lookupPut<JSDOMWindow>(exec, propertyName, value, *s_info.propHashTable(exec), thisObject))
if (lookupPut(exec, propertyName, value, *s_info.propHashTable(exec), slot))
return;
if (BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->impl()))
......
......@@ -376,9 +376,9 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
ASSERT(!exec->hadException());
JSLockHolder lock(exec);
PutPropertySlot slot;
[self _imp]->methodTable()->put([self _imp], exec, Identifier(exec, String(key)), convertObjcValueToValue(exec, &value, ObjcObjectType, [self _rootObject]), slot);
JSObject* object = JSC::jsDynamicCast<JSObject*>([self _imp]);
PutPropertySlot slot(object);
object->methodTable()->put(object, exec, Identifier(exec, String(key)), convertObjcValueToValue(exec, &value, ObjcObjectType, [self _rootObject]), slot);
if (exec->hadException()) {
addExceptionToConsole(exec);
......
......@@ -1929,8 +1929,8 @@ sub GenerateImplementation
}
if ($interface->extendedAttributes->{"CheckSecurity"} &&
!$attribute->signature->extendedAttributes->{"DoNotCheckSecurity"} &&
!$attribute->signature->extendedAttributes->{"DoNotCheckSecurityOnGetter"}) {
!$attribute->signature->extendedAttributes->{"DoNotCheckSecurity"} &&
!$attribute->signature->extendedAttributes->{"DoNotCheckSecurityOnGetter"}) {
push(@implContent, " if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, castedThis->impl()))\n");
push(@implContent, " return JSValue::encode(jsUndefined());\n");