Title: [235356] trunk
Revision
235356
Author
yusukesuz...@slowstart.org
Date
2018-08-27 01:31:43 -0700 (Mon, 27 Aug 2018)

Log Message

[JSC] Array.prototype.reverse modifies JSImmutableButterfly
https://bugs.webkit.org/show_bug.cgi?id=188794

Reviewed by Saam Barati.

JSTests:

* stress/reverse-with-immutable-butterfly.js: Added.
(shouldBe):
(reverseInt):
(reverseDouble):
(reverseContiguous):

Source/_javascript_Core:

While Array.prototype.reverse modifies the butterfly of the given Array,
it does not account JSImmutableButterfly case. So it accidentally modifies
the content of JSImmutableButterfly.
This patch converts CoW arrays to writable arrays before reversing.

* runtime/ArrayPrototype.cpp:
(JSC::arrayProtoFuncReverse):
* runtime/JSObject.h:
(JSC::JSObject::ensureWritable):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (235355 => 235356)


--- trunk/JSTests/ChangeLog	2018-08-27 08:30:58 UTC (rev 235355)
+++ trunk/JSTests/ChangeLog	2018-08-27 08:31:43 UTC (rev 235356)
@@ -1,3 +1,16 @@
+2018-08-24  Yusuke Suzuki  <yusukesuz...@slowstart.org>
+
+        [JSC] Array.prototype.reverse modifies JSImmutableButterfly
+        https://bugs.webkit.org/show_bug.cgi?id=188794
+
+        Reviewed by Saam Barati.
+
+        * stress/reverse-with-immutable-butterfly.js: Added.
+        (shouldBe):
+        (reverseInt):
+        (reverseDouble):
+        (reverseContiguous):
+
 2018-08-22  Saam barati  <sbar...@apple.com>
 
         Make data-view-access.js run less time to prevent timeouts on 32-bit

Added: trunk/JSTests/stress/reverse-with-immutable-butterfly.js (0 => 235356)


--- trunk/JSTests/stress/reverse-with-immutable-butterfly.js	                        (rev 0)
+++ trunk/JSTests/stress/reverse-with-immutable-butterfly.js	2018-08-27 08:31:43 UTC (rev 235356)
@@ -0,0 +1,28 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function reverseInt()
+{
+    var array = [0, 1, 2, 3];
+    return array.reverse();
+}
+
+function reverseDouble()
+{
+    var array = [0.0, 1.1, 2.2, 3.3];
+    return array.reverse();
+}
+
+function reverseContiguous()
+{
+    var array = [0.0, 1.1, 2.2, 'hello'];
+    return array.reverse();
+}
+
+for (var i = 0; i < 1e4; ++i) {
+    shouldBe(JSON.stringify(reverseInt()), `[3,2,1,0]`);
+    shouldBe(JSON.stringify(reverseDouble()), `[3.3,2.2,1.1,0]`);
+    shouldBe(JSON.stringify(reverseContiguous()), `["hello",2.2,1.1,0]`);
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (235355 => 235356)


--- trunk/Source/_javascript_Core/ChangeLog	2018-08-27 08:30:58 UTC (rev 235355)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-08-27 08:31:43 UTC (rev 235356)
@@ -1,3 +1,20 @@
+2018-08-24  Yusuke Suzuki  <yusukesuz...@slowstart.org>
+
+        [JSC] Array.prototype.reverse modifies JSImmutableButterfly
+        https://bugs.webkit.org/show_bug.cgi?id=188794
+
+        Reviewed by Saam Barati.
+
+        While Array.prototype.reverse modifies the butterfly of the given Array,
+        it does not account JSImmutableButterfly case. So it accidentally modifies
+        the content of JSImmutableButterfly.
+        This patch converts CoW arrays to writable arrays before reversing.
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::arrayProtoFuncReverse):
+        * runtime/JSObject.h:
+        (JSC::JSObject::ensureWritable):
+
 2018-08-24  Michael Saboff  <msab...@apple.com>
 
         YARR: Update UCS canonicalization tables for Unicode 11

Modified: trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp (235355 => 235356)


--- trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp	2018-08-27 08:30:58 UTC (rev 235355)
+++ trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp	2018-08-27 08:31:43 UTC (rev 235356)
@@ -855,6 +855,8 @@
     unsigned length = toLength(exec, thisObject);
     RETURN_IF_EXCEPTION(scope, encodedJSValue());
 
+    thisObject->ensureWritable(vm);
+
     switch (thisObject->indexingType()) {
     case ALL_CONTIGUOUS_INDEXING_TYPES:
     case ALL_INT32_INDEXING_TYPES: {

Modified: trunk/Source/_javascript_Core/runtime/JSArray.cpp (235355 => 235356)


--- trunk/Source/_javascript_Core/runtime/JSArray.cpp	2018-08-27 08:30:58 UTC (rev 235355)
+++ trunk/Source/_javascript_Core/runtime/JSArray.cpp	2018-08-27 08:31:43 UTC (rev 235356)
@@ -287,8 +287,7 @@
         return ordinarySetSlow(exec, thisObject, propertyName, value, slot.thisValue(), slot.isStrictMode());
     }
 
-    if (isCopyOnWrite(thisObject->indexingMode()))
-        thisObject->convertFromCopyOnWrite(vm);
+    thisObject->ensureWritable(vm);
 
     if (propertyName == vm.propertyNames->length) {
         if (!thisObject->isLengthWritable())
@@ -662,8 +661,7 @@
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    if (isCopyOnWrite(indexingMode()))
-        convertFromCopyOnWrite(vm);
+    ensureWritable(vm);
 
     Butterfly* butterfly = this->butterfly();
 
@@ -770,14 +768,11 @@
 JSArray* JSArray::fastSlice(ExecState& exec, unsigned startIndex, unsigned count)
 {
     VM& vm = exec.vm();
+
+    ensureWritable(vm);
+
     auto arrayType = indexingMode();
     switch (arrayType) {
-    case CopyOnWriteArrayWithInt32:
-    case CopyOnWriteArrayWithDouble:
-    case CopyOnWriteArrayWithContiguous:
-        convertFromCopyOnWrite(vm);
-        arrayType = indexingMode();
-        FALLTHROUGH;
     case ArrayWithDouble:
     case ArrayWithInt32:
     case ArrayWithContiguous: {
@@ -922,8 +917,7 @@
     VM& vm = exec->vm();
     RELEASE_ASSERT(count > 0);
 
-    if (isCopyOnWrite(indexingMode()))
-        convertFromCopyOnWrite(vm);
+    ensureWritable(vm);
 
     Butterfly* butterfly = this->butterfly();
     
@@ -1081,8 +1075,7 @@
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    if (isCopyOnWrite(indexingMode()))
-        convertFromCopyOnWrite(vm);
+    ensureWritable(vm);
 
     Butterfly* butterfly = this->butterfly();
     

Modified: trunk/Source/_javascript_Core/runtime/JSArrayInlines.h (235355 => 235356)


--- trunk/Source/_javascript_Core/runtime/JSArrayInlines.h	2018-08-27 08:30:58 UTC (rev 235355)
+++ trunk/Source/_javascript_Core/runtime/JSArrayInlines.h	2018-08-27 08:31:43 UTC (rev 235356)
@@ -88,7 +88,8 @@
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-reloop:
+    ensureWritable(vm);
+
     Butterfly* butterfly = this->butterfly();
 
     switch (indexingMode()) {
@@ -228,12 +229,9 @@
         return;
     }
 
-    default: {
-        RELEASE_ASSERT(isCopyOnWrite(indexingMode()));
-        convertFromCopyOnWrite(vm);
-        goto reloop;
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
     }
-    }
 }
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/JSObject.cpp (235355 => 235356)


--- trunk/Source/_javascript_Core/runtime/JSObject.cpp	2018-08-27 08:30:58 UTC (rev 235355)
+++ trunk/Source/_javascript_Core/runtime/JSObject.cpp	2018-08-27 08:31:43 UTC (rev 235356)
@@ -838,8 +838,7 @@
         return thisObject->methodTable(vm)->put(thisObject, exec, Identifier::from(exec, propertyName), value, slot);
     }
 
-    if (isCopyOnWrite(thisObject->indexingMode()))
-        thisObject->convertFromCopyOnWrite(vm);
+    thisObject->ensureWritable(vm);
 
     switch (thisObject->indexingType()) {
     case ALL_BLANK_INDEXING_TYPES:
@@ -1636,9 +1635,8 @@
     if (structure(vm)->hijacksIndexingHeader())
         return nullptr;
 
-    if (isCopyOnWrite(indexingMode()))
-        convertFromCopyOnWrite(vm);
-    
+    ensureWritable(vm);
+
     switch (indexingType()) {
     case ALL_BLANK_INDEXING_TYPES:
         if (UNLIKELY(indexingShouldBeSparse(vm)))
@@ -1673,8 +1671,7 @@
 
 ArrayStorage* JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode(VM& vm)
 {
-    if (isCopyOnWrite(indexingMode()))
-        convertFromCopyOnWrite(vm);
+    ensureWritable(vm);
 
     switch (indexingType()) {
     case ALL_BLANK_INDEXING_TYPES: {
@@ -1707,8 +1704,7 @@
 
 void JSObject::switchToSlowPutArrayStorage(VM& vm)
 {
-    if (isCopyOnWrite(indexingMode()))
-        convertFromCopyOnWrite(vm);
+    ensureWritable(vm);
 
     switch (indexingType()) {
     case ArrayClass:
@@ -2544,8 +2540,7 @@
 
     ASSERT(index <= MAX_ARRAY_INDEX);
 
-    if (isCopyOnWrite(indexingMode()))
-        convertFromCopyOnWrite(vm);
+    ensureWritable(vm);
 
     if (!inSparseIndexingMode()) {
         // Fast case: we're putting a regular property to a regular array

Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (235355 => 235356)


--- trunk/Source/_javascript_Core/runtime/JSObject.h	2018-08-27 08:30:58 UTC (rev 235355)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h	2018-08-27 08:31:43 UTC (rev 235356)
@@ -865,6 +865,12 @@
 
         return ensureArrayStorageSlow(vm);
     }
+
+    void ensureWritable(VM& vm)
+    {
+        if (isCopyOnWrite(indexingMode()))
+            convertFromCopyOnWrite(vm);
+    }
         
     static size_t offsetOfInlineStorage();
         
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to