diff options
Diffstat (limited to 'deps/v8/src/builtins/array-from.tq')
-rw-r--r-- | deps/v8/src/builtins/array-from.tq | 323 |
1 files changed, 161 insertions, 162 deletions
diff --git a/deps/v8/src/builtins/array-from.tq b/deps/v8/src/builtins/array-from.tq index 6eb3b006935..e51d37fef2c 100644 --- a/deps/v8/src/builtins/array-from.tq +++ b/deps/v8/src/builtins/array-from.tq @@ -3,182 +3,181 @@ // found in the LICENSE file. namespace array { - // Array.from( items [, mapfn [, thisArg ] ] ) - // ES #sec-array.from - transitioning javascript builtin - ArrayFrom(js-implicit context: NativeContext, receiver: JSAny)(...arguments): - JSReceiver { - // Use fast path if: - // * |items| is the only argument, and - // * the receiver is the Array function. - if (arguments.length == 1 && receiver == GetArrayFunction()) { - try { - return iterator::FastIterableToList(arguments[0]) otherwise Slow; - } - label Slow { - // fall through - } +// Array.from( items [, mapfn [, thisArg ] ] ) +// ES #sec-array.from +transitioning javascript builtin +ArrayFrom(js-implicit context: NativeContext, receiver: JSAny)(...arguments): + JSReceiver { + // Use fast path if: + // * |items| is the only argument, and + // * the receiver is the Array function. + if (arguments.length == 1 && receiver == GetArrayFunction()) { + try { + return iterator::FastIterableToList(arguments[0]) otherwise Slow; + } label Slow { + // fall through } + } - const items = arguments[0]; - const mapfn = arguments[1]; - const thisArg = arguments[2]; - - // 1. Let C be the this value. - const c = receiver; - - let mapping: bool; - // 2. If mapfn is undefined, let mapping be false. - if (mapfn == Undefined) { - mapping = false; - } else { - // a. If IsCallable(mapfn) is false, throw a TypeError exception. - if (!TaggedIsCallable(mapfn)) deferred { - ThrowTypeError(MessageTemplate::kCalledNonCallable, mapfn); - } - // b. Let mapping be true. - mapping = true; + const items = arguments[0]; + const mapfn = arguments[1]; + const thisArg = arguments[2]; + + // 1. Let C be the this value. + const c = receiver; + + let mapping: bool; + // 2. If mapfn is undefined, let mapping be false. + if (mapfn == Undefined) { + mapping = false; + } else { + // a. If IsCallable(mapfn) is false, throw a TypeError exception. + if (!Is<Callable>(mapfn)) deferred { + ThrowTypeError(MessageTemplate::kCalledNonCallable, mapfn); + } + // b. Let mapping be true. + mapping = true; + } + + // 4. Let usingIterator be ? GetMethod(items, @@iterator). + // 5. If usingIterator is not undefined, then + try { + const usingIterator = GetMethod(items, IteratorSymbolConstant()) + otherwise IteratorIsUndefined, IteratorNotCallable; + + let a: JSReceiver; + // a. If IsConstructor(C) is true, then + typeswitch (c) { + case (c: Constructor): { + // i. Let A be ? Construct(C). + a = Construct(c); + } + case (JSAny): { + // i. Let A be ? ArrayCreate(0). + a = ArrayCreate(0); + } } - // 4. Let usingIterator be ? GetMethod(items, @@iterator). - // 5. If usingIterator is not undefined, then - try { - const usingIterator = GetMethod(items, IteratorSymbolConstant()) - otherwise IteratorIsUndefined, IteratorNotCallable; - - let a: JSReceiver; - // a. If IsConstructor(C) is true, then - typeswitch (c) { - case (c: Constructor): { - // i. Let A be ? Construct(C). - a = Construct(c); - } - case (JSAny): { - // i. Let A be ? ArrayCreate(0). - a = ArrayCreate(0); - } + // c. Let iteratorRecord be ? GetIterator(items, sync, usingIterator). + const iteratorRecord = iterator::GetIterator(items, usingIterator); + + const fastIteratorResultMap = GetIteratorResultMap(); + + // d. Let k be 0. + let k: Smi = 0; + // e. Repeat, + while (true) { + // i. If k ≥ 2^53-1, then + // 1. Let error be ThrowCompletion(a newly created TypeError object). + // 2. Return ? IteratorClose(iteratorRecord, error). + // The spec requires that we throw an exception if index reaches 2^53-1, + // but an empty loop would take >100 days to do this many iterations. To + // actually run for that long would require an iterator that never set + // done to true and a target array which somehow never ran out of + // memory, e.g. a proxy that discarded the values. Ignoring this case + // just means we would repeatedly call CreateDataProperty with index = + // 2^53 + assert(k < kMaxSafeInteger); + + // ii. Let Pk be ! ToString(k). + + // iii. Let next be ? IteratorStep(iteratorRecord). + let next: JSReceiver; + try { + next = iterator::IteratorStep(iteratorRecord, fastIteratorResultMap) + otherwise NextIsFalse; + } + // iv. If next is false, then + label NextIsFalse { + // 1. Perform ? Set(A, "length", k, true). + array::SetPropertyLength(a, k); + // 2. Return A. + return a; } - // c. Let iteratorRecord be ? GetIterator(items, sync, usingIterator). - const iteratorRecord = iterator::GetIterator(items, usingIterator); - - const fastIteratorResultMap = GetIteratorResultMap(); - - // d. Let k be 0. - let k: Smi = 0; - // e. Repeat, - while (true) { - // i. If k ≥ 2^53-1, then - // 1. Let error be ThrowCompletion(a newly created TypeError object). - // 2. Return ? IteratorClose(iteratorRecord, error). - // The spec requires that we throw an exception if index reaches 2^53-1, - // but an empty loop would take >100 days to do this many iterations. To - // actually run for that long would require an iterator that never set - // done to true and a target array which somehow never ran out of - // memory, e.g. a proxy that discarded the values. Ignoring this case - // just means we would repeatedly call CreateDataProperty with index = - // 2^53 - assert(k < kMaxSafeInteger); - - // ii. Let Pk be ! ToString(k). - - // iii. Let next be ? IteratorStep(iteratorRecord). - let next: JSReceiver; - try { - next = iterator::IteratorStep(iteratorRecord, fastIteratorResultMap) - otherwise NextIsFalse; - } - // iv. If next is false, then - label NextIsFalse { - // 1. Perform ? Set(A, "length", k, true). - array::SetPropertyLength(a, k); - // 2. Return A. - return a; - } + // v. Let nextValue be ? IteratorValue(next). + const nextValue = iterator::IteratorValue(next, fastIteratorResultMap); - // v. Let nextValue be ? IteratorValue(next). - const nextValue = iterator::IteratorValue(next, fastIteratorResultMap); - - let mappedValue: JSAny; - // vi. If mapping is true, then - if (mapping) { - // 1. Let mappedValue be Call(mapfn, thisArg, « nextValue, k »). - // 2. If mappedValue is an abrupt completion, - // return ? IteratorClose(iteratorRecord, mappedValue). - // 3. Set mappedValue to mappedValue.[[Value]]. - try { - mappedValue = Call( - context, UnsafeCast<Callable>(mapfn), thisArg, nextValue, k); - } catch (e) { - iterator::IteratorCloseOnException(iteratorRecord, e); - } - } else { - mappedValue = nextValue; - } - // viii. Let defineStatus be - // CreateDataPropertyOrThrow(A, Pk, mappedValue). - // ix. If defineStatus is an abrupt completion, - // return ? IteratorClose(iteratorRecord, defineStatus). + let mappedValue: JSAny; + // vi. If mapping is true, then + if (mapping) { + // 1. Let mappedValue be Call(mapfn, thisArg, « nextValue, k »). + // 2. If mappedValue is an abrupt completion, + // return ? IteratorClose(iteratorRecord, mappedValue). + // 3. Set mappedValue to mappedValue.[[Value]]. try { - FastCreateDataProperty(a, k, mappedValue); - } catch (e) deferred { - iterator::IteratorCloseOnException(iteratorRecord, e); + mappedValue = + Call(context, UnsafeCast<Callable>(mapfn), thisArg, nextValue, k); + } catch (e) { + iterator::IteratorCloseOnException(iteratorRecord); + ReThrow(context, e); } - // x. Set k to k + 1. - k += 1; + } else { + mappedValue = nextValue; } - unreachable; + // viii. Let defineStatus be + // CreateDataPropertyOrThrow(A, Pk, mappedValue). + // ix. If defineStatus is an abrupt completion, + // return ? IteratorClose(iteratorRecord, defineStatus). + try { + FastCreateDataProperty(a, k, mappedValue); + } catch (e) deferred { + iterator::IteratorCloseOnException(iteratorRecord); + ReThrow(context, e); + } + // x. Set k to k + 1. + k += 1; } - label IteratorIsUndefined { - // 6. NOTE: items is not an Iterable so assume it is an array-like object. - // 7. Let arrayLike be ! ToObject(items). - const arrayLike = ToObject_Inline(context, items); - // 8. Let len be ? LengthOfArrayLike(arrayLike). - const len = GetLengthProperty(arrayLike); - - let a: JSReceiver; - // 9. If IsConstructor(C) is true, then - typeswitch (c) { - case (c: Constructor): { - // a. Let A be ? Construct(C, « len »). - a = Construct(c, len); - } - case (JSAny): { - // a. Let A be ? ArrayCreate(len). - a = ArrayCreate(len); - } + unreachable; + } label IteratorIsUndefined { + // 6. NOTE: items is not an Iterable so assume it is an array-like object. + // 7. Let arrayLike be ! ToObject(items). + const arrayLike = ToObject_Inline(context, items); + // 8. Let len be ? LengthOfArrayLike(arrayLike). + const len = GetLengthProperty(arrayLike); + + let a: JSReceiver; + // 9. If IsConstructor(C) is true, then + typeswitch (c) { + case (c: Constructor): { + // a. Let A be ? Construct(C, « len »). + a = Construct(c, len); } - - // 11. Let k be 0. - let k: Smi = 0; - // 12. Repeat, while k < len - while (k < len) { - // a. Let Pk be ! ToString(k). - // b. Let kValue be ? Get(arrayLike, Pk). - const kValue = GetProperty(arrayLike, k); - let mappedValue: JSAny; - // c. If mapping is true, then - if (mapping) { - // i. Let mappedValue be ? Call(mapfn, thisArg, « kValue, k »). - mappedValue = - Call(context, UnsafeCast<Callable>(mapfn), thisArg, kValue, k); - } else { - // d. Else, let mappedValue be kValue. - mappedValue = kValue; - } - // e. Perform ? CreateDataPropertyOrThrow(A, Pk, mappedValue). - FastCreateDataProperty(a, k, mappedValue); - // f. Set k to k + 1. - k += 1; + case (JSAny): { + // a. Let A be ? ArrayCreate(len). + a = ArrayCreate(len); } - - // 13. Perform ? Set(A, "length", len, true). - array::SetPropertyLength(a, len); - // 14. Return A. - return a; } - label IteratorNotCallable(_value: JSAny) deferred { - ThrowTypeError(MessageTemplate::kIteratorSymbolNonCallable); + + // 11. Let k be 0. + let k: Smi = 0; + // 12. Repeat, while k < len + while (k < len) { + // a. Let Pk be ! ToString(k). + // b. Let kValue be ? Get(arrayLike, Pk). + const kValue = GetProperty(arrayLike, k); + let mappedValue: JSAny; + // c. If mapping is true, then + if (mapping) { + // i. Let mappedValue be ? Call(mapfn, thisArg, « kValue, k »). + mappedValue = + Call(context, UnsafeCast<Callable>(mapfn), thisArg, kValue, k); + } else { + // d. Else, let mappedValue be kValue. + mappedValue = kValue; + } + // e. Perform ? CreateDataPropertyOrThrow(A, Pk, mappedValue). + FastCreateDataProperty(a, k, mappedValue); + // f. Set k to k + 1. + k += 1; } + + // 13. Perform ? Set(A, "length", len, true). + array::SetPropertyLength(a, len); + // 14. Return A. + return a; + } label IteratorNotCallable(_value: JSAny) deferred { + ThrowTypeError(MessageTemplate::kIteratorSymbolNonCallable); } } +} |