Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/ChangeLog (214794 => 214795)
--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/ChangeLog 2017-04-03 15:43:58 UTC (rev 214794)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/ChangeLog 2017-04-03 15:56:17 UTC (rev 214795)
@@ -1,3 +1,15 @@
+2017-03-23 Mark Lam <mark....@apple.com>
+
+ Array.prototype.splice behaves incorrectly when the VM is "having a bad time".
+ https://bugs.webkit.org/show_bug.cgi?id=170025
+ <rdar://problem/31228679>
+
+ Reviewed by Saam Barati.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::copySplicedArrayElements):
+ (JSC::arrayProtoFuncSplice):
+
2017-03-23 Yusuke Suzuki <utatane....@gmail.com>
[JSC][DFG] Make addShouldSpeculateAnyInt more conservative to avoid regression caused by Double <-> Int52 conversions
Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/ArrayPrototype.cpp (214794 => 214795)
--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2017-04-03 15:43:58 UTC (rev 214794)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2017-04-03 15:56:17 UTC (rev 214795)
@@ -967,6 +967,20 @@
return JSValue::encode(result);
}
+template<bool needToFillHolesManually>
+inline bool copySplicedArrayElements(ExecState* exec, ThrowScope& scope, JSObject* result, JSObject* thisObj, unsigned actualStart, unsigned actualDeleteCount)
+{
+ VM& vm = scope.vm();
+ for (unsigned k = 0; k < actualDeleteCount; ++k) {
+ JSValue v = getProperty(exec, thisObj, k + actualStart);
+ RETURN_IF_EXCEPTION(scope, false);
+ if (UNLIKELY(!v && !needToFillHolesManually))
+ continue;
+ result->initializeIndex(vm, k, v);
+ }
+ return true;
+}
+
EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
{
// 15.4.4.12
@@ -1046,14 +1060,22 @@
throwOutOfMemoryError(exec, scope);
return encodedJSValue();
}
-
- for (unsigned k = 0; k < actualDeleteCount; ++k) {
- JSValue v = getProperty(exec, thisObj, k + actualStart);
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
- if (UNLIKELY(!v))
- continue;
- result->initializeIndex(vm, k, v);
+
+ // The result can have an ArrayStorage indexing type if we're having a bad time.
+ bool isArrayStorage = hasAnyArrayStorage(result->indexingType());
+ bool success = false;
+ if (UNLIKELY(isArrayStorage)) {
+ static const bool needToFillHolesManually = true;
+ success = copySplicedArrayElements<needToFillHolesManually>(exec, scope, result, thisObj, actualStart, actualDeleteCount);
+ } else {
+ ASSERT(hasUndecided(result->indexingType()));
+ static const bool needToFillHolesManually = false;
+ success = copySplicedArrayElements<needToFillHolesManually>(exec, scope, result, thisObj, actualStart, actualDeleteCount);
}
+ if (UNLIKELY(!success)) {
+ ASSERT(scope.exception());
+ return encodedJSValue();
+ }
}
}