diff --git a/lib/VM/JSLib/Array.cpp b/lib/VM/JSLib/Array.cpp index b9c11c33ac3..8b4d3f56bbe 100644 --- a/lib/VM/JSLib/Array.cpp +++ b/lib/VM/JSLib/Array.cpp @@ -2691,19 +2691,18 @@ CallResult arrayPrototypeSplice(void *, Runtime &runtime) { gcScope.flushToMarker(gcMarker); } - // Use i here to refer to (k-1) in the spec, and reindex the loop. - double i = len - 1; + // (len - actualDeleteCount + itemCount) >= 0 so k never underflow + uint64_t k = len; // Delete the remaining elements from the right that we didn't copy into. - while (i > (len - actualDeleteCount + itemCount - 1)) { - lv.i = HermesValue::encodeTrustedNumberValue(i); + while (k-- > len - actualDeleteCount + itemCount) { + lv.i = HermesValue::encodeTrustedNumberValue(k); if (LLVM_UNLIKELY( JSObject::deleteComputed( lv.O, runtime, lv.i, PropOpFlags().plusThrowOnError()) == ExecutionStatus::EXCEPTION)) { return ExecutionStatus::EXCEPTION; } - i -= 1; gcScope.flushToMarker(gcMarker); } } else if (itemCount > actualDeleteCount) { diff --git a/test/hermes/regress-array-splice.js b/test/hermes/regress-array-splice.js new file mode 100644 index 00000000000..8a2f22fac27 --- /dev/null +++ b/test/hermes/regress-array-splice.js @@ -0,0 +1,24 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// RUN: %hermes -O %s | %FileCheck --match-full-lines %s + +print("splice"); +// CHECK: splice + +let removed = []; +let arr = new Proxy([], { + deleteProperty(target, p) { + removed.push(p); + return Reflect.deleteProperty(target, p); + }, +}); + +arr.push('a', 'b', 'c'); +arr.splice(0); +print(removed); +// CHECK-NEXT: 2,1,0