diff options
author | Ujjwal Sharma <usharma1998@gmail.com> | 2019-03-15 18:35:06 +0530 |
---|---|---|
committer | Refael Ackermann <refack@gmail.com> | 2019-03-28 16:36:18 -0400 |
commit | f579e1194046c50f2e6bb54348d48c8e7d1a53cf (patch) | |
tree | 9125787c758358365f74f9fd9673c14f57e67870 /deps/v8/src/builtins/array-map.tq | |
parent | 2c73868b0471fbd4038f500d076df056cbf697fe (diff) | |
download | android-node-v8-f579e1194046c50f2e6bb54348d48c8e7d1a53cf.tar.gz android-node-v8-f579e1194046c50f2e6bb54348d48c8e7d1a53cf.tar.bz2 android-node-v8-f579e1194046c50f2e6bb54348d48c8e7d1a53cf.zip |
deps: update V8 to 7.4.288.13
PR-URL: https://github.com/nodejs/node/pull/26685
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Michaƫl Zasso <targos@protonmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Diffstat (limited to 'deps/v8/src/builtins/array-map.tq')
-rw-r--r-- | deps/v8/src/builtins/array-map.tq | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/deps/v8/src/builtins/array-map.tq b/deps/v8/src/builtins/array-map.tq new file mode 100644 index 0000000000..d3bba56220 --- /dev/null +++ b/deps/v8/src/builtins/array-map.tq @@ -0,0 +1,281 @@ +// Copyright 2018 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_map { + transitioning javascript builtin + ArrayMapLoopEagerDeoptContinuation(implicit context: Context)( + receiver: Object, callback: Object, thisArg: Object, array: Object, + initialK: Object, length: Object): Object { + // All continuation points in the optimized filter implementation are + // after the ToObject(O) call that ensures we are dealing with a + // JSReceiver. + // + // Also, this great mass of casts is necessary because the signature + // of Torque javascript builtins requires Object type for all parameters + // other than {context}. + const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable; + const callbackfn = Cast<Callable>(callback) otherwise unreachable; + const outputArray = Cast<JSReceiver>(array) otherwise unreachable; + const numberK = Cast<Number>(initialK) otherwise unreachable; + const numberLength = Cast<Number>(length) otherwise unreachable; + + return ArrayMapLoopContinuation( + jsreceiver, callbackfn, thisArg, outputArray, jsreceiver, numberK, + numberLength); + } + + transitioning javascript builtin + ArrayMapLoopLazyDeoptContinuation(implicit context: Context)( + receiver: Object, callback: Object, thisArg: Object, array: Object, + initialK: Object, length: Object, result: Object): Object { + // All continuation points in the optimized filter implementation are + // after the ToObject(O) call that ensures we are dealing with a + // JSReceiver. + const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable; + const callbackfn = Cast<Callable>(callback) otherwise unreachable; + const outputArray = Cast<JSReceiver>(array) otherwise unreachable; + let numberK = Cast<Number>(initialK) otherwise unreachable; + const numberLength = Cast<Number>(length) otherwise unreachable; + + // This custom lazy deopt point is right after the callback. map() needs + // to pick up at the next step, which is setting the callback result in + // the output array. After incrementing k, we can glide into the loop + // continuation builtin. + + // iii. Perform ? CreateDataPropertyOrThrow(A, Pk, mappedValue). + FastCreateDataProperty(outputArray, numberK, result); + + // 7d. Increase k by 1. + numberK = numberK + 1; + + return ArrayMapLoopContinuation( + jsreceiver, callbackfn, thisArg, outputArray, jsreceiver, numberK, + numberLength); + } + + transitioning builtin ArrayMapLoopContinuation(implicit context: Context)( + receiver: JSReceiver, callbackfn: Callable, thisArg: Object, + array: JSReceiver, o: JSReceiver, initialK: Number, + length: Number): Object { + // 6. Let k be 0. + // 7. Repeat, while k < len + for (let k: Number = initialK; k < length; k++) { + // 7a. Let Pk be ! ToString(k). + // k is guaranteed to be a positive integer, hence ToString is + // side-effect free and HasProperty/GetProperty do the conversion inline. + + // 7b. Let kPresent be ? HasProperty(O, Pk). + const kPresent: Boolean = HasProperty_Inline(o, k); + + // 7c. If kPresent is true, then: + if (kPresent == True) { + // i. Let kValue be ? Get(O, Pk). + const kValue: Object = GetProperty(o, k); + + // ii. Let mapped_value be ? Call(callbackfn, T, kValue, k, O). + const mappedValue: Object = + Call(context, callbackfn, thisArg, kValue, k, o); + + // iii. Perform ? CreateDataPropertyOrThrow(A, Pk, mapped_value). + FastCreateDataProperty(array, k, mappedValue); + } + + // 7d. Increase k by 1. (done by the loop). + } + + // 8. Return A. + return array; + } + + struct Vector { + ReportSkippedElement() { + this.skippedElements = true; + } + + CreateJSArray(implicit context: Context)(validLength: Smi): JSArray { + let length: Smi = this.fixedArray.length; + assert(validLength <= length); + let kind: ElementsKind = PACKED_SMI_ELEMENTS; + if (!this.onlySmis) { + if (this.onlyNumbers) { + kind = PACKED_DOUBLE_ELEMENTS; + } else { + kind = PACKED_ELEMENTS; + } + } + + if (this.skippedElements || validLength < length) { + // We also need to create a holey output array if we are + // bailing out of the fast path partway through the array. + // This is indicated by {validLength} < {length}. + // Who knows if the bailout condition will continue to fill in + // every element? + kind = FastHoleyElementsKind(kind); + } + + let map: Map = LoadJSArrayElementsMap(kind, LoadNativeContext(context)); + let a: JSArray; + + if (IsDoubleElementsKind(kind)) { + // We need to allocate and copy. + // First, initialize the elements field before allocation to prevent + // heap corruption. + const elements: FixedDoubleArray = AllocateFixedDoubleArrayWithHoles( + SmiUntag(length), kAllowLargeObjectAllocation); + a = NewJSArray(map, this.fixedArray); + for (let i: Smi = 0; i < validLength; i++) { + typeswitch (this.fixedArray.objects[i]) { + case (n: Number): { + elements.floats[i] = Float64SilenceNaN(Convert<float64>(n)); + } + case (h: HeapObject): { + assert(h == Hole); + } + } + } + a.elements = elements; + } else { + // Simply install the given fixedArray in {vector}. + a = NewJSArray(map, this.fixedArray); + } + + // Paranoia. the FixedArray now "belongs" to JSArray {a}. + this.fixedArray = kEmptyFixedArray; + return a; + } + + StoreResult(implicit context: Context)(index: Smi, result: Object) { + typeswitch (result) { + case (s: Smi): { + this.fixedArray.objects[index] = s; + } + case (s: HeapNumber): { + this.onlySmis = false; + this.fixedArray.objects[index] = s; + } + case (s: HeapObject): { + this.onlySmis = false; + this.onlyNumbers = false; + this.fixedArray.objects[index] = s; + } + } + } + + fixedArray: FixedArray; + onlySmis: bool; // initially true. + onlyNumbers: bool; // initially true. + skippedElements: bool; // initially false. + } + + macro NewVector(implicit context: Context)(length: Smi): Vector { + const fixedArray = length > 0 ? + AllocateFixedArrayWithHoles( + SmiUntag(length), kAllowLargeObjectAllocation) : + kEmptyFixedArray; + return Vector{fixedArray, true, true, false}; + } + + transitioning macro FastArrayMap(implicit context: Context)( + fastO: FastJSArray, len: Smi, callbackfn: Callable, + thisArg: Object): JSArray + labels Bailout(JSArray, Smi) { + let k: Smi = 0; + let fastOW = NewFastJSArrayWitness(fastO); + let vector = NewVector(len); + + // Build a fast loop over the smi array. + // 7. Repeat, while k < len. + try { + for (; k < len; k++) { + fastOW.Recheck() otherwise goto PrepareBailout(k); + + // Ensure that we haven't walked beyond a possibly updated length. + if (k >= fastOW.Get().length) goto PrepareBailout(k); + + try { + const value: Object = fastOW.LoadElementNoHole(k) + otherwise FoundHole; + const result: Object = + Call(context, callbackfn, thisArg, value, k, fastOW.Get()); + vector.StoreResult(k, result); + } + label FoundHole { + // Our output array must necessarily be holey because of holes in + // the input array. + vector.ReportSkippedElement(); + } + } + } + label PrepareBailout(k: Smi) deferred { + // Transform {vector} into a JSArray and bail out. + goto Bailout(vector.CreateJSArray(k), k); + } + + return vector.CreateJSArray(len); + } + + // Bails out if the slow path needs to be taken. + // It's useful to structure it this way, because the consequences of + // using the slow path on species creation are interesting to the caller. + macro FastMapSpeciesCreate(implicit context: Context)( + receiver: JSReceiver, length: Number): JSArray labels Bailout { + if (IsArraySpeciesProtectorCellInvalid()) goto Bailout; + const o = Cast<FastJSArray>(receiver) otherwise Bailout; + const smiLength = Cast<Smi>(length) otherwise Bailout; + const newMap: Map = + LoadJSArrayElementsMap(PACKED_SMI_ELEMENTS, LoadNativeContext(context)); + return AllocateJSArray(PACKED_SMI_ELEMENTS, newMap, smiLength, smiLength); + } + + // https://tc39.github.io/ecma262/#sec-array.prototype.map + transitioning javascript builtin + ArrayMap(implicit context: Context)(receiver: Object, ...arguments): Object { + try { + if (IsNullOrUndefined(receiver)) goto NullOrUndefinedError; + + // 1. Let O be ? ToObject(this value). + const o: JSReceiver = ToObject_Inline(context, receiver); + + // 2. Let len be ? ToLength(? Get(O, "length")). + const len: Number = GetLengthProperty(o); + + // 3. If IsCallable(callbackfn) is false, throw a TypeError exception. + if (arguments.length == 0) goto TypeError; + + const callbackfn = Cast<Callable>(arguments[0]) otherwise TypeError; + + // 4. If thisArg is present, let T be thisArg; else let T be undefined. + const thisArg: Object = arguments.length > 1 ? arguments[1] : Undefined; + + let array: JSReceiver; + let k: Number = 0; + try { + // 5. Let A be ? ArraySpeciesCreate(O, len). + if (IsArraySpeciesProtectorCellInvalid()) goto SlowSpeciesCreate; + const o: FastJSArray = Cast<FastJSArray>(receiver) + otherwise SlowSpeciesCreate; + const smiLength: Smi = Cast<Smi>(len) + otherwise SlowSpeciesCreate; + + return FastArrayMap(o, smiLength, callbackfn, thisArg) + otherwise Bailout; + } + label SlowSpeciesCreate { + array = ArraySpeciesCreate(context, receiver, len); + } + label Bailout(output: JSArray, kValue: Smi) deferred { + array = output; + k = kValue; + } + + return ArrayMapLoopContinuation(o, callbackfn, thisArg, array, o, k, len); + } + label TypeError deferred { + ThrowTypeError(kCalledNonCallable, arguments[0]); + } + label NullOrUndefinedError deferred { + ThrowTypeError(kCalledOnNullOrUndefined, 'Array.prototype.map'); + } + } +} |