/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
deps/v8/src/builtins/array-flat.tq
272 строки
10 KB
Michaël Zasso
deps: update V8 to 12.2.281.27
31 мар 2024, 16:36
Не верифицирован
31 мар 2024, 16:36
09a8440
Код
Авторство
О чём код?
// Copyright 2023 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. namespace array { transitioning macro ArrayIsArray_Inline( implicit context: Context)(element: JSAny): Boolean { if (Is<JSArray>(element)) { return True; } else if (Is<JSProxy>(element)) { return Cast<Boolean>(runtime::ArrayIsArray(element)) otherwise unreachable; } else { return False; } } transitioning macro FlattenIntoArrayFast( implicit context: Context)(target: JSReceiver, source: JSReceiver, sourceLength: Number, start: Number, depth: Smi, hasMapper: constexpr bool, mapfn: JSAny, thisArgs: JSAny): Number labels Bailout(Number, Number) { // 1. Let targetIndex be start. let targetIndex: Number = start; // 2. Let sourceIndex be 0. let smiSourceIndex: Smi = 0; const fastSource = Cast<FastJSArray>(source) otherwise goto Bailout(targetIndex, smiSourceIndex); let fastOW = NewFastJSArrayWitness(fastSource); // The source is a FastJSArray, thus its length must be a Smi. dcheck(Is<Smi>(sourceLength)); const smiSourceLength = UnsafeCast<Smi>(sourceLength); // 3. Repeat, while sourceIndex < sourceLen for (; smiSourceIndex < smiSourceLength; smiSourceIndex++) { fastOW.Recheck() otherwise goto Bailout(targetIndex, smiSourceIndex); // Ensure that we haven't walked beyond a possibly updated length. if (smiSourceIndex >= fastOW.Get().length) goto Bailout(targetIndex, smiSourceIndex); // a. Let P be ! ToString(sourceIndex). // b. Let exists be ? HasProperty(source, P). // i. Let element be ? Get(source, P). let element = fastOW.LoadElementNoHole(smiSourceIndex) otherwise continue; // ii. If mapperFunction is present, then if constexpr (hasMapper) { // 1. Set element to ? Call(mapperFunction, thisArgs , « element, // sourceIndex, source »). element = Call(context, mapfn, thisArgs, element, smiSourceIndex, source); } // iii. Let shouldFlatten be false. let shouldFlatten: Boolean = False; // iv. If depth > 0, then let elementLength: Number = 0; if (depth > 0) { // Set shouldFlatten to ? IsArray(element). // 1. Let elementLen be ? ToLength(? Get(element, "length")). try { const elementJSArray: JSArray = Cast<JSArray>(element) otherwise NonJSArray; shouldFlatten = True; elementLength = elementJSArray.length; } label NonJSArray { if (Is<JSProxy>(element)) { shouldFlatten = Cast<Boolean>(runtime::ArrayIsArray(element)) otherwise unreachable; } if (shouldFlatten == True) { elementLength = GetLengthProperty(element); } } } // v. If shouldFlatten is true, then if (shouldFlatten == True) { if (elementLength > 0) { // 2. Set targetIndex to ? FlattenIntoArray(target, element, // elementLen, targetIndex, depth - 1). const element = Cast<JSReceiver>(element) otherwise unreachable; targetIndex = FlattenIntoArrayWithoutMapFn( target, element, elementLength, targetIndex, depth - 1); } } else { // 1. If targetIndex >= 2^53-1, throw a TypeError exception. if (targetIndex >= kMaxSafeInteger) deferred { ThrowTypeError( MessageTemplate::kFlattenPastSafeLength, sourceLength, targetIndex); } // 2. Perform ? CreateDataPropertyOrThrow(target, // ! ToString(targetIndex), // element). FastCreateDataProperty(target, targetIndex, element); targetIndex++; } } return targetIndex; } // https://tc39.github.io/proposal-flatMap/#sec-FlattenIntoArray transitioning macro FlattenIntoArraySlow( implicit context: Context)(target: JSReceiver, source: JSReceiver, sourceIndex: Number, sourceLength: Number, start: Number, depth: Smi, hasMapper: constexpr bool, mapfn: JSAny, thisArgs: JSAny): Number { // 1. Let targetIndex be start. let targetIndex: Number = start; // 2. Let sourceIndex be 0. let sourceIndex: Number = sourceIndex; // 3. Repeat, while sourceIndex < sourceLen while (sourceIndex < sourceLength) { // a. Let P be ! ToString(sourceIndex). // b. Let exists be ? HasProperty(source, P). const exists: Boolean = HasProperty(source, sourceIndex); if (exists == True) { let element: JSAny; // i. Let element be ? Get(source, P). element = GetProperty(source, sourceIndex); // ii. If mapperFunction is present, then if constexpr (hasMapper) { // 1. Set element to ? Call(mapperFunction, thisArgs , « element, // sourceIndex, source »). element = Call(context, mapfn, thisArgs, element, sourceIndex, source); } // iii. Let shouldFlatten be false. let shouldFlatten: Boolean = False; // iv. If depth > 0, then if (depth > 0) { // Set shouldFlatten to ? IsArray(element). shouldFlatten = ArrayIsArray_Inline(element); } // v. If shouldFlatten is true, then if (shouldFlatten == True) { // 1. Let elementLen be ? ToLength(? Get(element, "length")). const elementLength: Number = GetLengthProperty(element); // 2. Set targetIndex to ? FlattenIntoArray(target, element, // elementLen, targetIndex, depth - 1). const element = Cast<JSReceiver>(element) otherwise unreachable; targetIndex = FlattenIntoArrayWithoutMapFn( target, element, elementLength, targetIndex, depth - 1); } else { // 1. If targetIndex >= 2^53-1, throw a TypeError exception. if (targetIndex >= kMaxSafeInteger) deferred { ThrowTypeError( MessageTemplate::kFlattenPastSafeLength, sourceLength, targetIndex); } // 2. Perform ? CreateDataPropertyOrThrow(target, // ! ToString(targetIndex), // element). FastCreateDataProperty(target, targetIndex, element); targetIndex++; } } // d. Increase sourceIndex by 1. sourceIndex++; } return targetIndex; } transitioning macro FlattenIntoArray( implicit context: Context)(target: JSReceiver, source: JSReceiver, sourceLength: Number, start: Number, depth: Smi, hasMapper: constexpr bool, mapfn: JSAny, thisArgs: JSAny): Number { try { return FlattenIntoArrayFast( target, source, sourceLength, start, depth, hasMapper, mapfn, thisArgs) otherwise Bailout; } label Bailout(kTargetIndex: Number, kSourceIndex: Number) { return FlattenIntoArraySlow( target, source, kSourceIndex, sourceLength, kTargetIndex, depth, hasMapper, mapfn, thisArgs); } } transitioning builtin FlattenIntoArrayWithoutMapFn( implicit context: Context)(target: JSReceiver, source: JSReceiver, sourceLength: Number, start: Number, depth: Smi): Number { // This builtin might get called recursively, check stack for overflow // manually as it has stub linkage. PerformStackCheck(); return FlattenIntoArray( target, source, sourceLength, start, depth, false, Undefined, Undefined); } transitioning builtin FlattenIntoArrayWithMapFn( implicit context: Context)(target: JSReceiver, source: JSReceiver, sourceLength: Number, start: Number, depth: Smi, mapfn: JSAny, thisArgs: JSAny): Number { return FlattenIntoArray( target, source, sourceLength, start, depth, true, mapfn, thisArgs); } // https://tc39.github.io/proposal-flatMap/#sec-Array.prototype.flat transitioning javascript builtin ArrayPrototypeFlat( js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny { // 1. Let O be ? ToObject(this value). const o: JSReceiver = ToObject_Inline(context, receiver); // 2. Let sourceLen be ? ToLength(? Get(O, "length")). const len: Number = GetLengthProperty(o); // 3. Let depthNum be 1. let depthNum: Number = 1; // 4. If depth is not Undefined, then if (arguments[0] != Undefined) { // a. Set depthNum to ? ToInteger(depth). depthNum = ToInteger_Inline(arguments[0]); } // We will hit stack overflow before the stack depth reaches kSmiMax, so we // can truncate depthNum(Number) to Smi to improve performance. let depthSmi: Smi = 0; try { depthSmi = Cast<PositiveSmi>(depthNum) otherwise NotPositiveSmi; } label NotPositiveSmi { if (depthNum <= 0) { depthSmi = 0; } else { depthSmi = Convert<Smi>(Convert<intptr>(kSmiMax)); } } // 5. Let A be ? ArraySpeciesCreate(O, 0). const a: JSReceiver = ArraySpeciesCreate(context, o, 0); // 6. Perform ? FlattenIntoArray(A, O, sourceLen, 0, depthNum). FlattenIntoArrayWithoutMapFn(a, o, len, 0, depthSmi); // 7. Return A. return a; } // https://tc39.github.io/proposal-flatMap/#sec-Array.prototype.flatMap transitioning javascript builtin ArrayPrototypeFlatMap( js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny { // 1. Let O be ? ToObject(this value). const o: JSReceiver = ToObject_Inline(context, receiver); // 2. Let sourceLen be ? ToLength(? Get(O, "length")). const len: Number = GetLengthProperty(o); // 3. If IsCallable(mapperFunction) is false, throw a TypeError exception. let mapfn: Callable; try { mapfn = Cast<Callable>(arguments[0]) otherwise NonCallableError; } label NonCallableError deferred { ThrowCalledNonCallable(arguments[0]); } // 4. If thisArgs is present, let T be thisArgs; else let T be Undefined. const t: JSAny = arguments[1]; // 5. Let A be ? ArraySpeciesCreate(O, 0). const a: JSReceiver = ArraySpeciesCreate(context, o, 0); // 6. Perform ? FlattenIntoArray(A, O, sourceLen, 0, depthNum). FlattenIntoArrayWithMapFn(a, o, len, 0, 1, mapfn, t); // 7. Return A. return a; } }