aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/builtins/array.tq
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/builtins/array.tq')
-rw-r--r--deps/v8/src/builtins/array.tq321
1 files changed, 37 insertions, 284 deletions
diff --git a/deps/v8/src/builtins/array.tq b/deps/v8/src/builtins/array.tq
index 590947dd44..df4387878d 100644
--- a/deps/v8/src/builtins/array.tq
+++ b/deps/v8/src/builtins/array.tq
@@ -14,303 +14,56 @@ module array {
type FastDoubleElements;
type DictionaryElements;
- macro GetLengthProperty(context: Context, o: Object): Number {
- if (BranchIfFastJSArray(o, context)) {
- let a: JSArray = unsafe_cast<JSArray>(o);
- return a.length_fast;
- } else
- deferred {
- return ToLength_Inline(context, GetProperty(context, o, 'length'));
- }
- }
-
- macro FastArraySplice(
- context: Context, args: constexpr Arguments, o: Object,
- originalLengthNumber: Number, actualStartNumber: Number, insertCount: Smi,
- actualDeleteCountNumber: Number): Object
- labels Bailout {
- let originalLength: Smi = cast<Smi>(originalLengthNumber) otherwise Bailout;
- let actualStart: Smi = cast<Smi>(actualStartNumber) otherwise Bailout;
- let actualDeleteCount: Smi =
- cast<Smi>(actualDeleteCountNumber) otherwise Bailout;
- let lengthDelta: Smi = insertCount - actualDeleteCount;
- let newLength: Smi = originalLength + lengthDelta;
-
- let a: JSArray = cast<JSArray>(o) otherwise Bailout;
-
- let map: Map = a.map;
- if (!IsPrototypeInitialArrayPrototype(context, 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;
-
- // For now, only support non-double fast elements
- if (!IsFastSmiOrTaggedElementsKind(elementsKind)) goto Bailout;
-
- if (IsFastSmiElementsKind(elementsKind)) {
- for (let e: Object of args [2: ]) {
- if (TaggedIsNotSmi(e)) goto Bailout;
- }
- }
-
- // Make sure that the length hasn't been changed by side-effect.
- let length: Smi = cast<Smi>(a.length) otherwise Bailout;
- if (originalLength != length) goto Bailout;
-
- let deletedResult: JSArray =
- ExtractFastJSArray(context, a, actualStart, actualDeleteCount);
-
- if (newLength == 0) {
- a.elements = kEmptyFixedArray;
- a.length = 0;
- return deletedResult;
- }
-
- let elements: FixedArray = cast<FixedArray>(a.elements) otherwise Bailout;
- let elementsMap: Map = elements.map;
-
- // If the source is a COW array or the spliced array is larger then the
- // source array, then allocate a new FixedArray to hold the result.
- let newElements: FixedArray = elements;
- if ((elementsMap == kCOWMap) || (lengthDelta > 0)) {
- newElements = ExtractFixedArray(
- elements, 0, actualStart, newLength, kAllFixedArrays);
- newElements.map = elementsMap;
- a.elements = newElements;
- }
+ macro EnsureWriteableFastElements(array: JSArray) {
+ assert(IsFastElementsKind(array.map.elements_kind));
- // Double check that the array is still in fast elements mode
- assert(IsFastSmiElementsKind(a.map.elements_kind));
+ const elements: FixedArrayBase = array.elements;
+ if (elements.map != kCOWMap) return;
- // Copy over inserted elements.
- let k: Smi = actualStart;
- if (insertCount > 0) {
- for (let e: Object of args [2: ]) {
- newElements[k++] = e;
- }
- }
-
- // Copy over elements after deleted elements.
- let count: Smi = length - actualStart - actualDeleteCount;
- while (count > 0) {
- let e: Object = elements[k - lengthDelta];
- newElements[k++] = e;
- count--;
- }
-
- // Fill rest of spliced FixedArray with the hole, but only if the
- // destination FixedArray is the original array's, since otherwise the array
- // is pre-filled with holes.
- if (elements == newElements) {
- let limit: Smi = elements.length;
- while (k < limit) {
- newElements[k++] = Hole;
- }
- }
-
- // Update the array's length after all the FixedArray shuffling is done.
- a.length = newLength;
+ // There are no COW *_DOUBLE_ELEMENTS arrays, so we are allowed to always
+ // extract FixedArrays and don't have to worry about FixedDoubleArrays.
+ assert(IsFastSmiOrTaggedElementsKind(array.map.elements_kind));
- return deletedResult;
+ const length: Smi = array.length_fast;
+ array.elements =
+ ExtractFixedArray(elements, 0, length, length, kFixedArrays);
+ assert(array.elements.map != kCOWMap);
}
- // https://tc39.github.io/ecma262/#sec-array.prototype.splice
- javascript builtin ArraySpliceTorque(
- context: Context, receiver: Object, ...arguments): Object {
- // 1. Let O be ? ToObject(this value).
- let o: JSReceiver = ToObject(context, receiver);
-
- // 2. Let len be ? ToLength(? Get(O, "length")).
- let len: Number = GetLengthProperty(context, o);
-
- // 3. Let relativeStart be ? ToInteger(start).
- let start: Object = arguments[0];
- let relativeStart: Number = ToInteger_Inline(context, start);
-
- // 4. If relativeStart < 0, let actualStart be max((len + relativeStart),
- // 0);
- // else let actualStart be min(relativeStart, len).
- let 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).
- let deleteCount: Object = arguments[1];
- let dc: Number = ToInteger_Inline(context, deleteCount);
- // c. Let actualDeleteCount be min(max(dc, 0), len - actualStart).
- actualDeleteCount = min(max(dc, 0), len - actualStart);
- }
-
- // 8. If len + insertCount - actualDeleteCount > 2^53-1, throw a
- // Bailout exception.
- if (len + insertCount - actualDeleteCount > kMaxSafeInteger) {
- ThrowRangeError(context, kInvalidArrayLength);
- }
-
+ macro IsJSArray(o: Object): bool {
try {
- return FastArraySplice(
- context, arguments, o, len, actualStart, insertCount,
- actualDeleteCount) otherwise Bailout;
+ const array: JSArray = Cast<JSArray>(o) otherwise NotArray;
+ return true;
}
- label Bailout {}
- // If the fast case fails, just continue with the slow, correct,
- // spec-compliant case.
-
- // 9. Let A be ? ArraySpeciesCreate(O, actualDeleteCount).
- let a: Object = ArraySpeciesCreate(context, o, actualDeleteCount);
-
- // 10. Let k be 0.
- let k: Number = 0;
-
- // 11. Repeat, while k < actualDeleteCount
- while (k < actualDeleteCount) {
- // a. Let from be ! ToString(actualStart + k).
- let from: String = ToString_Inline(context, actualStart + k);
-
- // b. Let fromPresent be ? HasProperty(O, from).
- let fromPresent: Oddball = HasProperty(context, o, from);
-
- // c. If fromPresent is true, then
- if (fromPresent == True) {
- // i. Let fromValue be ? Get(O, from).
- let fromValue: Object = GetProperty(context, o, from);
-
- // ii. Perform ? CreateDataPropertyOrThrow(A, ! ToString(k), fromValue).
- CreateDataProperty(context, a, ToString_Inline(context, k), fromValue);
- }
-
- // d. Increment k by 1.
- k = k + 1;
+ label NotArray {
+ return false;
}
+ }
- // 12. Perform ? Set(A, "length", actualDeleteCount, true).
- SetProperty(context, a, 'length', actualDeleteCount);
-
- // 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.
- let itemCount: Number = insertCount;
-
- // 15. If itemCount < actualDeleteCount, then
- if (itemCount < actualDeleteCount) {
- // 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).
- let from: String = ToString_Inline(context, k + actualDeleteCount);
- // ii. Let to be ! ToString(k + itemCount).
- let to: String = ToString_Inline(context, k + itemCount);
-
- // iii. Let fromPresent be ? HasProperty(O, from).
- let fromPresent: Oddball = HasProperty(context, o, from);
-
- // iv. If fromPresent is true, then
- if (fromPresent == True) {
- // 1. Let fromValue be ? Get(O, from).
- let fromValue: Object = GetProperty(context, o, from);
-
- // 2. Perform ? Set(O, to, fromValue, true).
- SetProperty(context, o, to, fromValue);
-
- // v. Else fromPresent is false,
- } else {
- // 1. Perform ? DeletePropertyOrThrow(O, to).
- DeleteProperty(context, o, to, kStrict);
- }
- // vi. Increase k by 1.
- k = k + 1;
- }
-
- // 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(context, o, ToString_Inline(context, k - 1), kStrict);
-
- // ii. Decrease k by 1.
- k = k - 1;
- }
- // 16. Else if itemCount > actualDeleteCount, then
- } else if (itemCount > actualDeleteCount) {
- // 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).
- let from: String = ToString_Inline(context, k + actualDeleteCount - 1);
-
- // ii. Let to be ! ToString(k + itemCount - 1).
- let to: String = ToString_Inline(context, k + itemCount - 1);
-
- // iii. Let fromPresent be ? HasProperty(O, from).
- let fromPresent: Oddball = HasProperty(context, o, from);
-
- // iv. If fromPresent is true, then
- if (fromPresent == True) {
- // 1. Let fromValue be ? Get(O, from).
- let fromValue: Object = GetProperty(context, o, from);
+ macro StoreArrayHole(elements: FixedDoubleArray, k: Smi): void {
+ StoreFixedDoubleArrayHoleSmi(elements, k);
+ }
- // 2. Perform ? Set(O, to, fromValue, true).
- SetProperty(context, o, to, fromValue);
+ macro StoreArrayHole(elements: FixedArray, k: Smi): void {
+ elements[k] = Hole;
+ }
- // v. Else fromPresent is false,
- } else {
- // 1. Perform ? DeletePropertyOrThrow(O, to).
- DeleteProperty(context, o, to, kStrict);
- }
+ macro CopyArrayElement(
+ elements: FixedArray, newElements: FixedArray, from: Smi, to: Smi): void {
+ const e: Object = elements[from];
+ newElements[to] = e;
+ }
- // vi. Decrease k by 1.
- k = k - 1;
- }
+ macro CopyArrayElement(
+ elements: FixedDoubleArray, newElements: FixedDoubleArray, from: Smi,
+ to: Smi): void {
+ try {
+ const floatValue: float64 = LoadDoubleWithHoleCheck(elements, from)
+ otherwise FoundHole;
+ newElements[to] = floatValue;
}
-
- // 17. Let k be actualStart.
- k = 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 e: Object of arguments [2: ]) {
- // b. Perform ? Set(O, ! ToString(k), E, true).
- SetProperty(context, o, ToString_Inline(context, k), e);
-
- // c. Increase k by 1.
- k = k + 1;
- }
+ label FoundHole {
+ StoreArrayHole(newElements, to);
}
-
- // 19. Perform ? Set(O, "length", len - actualDeleteCount + itemCount,
- // true).
- SetProperty(context, o, 'length', len - actualDeleteCount + itemCount);
-
- return a;
}
}