Title: [108304] trunk
Revision
108304
Author
barraclo...@apple.com
Date
2012-02-20 22:17:40 -0800 (Mon, 20 Feb 2012)

Log Message

[[Put]] should throw if prototype chain contains a readonly property.
https://bugs.webkit.org/show_bug.cgi?id=79069

Reviewed by Oliver Hunt.

Currently we only check the base of the put, not the prototype chain.
Fold this check in with the test for accessors.

Source/_javascript_Core: 

* runtime/JSObject.cpp:
(JSC::JSObject::put):
    - Updated to test all objects in the propotype chain for readonly properties.
(JSC::JSObject::putDirectAccessor):
(JSC::putDescriptor):
    - Record the presence of readonly properties on the structure.
* runtime/Structure.cpp:
(JSC::Structure::Structure):
    - hasGetterSetterPropertiesExcludingProto expanded to hasReadOnlyOrGetterSetterPropertiesExcludingProto.
* runtime/Structure.h:
(JSC::Structure::hasReadOnlyOrGetterSetterPropertiesExcludingProto):
(JSC::Structure::setHasGetterSetterProperties):
    - hasGetterSetterPropertiesExcludingProto expanded to hasReadOnlyOrGetterSetterPropertiesExcludingProto.
(JSC::Structure::setContainsReadOnlyProperties):
    - Added.

LayoutTests: 

* fast/js/Object-defineProperty-expected.txt:
* fast/js/script-tests/Object-defineProperty.js:
(get shouldBeTrue):
    - Added test case.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (108303 => 108304)


--- trunk/LayoutTests/ChangeLog	2012-02-21 06:15:04 UTC (rev 108303)
+++ trunk/LayoutTests/ChangeLog	2012-02-21 06:17:40 UTC (rev 108304)
@@ -1,3 +1,18 @@
+2012-02-20  Gavin Barraclough  <barraclo...@apple.com>
+
+        [[Put]] should throw if prototype chain contains a readonly property.
+        https://bugs.webkit.org/show_bug.cgi?id=79069
+
+        Reviewed by Oliver Hunt.
+
+        Currently we only check the base of the put, not the prototype chain.
+        Fold this check in with the test for accessors.
+
+        * fast/js/Object-defineProperty-expected.txt:
+        * fast/js/script-tests/Object-defineProperty.js:
+        (get shouldBeTrue):
+            - Added test case.
+
 2012-02-20  Yanbin Zhang  <yanbin.zh...@intel.com>
 
          There is no complete test cases of optional arguments for MediaStream API and PeerConnection

Modified: trunk/LayoutTests/fast/js/Object-defineProperty-expected.txt (108303 => 108304)


--- trunk/LayoutTests/fast/js/Object-defineProperty-expected.txt	2012-02-21 06:15:04 UTC (rev 108303)
+++ trunk/LayoutTests/fast/js/Object-defineProperty-expected.txt	2012-02-21 06:17:40 UTC (rev 108304)
@@ -114,6 +114,8 @@
 PASS 'use strict'; var o = Object.defineProperty(Object.defineProperty({foo:1}, 'foo', {get:function(){return 42;}, set:function(x){this.result = x;}}), 'foo', {set:undefined}); o.foo = 42; o.result; threw exception TypeError: setting a property that has only a getter.
 PASS 0 in Object.prototype is true
 PASS '0' in Object.prototype is true
+PASS var o = {}; o.readOnly = false; o.readOnly is true
+PASS 'use strict'; var o = {}; o.readOnly = false; o.readOnly threw exception TypeError: Attempted to assign to readonly property..
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/js/script-tests/Object-defineProperty.js (108303 => 108304)


--- trunk/LayoutTests/fast/js/script-tests/Object-defineProperty.js	2012-02-21 06:15:04 UTC (rev 108303)
+++ trunk/LayoutTests/fast/js/script-tests/Object-defineProperty.js	2012-02-21 06:17:40 UTC (rev 108304)
@@ -161,3 +161,10 @@
 shouldBeTrue("0 in Object.prototype");
 shouldBeTrue("'0' in Object.prototype");
 delete Object.prototype[0];
+
+Object.defineProperty(Object.prototype, 'readOnly', {value:true, configurable:true, writable:false})
+shouldBeTrue("var o = {}; o.readOnly = false; o.readOnly");
+shouldThrow("'use strict'; var o = {}; o.readOnly = false; o.readOnly");
+delete Object.prototype.readOnly;
+
+

Modified: trunk/Source/_javascript_Core/ChangeLog (108303 => 108304)


--- trunk/Source/_javascript_Core/ChangeLog	2012-02-21 06:15:04 UTC (rev 108303)
+++ trunk/Source/_javascript_Core/ChangeLog	2012-02-21 06:17:40 UTC (rev 108304)
@@ -1,3 +1,29 @@
+2012-02-20  Gavin Barraclough  <barraclo...@apple.com>
+
+        [[Put]] should throw if prototype chain contains a readonly property.
+        https://bugs.webkit.org/show_bug.cgi?id=79069
+
+        Reviewed by Oliver Hunt.
+
+        Currently we only check the base of the put, not the prototype chain.
+        Fold this check in with the test for accessors.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::put):
+            - Updated to test all objects in the propotype chain for readonly properties.
+        (JSC::JSObject::putDirectAccessor):
+        (JSC::putDescriptor):
+            - Record the presence of readonly properties on the structure.
+        * runtime/Structure.cpp:
+        (JSC::Structure::Structure):
+            - hasGetterSetterPropertiesExcludingProto expanded to hasReadOnlyOrGetterSetterPropertiesExcludingProto.
+        * runtime/Structure.h:
+        (JSC::Structure::hasReadOnlyOrGetterSetterPropertiesExcludingProto):
+        (JSC::Structure::setHasGetterSetterProperties):
+            - hasGetterSetterPropertiesExcludingProto expanded to hasReadOnlyOrGetterSetterPropertiesExcludingProto.
+        (JSC::Structure::setContainsReadOnlyProperties):
+            - Added.
+
 2012-02-20  Mark Hahnenberg  <mhahnenb...@apple.com>
 
         Implement fast path for op_new_array in the baseline JIT

Modified: trunk/Source/_javascript_Core/runtime/JSObject.cpp (108303 => 108304)


--- trunk/Source/_javascript_Core/runtime/JSObject.cpp	2012-02-21 06:15:04 UTC (rev 108303)
+++ trunk/Source/_javascript_Core/runtime/JSObject.cpp	2012-02-21 06:17:40 UTC (rev 108304)
@@ -135,7 +135,7 @@
     // Check if there are any setters or getters in the prototype chain
     JSValue prototype;
     if (propertyName != exec->propertyNames().underscoreProto) {
-        for (JSObject* obj = thisObject; !obj->structure()->hasGetterSetterPropertiesExcludingProto(); obj = asObject(prototype)) {
+        for (JSObject* obj = thisObject; !obj->structure()->hasReadOnlyOrGetterSetterPropertiesExcludingProto(); obj = asObject(prototype)) {
             prototype = obj->prototype();
             if (prototype.isNull()) {
                 if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getJSFunction(value)) && slot.isStrictMode())
@@ -145,16 +145,18 @@
         }
     }
 
-    unsigned attributes;
-    JSCell* specificValue;
-    if ((thisObject->structure()->get(globalData, propertyName, attributes, specificValue) != WTF::notFound) && attributes & ReadOnly) {
-        if (slot.isStrictMode())
-            throwError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
-        return;
-    }
+    for (JSObject* obj = thisObject; ; obj = asObject(prototype)) {
+        unsigned attributes;
+        JSCell* specificValue;
+        size_t offset = obj->structure()->get(globalData, propertyName, attributes, specificValue);
+        if (offset != WTF::notFound) {
+            if (attributes & ReadOnly) {
+                if (slot.isStrictMode())
+                    throwError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
+                return;
+            }
 
-    for (JSObject* obj = thisObject; ; obj = asObject(prototype)) {
-        if (JSValue gs = obj->getDirect(globalData, propertyName)) {
+            JSValue gs = obj->getDirectOffset(offset);
             if (gs.isGetterSetter()) {
                 JSObject* setterFunc = asGetterSetter(gs)->setter();        
                 if (!setterFunc) {
@@ -237,6 +239,9 @@
     if (slot.type() != PutPropertySlot::NewProperty)
         setStructure(globalData, Structure::attributeChangeTransition(globalData, structure(), propertyName, attributes));
 
+    if (attributes & ReadOnly)
+        structure()->setContainsReadOnlyProperties();
+
     structure()->setHasGetterSetterProperties(propertyName == globalData.propertyNames->underscoreProto);
 }
 
@@ -619,6 +624,8 @@
         else if (oldDescriptor.value())
             newValue = oldDescriptor.value();
         target->putDirect(exec->globalData(), propertyName, newValue, attributes & ~Accessor);
+        if (attributes & ReadOnly)
+            target->structure()->setContainsReadOnlyProperties();
         return true;
     }
     attributes &= ~ReadOnly;

Modified: trunk/Source/_javascript_Core/runtime/Structure.cpp (108303 => 108304)


--- trunk/Source/_javascript_Core/runtime/Structure.cpp	2012-02-21 06:15:04 UTC (rev 108303)
+++ trunk/Source/_javascript_Core/runtime/Structure.cpp	2012-02-21 06:17:40 UTC (rev 108304)
@@ -167,7 +167,7 @@
     , m_dictionaryKind(NoneDictionaryKind)
     , m_isPinnedPropertyTable(false)
     , m_hasGetterSetterProperties(false)
-    , m_hasGetterSetterPropertiesExcludingProto(false)
+    , m_hasReadOnlyGetterSetterPropertiesExcludingProto(false)
     , m_hasNonEnumerableProperties(false)
     , m_attributesInPrevious(0)
     , m_specificFunctionThrashCount(0)
@@ -189,7 +189,7 @@
     , m_dictionaryKind(NoneDictionaryKind)
     , m_isPinnedPropertyTable(false)
     , m_hasGetterSetterProperties(false)
-    , m_hasGetterSetterPropertiesExcludingProto(false)
+    , m_hasReadOnlyGetterSetterPropertiesExcludingProto(false)
     , m_hasNonEnumerableProperties(false)
     , m_attributesInPrevious(0)
     , m_specificFunctionThrashCount(0)
@@ -209,7 +209,7 @@
     , m_dictionaryKind(previous->m_dictionaryKind)
     , m_isPinnedPropertyTable(false)
     , m_hasGetterSetterProperties(previous->m_hasGetterSetterProperties)
-    , m_hasGetterSetterPropertiesExcludingProto(previous->m_hasGetterSetterPropertiesExcludingProto)
+    , m_hasReadOnlyGetterSetterPropertiesExcludingProto(previous->m_hasReadOnlyGetterSetterPropertiesExcludingProto)
     , m_hasNonEnumerableProperties(previous->m_hasNonEnumerableProperties)
     , m_attributesInPrevious(0)
     , m_specificFunctionThrashCount(previous->m_specificFunctionThrashCount)

Modified: trunk/Source/_javascript_Core/runtime/Structure.h (108303 => 108304)


--- trunk/Source/_javascript_Core/runtime/Structure.h	2012-02-21 06:15:04 UTC (rev 108303)
+++ trunk/Source/_javascript_Core/runtime/Structure.h	2012-02-21 06:17:40 UTC (rev 108304)
@@ -145,13 +145,17 @@
         }
 
         bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
-        bool hasGetterSetterPropertiesExcludingProto() const { return m_hasGetterSetterPropertiesExcludingProto; }
+        bool hasReadOnlyOrGetterSetterPropertiesExcludingProto() const { return m_hasReadOnlyGetterSetterPropertiesExcludingProto; }
         void setHasGetterSetterProperties(bool is__proto__)
         {
             m_hasGetterSetterProperties = true;
             if (!is__proto__)
-                m_hasGetterSetterPropertiesExcludingProto = true;
+                m_hasReadOnlyGetterSetterPropertiesExcludingProto = true;
         }
+        void setContainsReadOnlyProperties()
+        {
+            m_hasReadOnlyGetterSetterPropertiesExcludingProto = true;
+        }
 
         bool hasNonEnumerableProperties() const { return m_hasNonEnumerableProperties; }
         
@@ -288,7 +292,7 @@
         unsigned m_dictionaryKind : 2;
         bool m_isPinnedPropertyTable : 1;
         bool m_hasGetterSetterProperties : 1;
-        bool m_hasGetterSetterPropertiesExcludingProto : 1;
+        bool m_hasReadOnlyGetterSetterPropertiesExcludingProto : 1;
         bool m_hasNonEnumerableProperties : 1;
         unsigned m_attributesInPrevious : 7;
         unsigned m_specificFunctionThrashCount : 2;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to