Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/builtins/array-splice.tq')
-rw-r--r--deps/v8/src/builtins/array-splice.tq708
1 files changed, 355 insertions, 353 deletions
diff --git a/deps/v8/src/builtins/array-splice.tq b/deps/v8/src/builtins/array-splice.tq
index 9d7a223d974..92eace071cb 100644
--- a/deps/v8/src/builtins/array-splice.tq
+++ b/deps/v8/src/builtins/array-splice.tq
@@ -3,416 +3,418 @@
// found in the LICENSE file.
namespace array {
- // Given {elements}, we want to create a non-zero length array of type
- // FixedArrayType. Most of this behavior is outsourced to ExtractFixedArray(),
- // but the special case of wanting to have a FixedDoubleArray when given a
- // zero-length input FixedArray is handled here.
- macro Extract(implicit context: Context)(
- elements: FixedArray, first: Smi, count: Smi, capacity: Smi): FixedArray {
- return ExtractFixedArray(
- elements, Convert<intptr>(first), Convert<intptr>(count),
- Convert<intptr>(capacity));
- }
+// Given {source}, we want to create a non-zero length array of type
+// FixedArrayType with the specified {result_capacity}. Starting from
+// {startIndex}, {count} number of elements are copied to the newly
+// created result array. Most of this behavior is outsourced to
+// ExtractFixedArray(). We handle the case where the {source} is
+// EmptyFixedArray but result is expected to be a FixedDoubleArray.
+macro Extract(implicit context: Context)(
+ source: FixedArray, startIndex: Smi, count: Smi,
+ resultCapacity: Smi): FixedArray {
+ return ExtractFixedArray(
+ source, Convert<intptr>(startIndex), Convert<intptr>(count),
+ Convert<intptr>(resultCapacity));
+}
- macro Extract(implicit context: Context)(
- elements: FixedDoubleArray|EmptyFixedArray, first: Smi, count: Smi,
- capacity: Smi): FixedDoubleArray|EmptyFixedArray {
- typeswitch (elements) {
- case (EmptyFixedArray): {
- return AllocateZeroedFixedDoubleArray(Convert<intptr>(capacity));
- }
- case (elements: FixedDoubleArray): {
- return ExtractFixedDoubleArray(
- elements, Convert<intptr>(first), Convert<intptr>(count),
- Convert<intptr>(capacity));
- }
+macro Extract(implicit context: Context)(
+ source: FixedDoubleArray|EmptyFixedArray, startIndex: Smi, count: Smi,
+ resultCapacity: Smi): FixedDoubleArray|EmptyFixedArray {
+ typeswitch (source) {
+ case (EmptyFixedArray): {
+ // ExtractFixedDoubleArray expects {source} to be a FixedDoubleArray.
+ // Handle the case where {source} is empty here.
+ return AllocateFixedDoubleArrayWithHoles(
+ Convert<intptr>(resultCapacity),
+ AllocationFlag::kAllowLargeObjectAllocation);
+ }
+ case (source: FixedDoubleArray): {
+ return ExtractFixedDoubleArray(
+ source, Convert<intptr>(startIndex), Convert<intptr>(count),
+ Convert<intptr>(resultCapacity));
}
}
+}
- macro DoMoveElements<FixedArrayType : type extends FixedArrayBase>(
- elements: FixedArrayType, dstIndex: Smi, srcIndex: Smi,
- count: Smi): void {
- TorqueMoveElements(
- elements, Convert<intptr>(dstIndex), Convert<intptr>(srcIndex),
- Convert<intptr>(count));
- }
+macro DoMoveElements<FixedArrayType : type extends FixedArrayBase>(
+ elements: FixedArrayType, dstIndex: Smi, srcIndex: Smi, count: Smi): void {
+ TorqueMoveElements(
+ elements, Convert<intptr>(dstIndex), Convert<intptr>(srcIndex),
+ Convert<intptr>(count));
+}
- macro StoreHoles<FixedArrayType : type extends FixedArrayBase>(
- elements: FixedArrayType, holeStartIndex: Smi, holeEndIndex: Smi): void {
- for (let i: Smi = holeStartIndex; i < holeEndIndex; i++) {
- array::StoreArrayHole(elements, i);
- }
+macro StoreHoles<FixedArrayType : type extends FixedArrayBase>(
+ elements: FixedArrayType, holeStartIndex: Smi, holeEndIndex: Smi): void {
+ for (let i: Smi = holeStartIndex; i < holeEndIndex; i++) {
+ array::StoreArrayHole(elements, i);
}
+}
- macro DoCopyElements<FixedArrayType : type extends FixedArrayBase>(
- dstElements: FixedArrayType, dstIndex: Smi, srcElements: FixedArrayType,
- srcIndex: Smi, count: Smi): void {
- TorqueCopyElements(
- dstElements, Convert<intptr>(dstIndex), srcElements,
- Convert<intptr>(srcIndex), Convert<intptr>(count));
- }
+macro DoCopyElements<FixedArrayType : type extends FixedArrayBase>(
+ dstElements: FixedArrayType, dstIndex: Smi, srcElements: FixedArrayType,
+ srcIndex: Smi, count: Smi): void {
+ TorqueCopyElements(
+ dstElements, Convert<intptr>(dstIndex), srcElements,
+ Convert<intptr>(srcIndex), Convert<intptr>(count));
+}
- macro
- FastSplice<FixedArrayType : type extends FixedArrayBase, ElementType: type>(
- implicit context: Context)(
- args: Arguments, a: JSArray, length: Smi, newLength: Smi,
- actualStart: Smi, insertCount: Smi, actualDeleteCount: Smi): void {
- // Make sure elements are writable.
- array::EnsureWriteableFastElements(a);
-
- if (insertCount != actualDeleteCount) {
- const elements =
- UnsafeCast<(FixedArrayType | EmptyFixedArray)>(a.elements);
- const dstIndex: Smi = actualStart + insertCount;
- const srcIndex: Smi = actualStart + actualDeleteCount;
- const count: Smi = length - actualDeleteCount - actualStart;
- if (insertCount < actualDeleteCount) {
- // Shrink.
+macro
+FastSplice<FixedArrayType : type extends FixedArrayBase, ElementType: type>(
+ implicit context: Context)(
+ args: Arguments, a: JSArray, length: Smi, newLength: Smi, actualStart: Smi,
+ insertCount: Smi, actualDeleteCount: Smi): void {
+ // Make sure elements are writable.
+ array::EnsureWriteableFastElements(a);
+
+ if (insertCount != actualDeleteCount) {
+ const elements = UnsafeCast<(FixedArrayType | EmptyFixedArray)>(a.elements);
+ const dstIndex: Smi = actualStart + insertCount;
+ const srcIndex: Smi = actualStart + actualDeleteCount;
+ const count: Smi = length - actualDeleteCount - actualStart;
+ if (insertCount < actualDeleteCount) {
+ // Shrink.
+ DoMoveElements(
+ UnsafeCast<FixedArrayType>(elements), dstIndex, srcIndex, count);
+ StoreHoles(UnsafeCast<FixedArrayType>(elements), newLength, length);
+ } else if (insertCount > actualDeleteCount) {
+ // If the backing store is big enough, then moving elements is enough.
+ if (newLength <= elements.length) {
DoMoveElements(
UnsafeCast<FixedArrayType>(elements), dstIndex, srcIndex, count);
- StoreHoles(UnsafeCast<FixedArrayType>(elements), newLength, length);
- } else if (insertCount > actualDeleteCount) {
- // If the backing store is big enough, then moving elements is enough.
- if (newLength <= elements.length) {
- DoMoveElements(
- UnsafeCast<FixedArrayType>(elements), dstIndex, srcIndex, count);
- } else {
- // Grow.
- const capacity: Smi = CalculateNewElementsCapacity(newLength);
- const newElements: FixedArrayType = UnsafeCast<FixedArrayType>(
- Extract(elements, 0, actualStart, capacity));
- a.elements = newElements;
- if (elements.length > 0) {
- DoCopyElements(
- newElements, dstIndex, UnsafeCast<FixedArrayType>(elements),
- srcIndex, count);
- }
+ } else {
+ // Grow.
+ const capacity: Smi = CalculateNewElementsCapacity(newLength);
+ const newElements: FixedArrayType = UnsafeCast<FixedArrayType>(
+ Extract(elements, 0, actualStart, capacity));
+ a.elements = newElements;
+ if (elements.length > 0) {
+ DoCopyElements(
+ newElements, dstIndex, UnsafeCast<FixedArrayType>(elements),
+ srcIndex, count);
}
}
}
-
- // Copy arguments.
- let k: Smi = actualStart;
- if (insertCount > 0) {
- const typedNewElements: FixedArrayType =
- UnsafeCast<FixedArrayType>(a.elements);
- for (let i: intptr = 2; i < args.length; ++i) {
- const e: JSAny = args[i];
- // The argument elements were already validated to be an appropriate
- // {ElementType} to store in {FixedArrayType}.
- typedNewElements[k++] = UnsafeCast<ElementType>(e);
- }
- }
-
- // Update the array's length after all the FixedArray shuffling is done.
- a.length = newLength;
}
- transitioning macro FastArraySplice(
- context: Context, args: Arguments, o: JSReceiver,
- originalLengthNumber: Number, actualStartNumber: Number, insertCount: Smi,
- actualDeleteCountNumber: Number): JSAny
- labels Bailout {
- const originalLength: Smi =
- Cast<Smi>(originalLengthNumber) otherwise Bailout;
- const actualStart: Smi = Cast<Smi>(actualStartNumber) otherwise Bailout;
- const actualDeleteCount: Smi =
- Cast<Smi>(actualDeleteCountNumber) otherwise Bailout;
- const lengthDelta: Smi = insertCount - actualDeleteCount;
- const newLength: Smi = originalLength + lengthDelta;
-
- const a: JSArray = Cast<JSArray>(o) otherwise Bailout;
-
- const map: Map = a.map;
- if (!IsPrototypeInitialArrayPrototype(map)) goto Bailout;
- if (IsNoElementsProtectorCellInvalid()) goto Bailout;
- if (IsArraySpeciesProtectorCellInvalid()) goto Bailout;
-
- // Fast path only works on fast elements kind and with writable length.
- let elementsKind: ElementsKind = EnsureArrayPushable(map) otherwise Bailout;
- if (!IsFastElementsKind(elementsKind)) goto Bailout;
-
- const oldElementsKind: ElementsKind = elementsKind;
+ // Copy arguments.
+ let k: Smi = actualStart;
+ if (insertCount > 0) {
+ const typedNewElements: FixedArrayType =
+ UnsafeCast<FixedArrayType>(a.elements);
for (let i: intptr = 2; i < args.length; ++i) {
const e: JSAny = args[i];
- if (IsFastSmiElementsKind(elementsKind)) {
- if (TaggedIsNotSmi(e)) {
- const heapObject: HeapObject = UnsafeCast<HeapObject>(e);
- elementsKind = IsHeapNumber(heapObject) ?
- AllowDoubleElements(elementsKind) :
- AllowNonNumberElements(elementsKind);
- }
- } else if (IsDoubleElementsKind(elementsKind)) {
- if (!IsNumber(e)) {
- elementsKind = AllowNonNumberElements(elementsKind);
- }
- }
+ // The argument elements were already validated to be an appropriate
+ // {ElementType} to store in {FixedArrayType}.
+ typedNewElements[k++] = UnsafeCast<ElementType>(e);
}
+ }
- if (elementsKind != oldElementsKind) {
- const smiElementsKind: Smi = Convert<Smi>(Convert<int32>(elementsKind));
- TransitionElementsKindWithKind(context, a, smiElementsKind);
- }
+ // Update the array's length after all the FixedArray shuffling is done.
+ a.length = newLength;
+}
- // Make sure that the length hasn't been changed by side-effect.
- const length: Smi = Cast<Smi>(a.length) otherwise Bailout;
- if (originalLength != length) goto Bailout;
+transitioning macro FastArraySplice(
+ context: Context, args: Arguments, o: JSReceiver,
+ originalLengthNumber: Number, actualStartNumber: Number, insertCount: Smi,
+ actualDeleteCountNumber: Number): JSAny
+ labels Bailout {
+ const originalLength: Smi = Cast<Smi>(originalLengthNumber) otherwise Bailout;
+ const actualStart: Smi = Cast<Smi>(actualStartNumber) otherwise Bailout;
+ const actualDeleteCount: Smi =
+ Cast<Smi>(actualDeleteCountNumber) otherwise Bailout;
+ const lengthDelta: Smi = insertCount - actualDeleteCount;
+ const newLength: Smi = originalLength + lengthDelta;
+
+ const a: JSArray = Cast<JSArray>(o) otherwise Bailout;
+
+ const map: Map = a.map;
+ if (!IsPrototypeInitialArrayPrototype(map)) goto Bailout;
+ if (IsNoElementsProtectorCellInvalid()) goto Bailout;
+ if (IsArraySpeciesProtectorCellInvalid()) goto Bailout;
+
+ // Fast path only works on fast elements kind and with writable length.
+ let elementsKind: ElementsKind = EnsureArrayPushable(map) otherwise Bailout;
+ if (!IsFastElementsKind(elementsKind)) goto Bailout;
+
+ const oldElementsKind: ElementsKind = elementsKind;
+ for (let i: intptr = 2; i < args.length; ++i) {
+ const e: JSAny = args[i];
+ if (IsFastSmiElementsKind(elementsKind)) {
+ if (TaggedIsNotSmi(e)) {
+ const heapObject: HeapObject = UnsafeCast<HeapObject>(e);
+ elementsKind = IsHeapNumber(heapObject) ?
+ AllowDoubleElements(elementsKind) :
+ AllowNonNumberElements(elementsKind);
+ }
+ } else if (IsDoubleElementsKind(elementsKind)) {
+ if (!IsNumber(e)) {
+ elementsKind = AllowNonNumberElements(elementsKind);
+ }
+ }
+ }
- const deletedResult: JSArray =
- ExtractFastJSArray(context, a, actualStart, actualDeleteCount);
+ if (elementsKind != oldElementsKind) {
+ const smiElementsKind: Smi = Convert<Smi>(Convert<int32>(elementsKind));
+ TransitionElementsKindWithKind(context, a, smiElementsKind);
+ }
- if (newLength == 0) {
- a.elements = kEmptyFixedArray;
- a.length = 0;
- return deletedResult;
- }
+ // Make sure that the length hasn't been changed by side-effect.
+ const length: Smi = Cast<Smi>(a.length) otherwise Bailout;
+ if (originalLength != length) goto Bailout;
- if (IsFastSmiOrTaggedElementsKind(elementsKind)) {
- FastSplice<FixedArray, JSAny>(
- args, a, length, newLength, actualStart, insertCount,
- actualDeleteCount);
- } else {
- FastSplice<FixedDoubleArray, Number>(
- args, a, length, newLength, actualStart, insertCount,
- actualDeleteCount);
- }
+ const deletedResult: JSArray =
+ ExtractFastJSArray(context, a, actualStart, actualDeleteCount);
+ if (newLength == 0) {
+ a.elements = kEmptyFixedArray;
+ a.length = 0;
return deletedResult;
}
- transitioning macro FillDeletedElementsArray(
- context: Context, o: JSReceiver, actualStart: Number,
- actualDeleteCount: Number, a: JSReceiver): JSAny {
- // 10. Let k be 0.
- let k: Number = 0;
+ if (IsFastSmiOrTaggedElementsKind(elementsKind)) {
+ FastSplice<FixedArray, JSAny>(
+ args, a, length, newLength, actualStart, insertCount,
+ actualDeleteCount);
+ } else {
+ FastSplice<FixedDoubleArray, Number>(
+ args, a, length, newLength, actualStart, insertCount,
+ actualDeleteCount);
+ }
+
+ return deletedResult;
+}
- // 11. Repeat, while k < actualDeleteCount
- while (k < actualDeleteCount) {
- // a. Let from be ! ToString(actualStart + k).
- const from: Number = actualStart + k;
+transitioning macro FillDeletedElementsArray(
+ context: Context, o: JSReceiver, actualStart: Number,
+ actualDeleteCount: Number, a: JSReceiver): JSAny {
+ // 10. Let k be 0.
+ let k: Number = 0;
- // b. Let fromPresent be ? HasProperty(O, from).
- const fromPresent: Boolean = HasProperty(o, from);
+ // 11. Repeat, while k < actualDeleteCount
+ while (k < actualDeleteCount) {
+ // a. Let from be ! ToString(actualStart + k).
+ const from: Number = actualStart + k;
- // c. If fromPresent is true, then
- if (fromPresent == True) {
- // i. Let fromValue be ? Get(O, from).
- const fromValue: JSAny = GetProperty(o, from);
+ // b. Let fromPresent be ? HasProperty(O, from).
+ const fromPresent: Boolean = HasProperty(o, from);
- // ii. Perform ? CreateDataPropertyOrThrow(A, ! ToString(k), fromValue).
- FastCreateDataProperty(a, k, fromValue);
- }
+ // c. If fromPresent is true, then
+ if (fromPresent == True) {
+ // i. Let fromValue be ? Get(O, from).
+ const fromValue: JSAny = GetProperty(o, from);
- // d. Increment k by 1.
- k++;
+ // ii. Perform ? CreateDataPropertyOrThrow(A, ! ToString(k), fromValue).
+ FastCreateDataProperty(a, k, fromValue);
}
- // 12. Perform ? Set(A, "length", actualDeleteCount, true).
- SetProperty(a, kLengthString, actualDeleteCount);
- return a;
+
+ // d. Increment k by 1.
+ k++;
}
+ // 12. Perform ? Set(A, "length", actualDeleteCount, true).
+ SetProperty(a, kLengthString, actualDeleteCount);
+ return a;
+}
- // HandleForwardCase implements step 15. "If itemCount < actualDeleteCount,
- // then...""
- transitioning macro HandleForwardCase(
- context: Context, o: JSReceiver, len: Number, itemCount: Number,
- actualStart: Number, actualDeleteCount: Number): void {
- // 15. If itemCount < actualDeleteCount, then
- // a. Let k be actualStart.
- let k: Number = actualStart;
-
- // b. Repeat, while k < (len - actualDeleteCount)
- while (k < (len - actualDeleteCount)) {
- // i. Let from be ! ToString(k + actualDeleteCount).
- const from: Number = k + actualDeleteCount;
- // ii. Let to be ! ToString(k + itemCount).
- const to: Number = k + itemCount;
-
- // iii. Let fromPresent be ? HasProperty(O, from).
- const fromPresent: Boolean = HasProperty(o, from);
-
- // iv. If fromPresent is true, then
- if (fromPresent == True) {
- // 1. Let fromValue be ? Get(O, from).
- const fromValue: JSAny = GetProperty(o, from);
-
- // 2. Perform ? Set(O, to, fromValue, true).
- SetProperty(o, to, fromValue);
-
- // v. Else fromPresent is false,
- } else {
- // 1. Perform ? DeletePropertyOrThrow(O, to).
- DeleteProperty(o, to, LanguageMode::kStrict);
- }
- // vi. Increase k by 1.
- k++;
+// HandleForwardCase implements step 15. "If itemCount < actualDeleteCount,
+// then...""
+transitioning macro HandleForwardCase(
+ context: Context, o: JSReceiver, len: Number, itemCount: Number,
+ actualStart: Number, actualDeleteCount: Number): void {
+ // 15. If itemCount < actualDeleteCount, then
+ // a. Let k be actualStart.
+ let k: Number = actualStart;
+
+ // b. Repeat, while k < (len - actualDeleteCount)
+ while (k < (len - actualDeleteCount)) {
+ // i. Let from be ! ToString(k + actualDeleteCount).
+ const from: Number = k + actualDeleteCount;
+ // ii. Let to be ! ToString(k + itemCount).
+ const to: Number = k + itemCount;
+
+ // iii. Let fromPresent be ? HasProperty(O, from).
+ const fromPresent: Boolean = HasProperty(o, from);
+
+ // iv. If fromPresent is true, then
+ if (fromPresent == True) {
+ // 1. Let fromValue be ? Get(O, from).
+ const fromValue: JSAny = GetProperty(o, from);
+
+ // 2. Perform ? Set(O, to, fromValue, true).
+ SetProperty(o, to, fromValue);
+
+ // v. Else fromPresent is false,
+ } else {
+ // 1. Perform ? DeletePropertyOrThrow(O, to).
+ DeleteProperty(o, to, LanguageMode::kStrict);
}
+ // vi. Increase k by 1.
+ k++;
+ }
- // c. Let k be len.
- k = len;
+ // c. Let k be len.
+ k = len;
- // d. Repeat, while k > (len - actualDeleteCount + itemCount)
- while (k > (len - actualDeleteCount + itemCount)) {
- // i. Perform ? DeletePropertyOrThrow(O, ! ToString(k - 1)).
- DeleteProperty(o, k - 1, LanguageMode::kStrict);
- // ii. Decrease k by 1.
- k--;
- }
+ // d. Repeat, while k > (len - actualDeleteCount + itemCount)
+ while (k > (len - actualDeleteCount + itemCount)) {
+ // i. Perform ? DeletePropertyOrThrow(O, ! ToString(k - 1)).
+ DeleteProperty(o, k - 1, LanguageMode::kStrict);
+ // ii. Decrease k by 1.
+ k--;
}
+}
- // HandleBackwardCase implements step 16. "Else if itemCount >
- // actualDeleteCount, then..."
- transitioning macro HandleBackwardCase(
- context: Context, o: JSReceiver, len: Number, itemCount: Number,
- actualStart: Number, actualDeleteCount: Number): void {
- // 16. Else if itemCount > actualDeleteCount, then
- // a. Let k be (len - actualDeleteCount).
- let k: Number = len - actualDeleteCount;
-
- // b. Repeat, while k > actualStart
- while (k > actualStart) {
- // i. Let from be ! ToString(k + actualDeleteCount - 1).
- const from: Number = k + actualDeleteCount - 1;
+// HandleBackwardCase implements step 16. "Else if itemCount >
+// actualDeleteCount, then..."
+transitioning macro HandleBackwardCase(
+ context: Context, o: JSReceiver, len: Number, itemCount: Number,
+ actualStart: Number, actualDeleteCount: Number): void {
+ // 16. Else if itemCount > actualDeleteCount, then
+ // a. Let k be (len - actualDeleteCount).
+ let k: Number = len - actualDeleteCount;
- // ii. Let to be ! ToString(k + itemCount - 1).
- const to: Number = k + itemCount - 1;
+ // b. Repeat, while k > actualStart
+ while (k > actualStart) {
+ // i. Let from be ! ToString(k + actualDeleteCount - 1).
+ const from: Number = k + actualDeleteCount - 1;
- // iii. Let fromPresent be ? HasProperty(O, from).
- const fromPresent: Boolean = HasProperty(o, from);
+ // ii. Let to be ! ToString(k + itemCount - 1).
+ const to: Number = k + itemCount - 1;
- // iv. If fromPresent is true, then
- if (fromPresent == True) {
- // 1. Let fromValue be ? Get(O, from).
- const fromValue: JSAny = GetProperty(o, from);
+ // iii. Let fromPresent be ? HasProperty(O, from).
+ const fromPresent: Boolean = HasProperty(o, from);
- // 2. Perform ? Set(O, to, fromValue, true).
- SetProperty(o, to, fromValue);
+ // iv. If fromPresent is true, then
+ if (fromPresent == True) {
+ // 1. Let fromValue be ? Get(O, from).
+ const fromValue: JSAny = GetProperty(o, from);
- // v. Else fromPresent is false,
- } else {
- // 1. Perform ? DeletePropertyOrThrow(O, to).
- DeleteProperty(o, to, LanguageMode::kStrict);
- }
+ // 2. Perform ? Set(O, to, fromValue, true).
+ SetProperty(o, to, fromValue);
- // vi. Decrease k by 1.
- k--;
+ // v. Else fromPresent is false,
+ } else {
+ // 1. Perform ? DeletePropertyOrThrow(O, to).
+ DeleteProperty(o, to, LanguageMode::kStrict);
}
+
+ // vi. Decrease k by 1.
+ k--;
}
+}
- transitioning macro SlowSplice(
- context: Context, arguments: Arguments, o: JSReceiver, len: Number,
- actualStart: Number, insertCount: Smi, actualDeleteCount: Number): JSAny {
- // 9. Let A be ? ArraySpeciesCreate(O, actualDeleteCount).
- const a: JSReceiver = ArraySpeciesCreate(context, o, actualDeleteCount);
- const itemCount: Number = insertCount;
-
- // Steps 9 through 12: creating the array of deleted elements.
- FillDeletedElementsArray(context, o, actualStart, actualDeleteCount, a);
-
- // 13. Let items be a List whose elements are, in left-to-right order,
- // the portion of the actual argument list starting with the third
- // argument. The list is empty if fewer than three arguments were
- // passed.
- // 14. Let itemCount be the Number of elements in items.
- // (done above).
-
- // 15. If itemCount < actualDeleteCount, then
- if (itemCount < actualDeleteCount) {
- HandleForwardCase(
- context, o, len, itemCount, actualStart, actualDeleteCount);
- // 16. Else if itemCount > actualDeleteCount, then
- } else if (itemCount > actualDeleteCount) {
- HandleBackwardCase(
- context, o, len, itemCount, actualStart, actualDeleteCount);
- }
+transitioning macro SlowSplice(
+ context: Context, arguments: Arguments, o: JSReceiver, len: Number,
+ actualStart: Number, insertCount: Smi, actualDeleteCount: Number): JSAny {
+ // 9. Let A be ? ArraySpeciesCreate(O, actualDeleteCount).
+ const a: JSReceiver = ArraySpeciesCreate(context, o, actualDeleteCount);
+ const itemCount: Number = insertCount;
+
+ // Steps 9 through 12: creating the array of deleted elements.
+ FillDeletedElementsArray(context, o, actualStart, actualDeleteCount, a);
+
+ // 13. Let items be a List whose elements are, in left-to-right order,
+ // the portion of the actual argument list starting with the third
+ // argument. The list is empty if fewer than three arguments were
+ // passed.
+ // 14. Let itemCount be the Number of elements in items.
+ // (done above).
+
+ // 15. If itemCount < actualDeleteCount, then
+ if (itemCount < actualDeleteCount) {
+ HandleForwardCase(
+ context, o, len, itemCount, actualStart, actualDeleteCount);
+ // 16. Else if itemCount > actualDeleteCount, then
+ } else if (itemCount > actualDeleteCount) {
+ HandleBackwardCase(
+ context, o, len, itemCount, actualStart, actualDeleteCount);
+ }
- // 17. Let k be actualStart.
- let k: Number = actualStart;
+ // 17. Let k be actualStart.
+ let k: Number = actualStart;
- // 18. Repeat, while items is not empty
- // a. Remove the first element from items and let E be the value of that
- // element.
- if (arguments.length > 2) {
- for (let i: intptr = 2; i < arguments.length; ++i) {
- const e: JSAny = arguments[i];
- // b. Perform ? Set(O, ! ToString(k), E, true).
- SetProperty(o, k, e);
+ // 18. Repeat, while items is not empty
+ // a. Remove the first element from items and let E be the value of that
+ // element.
+ if (arguments.length > 2) {
+ for (let i: intptr = 2; i < arguments.length; ++i) {
+ const e: JSAny = arguments[i];
+ // b. Perform ? Set(O, ! ToString(k), E, true).
+ SetProperty(o, k, e);
- // c. Increase k by 1.
- k = k + 1;
- }
+ // c. Increase k by 1.
+ k = k + 1;
}
-
- // 19. Perform ? Set(O, "length", len - actualDeleteCount + itemCount,
- // true).
- SetProperty(o, kLengthString, len - actualDeleteCount + itemCount);
-
- return a;
}
- // https://tc39.github.io/ecma262/#sec-array.prototype.splice
- transitioning javascript builtin
- ArrayPrototypeSplice(js-implicit context: NativeContext, receiver: JSAny)(
- ...arguments): JSAny {
- // 1. Let O be ? ToObject(this value).
- const o: JSReceiver = ToObject(context, receiver);
-
- // 2. Let len be ? ToLength(? Get(O, "length")).
- const len: Number = GetLengthProperty(o);
-
- // 3. Let relativeStart be ? ToInteger(start).
- const start: JSAny = arguments[0];
- const relativeStart: Number = ToInteger_Inline(start);
-
- // 4. If relativeStart < 0, let actualStart be max((len + relativeStart),
- // 0);
- // else let actualStart be min(relativeStart, len).
- const actualStart: Number = relativeStart < 0 ?
- Max((len + relativeStart), 0) :
- Min(relativeStart, len);
-
- let insertCount: Smi;
- let actualDeleteCount: Number;
- // 5. If the Number of actual arguments is 0, then
- if (arguments.length == 0) {
- // a. Let insertCount be 0.
- insertCount = 0;
- // b. Let actualDeleteCount be 0.
- actualDeleteCount = 0;
- // 6. Else if the Number of actual arguments is 1, then
- } else if (arguments.length == 1) {
- // a. Let insertCount be 0.
- insertCount = 0;
- // b. Let actualDeleteCount be len - actualStart.
- actualDeleteCount = len - actualStart;
- // 7. Else,
- } else {
- // a. Let insertCount be the Number of actual arguments minus 2.
- insertCount = Convert<Smi>(arguments.length) - 2;
- // b. Let dc be ? ToInteger(deleteCount).
- const deleteCount: JSAny = arguments[1];
- const dc: Number = ToInteger_Inline(deleteCount);
- // c. Let actualDeleteCount be min(max(dc, 0), len - actualStart).
- actualDeleteCount = Min(Max(dc, 0), len - actualStart);
- }
+ // 19. Perform ? Set(O, "length", len - actualDeleteCount + itemCount,
+ // true).
+ SetProperty(o, kLengthString, len - actualDeleteCount + itemCount);
- // 8. If len + insertCount - actualDeleteCount > 2^53-1, throw a
- // Bailout exception.
- const newLength: Number = len + insertCount - actualDeleteCount;
- if (newLength > kMaxSafeInteger) {
- ThrowTypeError(MessageTemplate::kInvalidArrayLength, start);
- }
+ return a;
+}
- try {
- return FastArraySplice(
- context, arguments, o, len, actualStart, insertCount,
- actualDeleteCount) otherwise Bailout;
- }
- label Bailout {}
+// https://tc39.github.io/ecma262/#sec-array.prototype.splice
+transitioning javascript builtin
+ArrayPrototypeSplice(
+ js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
+ // 1. Let O be ? ToObject(this value).
+ const o: JSReceiver = ToObject(context, receiver);
+
+ // 2. Let len be ? ToLength(? Get(O, "length")).
+ const len: Number = GetLengthProperty(o);
+
+ // 3. Let relativeStart be ? ToInteger(start).
+ const start: JSAny = arguments[0];
+ const relativeStart: Number = ToInteger_Inline(start);
+
+ // 4. If relativeStart < 0, let actualStart be max((len + relativeStart),
+ // 0);
+ // else let actualStart be min(relativeStart, len).
+ const actualStart: Number = relativeStart < 0 ?
+ Max((len + relativeStart), 0) :
+ Min(relativeStart, len);
+
+ let insertCount: Smi;
+ let actualDeleteCount: Number;
+ // 5. If the Number of actual arguments is 0, then
+ if (arguments.length == 0) {
+ // a. Let insertCount be 0.
+ insertCount = 0;
+ // b. Let actualDeleteCount be 0.
+ actualDeleteCount = 0;
+ // 6. Else if the Number of actual arguments is 1, then
+ } else if (arguments.length == 1) {
+ // a. Let insertCount be 0.
+ insertCount = 0;
+ // b. Let actualDeleteCount be len - actualStart.
+ actualDeleteCount = len - actualStart;
+ // 7. Else,
+ } else {
+ // a. Let insertCount be the Number of actual arguments minus 2.
+ insertCount = Convert<Smi>(arguments.length) - 2;
+ // b. Let dc be ? ToInteger(deleteCount).
+ const deleteCount: JSAny = arguments[1];
+ const dc: Number = ToInteger_Inline(deleteCount);
+ // c. Let actualDeleteCount be min(max(dc, 0), len - actualStart).
+ actualDeleteCount = Min(Max(dc, 0), len - actualStart);
+ }
- // If the fast case fails, just continue with the slow, correct,
- // spec-compliant case.
- return SlowSplice(
- context, arguments, o, len, actualStart, insertCount,
- actualDeleteCount);
+ // 8. If len + insertCount - actualDeleteCount > 2^53-1, throw a
+ // Bailout exception.
+ const newLength: Number = len + insertCount - actualDeleteCount;
+ if (newLength > kMaxSafeInteger) {
+ ThrowTypeError(MessageTemplate::kInvalidArrayLength, start);
}
+
+ try {
+ return FastArraySplice(
+ context, arguments, o, len, actualStart, insertCount, actualDeleteCount)
+ otherwise Bailout;
+ } label Bailout {}
+
+ // If the fast case fails, just continue with the slow, correct,
+ // spec-compliant case.
+ return SlowSplice(
+ context, arguments, o, len, actualStart, insertCount, actualDeleteCount);
+}
}