Changeset 214334 in webkit


Ignore:
Timestamp:
Mar 23, 2017 9:53:37 PM (7 years ago)
Author:
mark.lam@apple.com
Message:

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):

Location:
trunk/Source/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r214323 r214334  
     12017-03-23  Mark Lam  <mark.lam@apple.com>
     2
     3        Array.prototype.splice behaves incorrectly when the VM is "having a bad time".
     4        https://bugs.webkit.org/show_bug.cgi?id=170025
     5        <rdar://problem/31228679>
     6
     7        Reviewed by Saam Barati.
     8
     9        * runtime/ArrayPrototype.cpp:
     10        (JSC::copySplicedArrayElements):
     11        (JSC::arrayProtoFuncSplice):
     12
    1132017-03-23  Yusuke Suzuki  <utatane.tea@gmail.com>
    214
  • trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp

    r214313 r214334  
    968968}
    969969
     970template<bool needToFillHolesManually>
     971inline bool copySplicedArrayElements(ExecState* exec, ThrowScope& scope, JSObject* result, JSObject* thisObj, unsigned actualStart, unsigned actualDeleteCount)
     972{
     973    VM& vm = scope.vm();
     974    for (unsigned k = 0; k < actualDeleteCount; ++k) {
     975        JSValue v = getProperty(exec, thisObj, k + actualStart);
     976        RETURN_IF_EXCEPTION(scope, false);
     977        if (UNLIKELY(!v && !needToFillHolesManually))
     978            continue;
     979        result->initializeIndex(vm, k, v);
     980    }
     981    return true;
     982}
     983
    970984EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
    971985{
     
    10471061                return encodedJSValue();
    10481062            }
    1049            
    1050             for (unsigned k = 0; k < actualDeleteCount; ++k) {
    1051                 JSValue v = getProperty(exec, thisObj, k + actualStart);
    1052                 RETURN_IF_EXCEPTION(scope, encodedJSValue());
    1053                 if (UNLIKELY(!v))
    1054                     continue;
    1055                 result->initializeIndex(vm, k, v);
     1063
     1064            // The result can have an ArrayStorage indexing type if we're having a bad time.
     1065            bool isArrayStorage = hasAnyArrayStorage(result->indexingType());
     1066            bool success = false;
     1067            if (UNLIKELY(isArrayStorage)) {
     1068                static const bool needToFillHolesManually = true;
     1069                success = copySplicedArrayElements<needToFillHolesManually>(exec, scope, result, thisObj, actualStart, actualDeleteCount);
     1070            } else {
     1071                ASSERT(hasUndecided(result->indexingType()));
     1072                static const bool needToFillHolesManually = false;
     1073                success = copySplicedArrayElements<needToFillHolesManually>(exec, scope, result, thisObj, actualStart, actualDeleteCount);
     1074            }
     1075            if (UNLIKELY(!success)) {
     1076                ASSERT(scope.exception());
     1077                return encodedJSValue();
    10561078            }
    10571079        }
Note: See TracChangeset for help on using the changeset viewer.