Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (104885 => 104886)
--- trunk/Source/_javascript_Core/ChangeLog 2012-01-13 01:27:28 UTC (rev 104885)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-01-13 01:40:22 UTC (rev 104886)
@@ -1,5 +1,39 @@
2012-01-12 Gavin Barraclough <barraclo...@apple.com>
+ Clean up putDirect (part 1)
+ https://bugs.webkit.org/show_bug.cgi?id=76232
+
+ Reviewed by Sam Weinig.
+
+ putDirect has ambiguous semantics, clean these up a bit.
+
+ putDirect generally behaves a bit like a fast defineOwnProperty, but one that
+ always creates the property, with no checking to validate the put it permitted.
+
+ It also encompasses two slightly different behaviors.
+ (1) a fast form of put for JSActivation, which doesn't have to handle searching
+ the prototype chain, getter/setter properties, or the magic __proto__ value.
+ Break this out as a new method, 'putOwnDataProperty'.
+ (2) the version of putDirect on JSValue will also check for overwriting ReadOnly
+ values, in strict mode. This is, however, not so smart on a few level, since
+ it is only called from op_put_by_id with direct set, which is only used with
+ an object as the base, and is only used to put new properties onto objects.
+
+ * dfg/DFGOperations.cpp:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::put):
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::getOwnPropertySlot):
+ * runtime/JSObject.h:
+ (JSC::JSObject::putOwnDataProperty):
+ * runtime/JSValue.h:
+
+2012-01-12 Gavin Barraclough <barraclo...@apple.com>
+
https://bugs.webkit.org/show_bug.cgi?id=76141
defineSetter/defineGetter may fail to update Accessor attribute
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (104885 => 104886)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2012-01-13 01:27:28 UTC (rev 104885)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2012-01-13 01:40:22 UTC (rev 104886)
@@ -431,13 +431,15 @@
void DFG_OPERATION operationPutByIdDirectStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
{
PutPropertySlot slot(true);
- JSValue(base).putDirect(exec, *propertyName, JSValue::decode(encodedValue), slot);
+ ASSERT(base->isObject());
+ asObject(base)->putDirect(exec->globalData(), *propertyName, JSValue::decode(encodedValue), slot);
}
void DFG_OPERATION operationPutByIdDirectNonStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
{
PutPropertySlot slot(false);
- JSValue(base).putDirect(exec, *propertyName, JSValue::decode(encodedValue), slot);
+ ASSERT(base->isObject());
+ asObject(base)->putDirect(exec->globalData(), *propertyName, JSValue::decode(encodedValue), slot);
}
V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictOptimize);
@@ -476,14 +478,14 @@
void DFG_OPERATION operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
{
JSValue value = JSValue::decode(encodedValue);
- JSValue baseValue(base);
PutPropertySlot slot(true);
- baseValue.putDirect(exec, *propertyName, value, slot);
+ ASSERT(base->isObject());
+ asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
if (stubInfo.seen)
- dfgRepatchPutByID(exec, baseValue, *propertyName, slot, stubInfo, Direct);
+ dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct);
else
stubInfo.seen = true;
}
@@ -492,14 +494,14 @@
void DFG_OPERATION operationPutByIdDirectNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
{
JSValue value = JSValue::decode(encodedValue);
- JSValue baseValue(base);
PutPropertySlot slot(false);
- baseValue.putDirect(exec, *propertyName, value, slot);
+ ASSERT(base->isObject());
+ asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
if (stubInfo.seen)
- dfgRepatchPutByID(exec, baseValue, *propertyName, slot, stubInfo, Direct);
+ dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct);
else
stubInfo.seen = true;
}
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (104885 => 104886)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2012-01-13 01:27:28 UTC (rev 104885)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2012-01-13 01:40:22 UTC (rev 104886)
@@ -3308,10 +3308,12 @@
int direct = vPC[8].u.operand;
JSValue baseValue = callFrame->r(base).jsValue();
+ ASSERT(baseValue.isObject());
+ JSObject* baseObject = asObject(baseValue);
Identifier& ident = codeBlock->identifier(property);
PutPropertySlot slot(codeBlock->isStrictMode());
if (direct)
- baseValue.putDirect(callFrame, ident, callFrame->r(value).jsValue(), slot);
+ baseObject->putDirect(*globalData, ident, callFrame->r(value).jsValue(), slot);
else
baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot);
CHECK_FOR_EXCEPTION();
@@ -3426,10 +3428,12 @@
int direct = vPC[8].u.operand;
JSValue baseValue = callFrame->r(base).jsValue();
+ ASSERT(baseValue.isObject());
+ JSObject* baseObject = asObject(baseValue);
Identifier& ident = codeBlock->identifier(property);
PutPropertySlot slot(codeBlock->isStrictMode());
if (direct)
- baseValue.putDirect(callFrame, ident, callFrame->r(value).jsValue(), slot);
+ baseObject->putDirect(*globalData, ident, callFrame->r(value).jsValue(), slot);
else
baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot);
CHECK_FOR_EXCEPTION();
Modified: trunk/Source/_javascript_Core/jit/JITStubs.cpp (104885 => 104886)
--- trunk/Source/_javascript_Core/jit/JITStubs.cpp 2012-01-13 01:27:28 UTC (rev 104885)
+++ trunk/Source/_javascript_Core/jit/JITStubs.cpp 2012-01-13 01:40:22 UTC (rev 104886)
@@ -1382,7 +1382,9 @@
STUB_INIT_STACK_FRAME(stackFrame);
PutPropertySlot slot(stackFrame.callFrame->codeBlock()->isStrictMode());
- stackFrame.args[0].jsValue().putDirect(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
+ JSValue baseValue = stackFrame.args[0].jsValue();
+ ASSERT(baseValue.isObject());
+ asObject(baseValue)->putDirect(stackFrame.callFrame->globalData(), stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
CHECK_FOR_EXCEPTION_AT_END();
}
@@ -1427,7 +1429,9 @@
Identifier& ident = stackFrame.args[1].identifier();
PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
- stackFrame.args[0].jsValue().putDirect(callFrame, ident, stackFrame.args[2].jsValue(), slot);
+ JSValue baseValue = stackFrame.args[0].jsValue();
+ ASSERT(baseValue.isObject());
+ asObject(baseValue)->putDirect(callFrame->globalData(), ident, stackFrame.args[2].jsValue(), slot);
CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
@@ -1460,7 +1464,9 @@
Identifier& ident = stackFrame.args[1].identifier();
PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
- stackFrame.args[0].jsValue().putDirect(callFrame, ident, stackFrame.args[2].jsValue(), slot);
+ JSValue baseValue = stackFrame.args[0].jsValue();
+ ASSERT(baseValue.isObject());
+ asObject(baseValue)->putDirect(callFrame->globalData(), ident, stackFrame.args[2].jsValue(), slot);
CHECK_FOR_EXCEPTION_AT_END();
}
Modified: trunk/Source/_javascript_Core/runtime/JSActivation.cpp (104885 => 104886)
--- trunk/Source/_javascript_Core/runtime/JSActivation.cpp 2012-01-13 01:27:28 UTC (rev 104885)
+++ trunk/Source/_javascript_Core/runtime/JSActivation.cpp 2012-01-13 01:40:22 UTC (rev 104886)
@@ -184,7 +184,7 @@
// properties are non-standard extensions that other implementations do not
// expose in the activation object.
ASSERT(!thisObject->hasGetterSetterProperties());
- thisObject->putDirect(exec->globalData(), propertyName, value, 0, true, slot);
+ thisObject->putOwnDataProperty(exec->globalData(), propertyName, value, slot);
}
// FIXME: Make this function honor ReadOnly (const) and DontEnum
Modified: trunk/Source/_javascript_Core/runtime/JSFunction.cpp (104885 => 104886)
--- trunk/Source/_javascript_Core/runtime/JSFunction.cpp 2012-01-13 01:27:28 UTC (rev 104885)
+++ trunk/Source/_javascript_Core/runtime/JSFunction.cpp 2012-01-13 01:40:22 UTC (rev 104886)
@@ -204,8 +204,7 @@
if (!location) {
JSObject* prototype = constructEmptyObject(exec, thisObject->globalObject()->emptyObjectStructure());
prototype->putDirect(exec->globalData(), exec->propertyNames().constructor, thisObject, DontEnum);
- PutPropertySlot slot;
- thisObject->putDirect(exec->globalData(), exec->propertyNames().prototype, prototype, DontDelete | DontEnum, false, slot);
+ thisObject->putDirect(exec->globalData(), exec->propertyNames().prototype, prototype, DontDelete | DontEnum);
location = thisObject->getDirectLocation(exec->globalData(), exec->propertyNames().prototype);
}
Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (104885 => 104886)
--- trunk/Source/_javascript_Core/runtime/JSObject.h 2012-01-13 01:27:28 UTC (rev 104885)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h 2012-01-13 01:40:22 UTC (rev 104886)
@@ -107,6 +107,10 @@
static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue);
+ // putWithAttributes is effectively an unchecked vesion of 'defineOwnProperty':
+ // - the prototype chain is not consulted
+ // - accessors are not called.
+ // - attributes will be respected (after the call the property will exist with the given attributes)
static void putWithAttributes(JSObject*, ExecState*, const Identifier& propertyName, JSValue, unsigned attributes);
void putWithAttributes(JSGlobalData*, const Identifier& propertyName, JSValue, unsigned attributes);
@@ -170,7 +174,13 @@
bool hasCustomProperties() { return structure()->didTransition(); }
bool hasGetterSetterProperties() { return structure()->hasGetterSetterProperties(); }
- bool putDirect(JSGlobalData&, const Identifier& propertyName, JSValue, unsigned attr, bool checkReadOnly, PutPropertySlot&);
+ // putOwnDataProperty has 'put' like semantics, however this method:
+ // - assumes the object contains no own getter/setter properties.
+ // - provides no special handling for __proto__
+ // - does not walk the prototype chain (to check for accessors or non-writable properties).
+ // This is used by JSActivation.
+ bool putOwnDataProperty(JSGlobalData&, const Identifier& propertyName, JSValue, PutPropertySlot&);
+
void putDirect(JSGlobalData&, const Identifier& propertyName, JSValue, unsigned attr = 0);
bool putDirect(JSGlobalData&, const Identifier& propertyName, JSValue, PutPropertySlot&);
@@ -738,12 +748,13 @@
return true;
}
-inline bool JSObject::putDirect(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+inline bool JSObject::putOwnDataProperty(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
ASSERT(value);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+ ASSERT(!structure()->hasGetterSetterProperties());
- return putDirectInternal(globalData, propertyName, value, attributes, checkReadOnly, slot, getJSFunction(value));
+ return putDirectInternal(globalData, propertyName, value, 0, true, slot, getJSFunction(value));
}
inline void JSObject::putDirect(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes)
@@ -840,13 +851,6 @@
asCell()->methodTable()->put(asCell(), exec, propertyName, value, slot);
}
-inline void JSValue::putDirect(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
-{
- ASSERT(isCell() && isObject());
- if (!asObject(asCell())->putDirect(exec->globalData(), propertyName, value, slot) && slot.isStrictMode())
- throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
-}
-
inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue value)
{
if (UNLIKELY(!isCell())) {
Modified: trunk/Source/_javascript_Core/runtime/JSValue.h (104885 => 104886)
--- trunk/Source/_javascript_Core/runtime/JSValue.h 2012-01-13 01:27:28 UTC (rev 104885)
+++ trunk/Source/_javascript_Core/runtime/JSValue.h 2012-01-13 01:40:22 UTC (rev 104886)
@@ -218,7 +218,6 @@
JSValue get(ExecState*, unsigned propertyName) const;
JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const;
void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
- void putDirect(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
void put(ExecState*, unsigned propertyName, JSValue);
JSObject* toThisObject(ExecState*) const;