Title: [104886] trunk/Source/_javascript_Core
Revision
104886
Author
barraclo...@apple.com
Date
2012-01-12 17:40:22 -0800 (Thu, 12 Jan 2012)

Log Message

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:

Modified Paths

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;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to