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/JavaScriptCore:
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):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235356
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2018-08-24 Yusuke Suzuki <yusukesuzuki@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 <sbarati@apple.com>
Make data-view-access.js run less time to prevent timeouts on 32-bit
--- /dev/null
+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]`);
+}
+2018-08-24 Yusuke Suzuki <yusukesuzuki@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 <msaboff@apple.com>
YARR: Update UCS canonicalization tables for Unicode 11
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: {
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())
VM& vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
- if (isCopyOnWrite(indexingMode()))
- convertFromCopyOnWrite(vm);
+ ensureWritable(vm);
Butterfly* butterfly = this->butterfly();
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: {
VM& vm = exec->vm();
RELEASE_ASSERT(count > 0);
- if (isCopyOnWrite(indexingMode()))
- convertFromCopyOnWrite(vm);
+ ensureWritable(vm);
Butterfly* butterfly = this->butterfly();
VM& vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
- if (isCopyOnWrite(indexingMode()))
- convertFromCopyOnWrite(vm);
+ ensureWritable(vm);
Butterfly* butterfly = this->butterfly();
VM& vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
-reloop:
+ ensureWritable(vm);
+
Butterfly* butterfly = this->butterfly();
switch (indexingMode()) {
return;
}
- default: {
- RELEASE_ASSERT(isCopyOnWrite(indexingMode()));
- convertFromCopyOnWrite(vm);
- goto reloop;
- }
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
}
}
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:
if (structure(vm)->hijacksIndexingHeader())
return nullptr;
- if (isCopyOnWrite(indexingMode()))
- convertFromCopyOnWrite(vm);
-
+ ensureWritable(vm);
+
switch (indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
if (UNLIKELY(indexingShouldBeSparse(vm)))
ArrayStorage* JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode(VM& vm)
{
- if (isCopyOnWrite(indexingMode()))
- convertFromCopyOnWrite(vm);
+ ensureWritable(vm);
switch (indexingType()) {
case ALL_BLANK_INDEXING_TYPES: {
void JSObject::switchToSlowPutArrayStorage(VM& vm)
{
- if (isCopyOnWrite(indexingMode()))
- convertFromCopyOnWrite(vm);
+ ensureWritable(vm);
switch (indexingType()) {
case ArrayClass:
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
return ensureArrayStorageSlow(vm);
}
+
+ void ensureWritable(VM& vm)
+ {
+ if (isCopyOnWrite(indexingMode()))
+ convertFromCopyOnWrite(vm);
+ }
static size_t offsetOfInlineStorage();