[Torque] Implement Array.prototype.every and some in Torque
Just a straightforward port. bug:v8:7672 Change-Id: Ie2511cda23d7b61775e3619d61dde43c8ae48c7f Reviewed-on: https://chromium-review.googlesource.com/c/1425916 Commit-Queue: Michael Stanton <mvstanton@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/master@{#59638}
This commit is contained in:
parent
9542fd8fa0
commit
9bf0c69674
2
BUILD.gn
2
BUILD.gn
@ -900,6 +900,7 @@ torque_files = [
|
|||||||
"src/builtins/arguments.tq",
|
"src/builtins/arguments.tq",
|
||||||
"src/builtins/array.tq",
|
"src/builtins/array.tq",
|
||||||
"src/builtins/array-copywithin.tq",
|
"src/builtins/array-copywithin.tq",
|
||||||
|
"src/builtins/array-every.tq",
|
||||||
"src/builtins/array-filter.tq",
|
"src/builtins/array-filter.tq",
|
||||||
"src/builtins/array-foreach.tq",
|
"src/builtins/array-foreach.tq",
|
||||||
"src/builtins/array-join.tq",
|
"src/builtins/array-join.tq",
|
||||||
@ -908,6 +909,7 @@ torque_files = [
|
|||||||
"src/builtins/array-map.tq",
|
"src/builtins/array-map.tq",
|
||||||
"src/builtins/array-reverse.tq",
|
"src/builtins/array-reverse.tq",
|
||||||
"src/builtins/array-slice.tq",
|
"src/builtins/array-slice.tq",
|
||||||
|
"src/builtins/array-some.tq",
|
||||||
"src/builtins/array-splice.tq",
|
"src/builtins/array-splice.tq",
|
||||||
"src/builtins/array-unshift.tq",
|
"src/builtins/array-unshift.tq",
|
||||||
"src/builtins/collections.tq",
|
"src/builtins/collections.tq",
|
||||||
|
172
src/builtins/array-every.tq
Normal file
172
src/builtins/array-every.tq
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
// 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 {
|
||||||
|
transitioning javascript builtin
|
||||||
|
ArrayEveryLoopEagerDeoptContinuation(implicit context: Context)(
|
||||||
|
receiver: Object, callback: Object, thisArg: Object, initialK: Object,
|
||||||
|
length: Object): Object {
|
||||||
|
// All continuation points in the optimized every 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 numberK = Cast<Number>(initialK) otherwise unreachable;
|
||||||
|
const numberLength = Cast<Number>(length) otherwise unreachable;
|
||||||
|
|
||||||
|
return ArrayEveryLoopContinuation(
|
||||||
|
jsreceiver, callbackfn, thisArg, Undefined, jsreceiver, numberK,
|
||||||
|
numberLength, Undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
transitioning javascript builtin
|
||||||
|
ArrayEveryLoopLazyDeoptContinuation(implicit context: Context)(
|
||||||
|
receiver: Object, callback: Object, thisArg: Object, initialK: Object,
|
||||||
|
length: Object, result: Object): Object {
|
||||||
|
// All continuation points in the optimized every 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;
|
||||||
|
let numberK = Cast<Number>(initialK) otherwise unreachable;
|
||||||
|
const numberLength = Cast<Number>(length) otherwise unreachable;
|
||||||
|
|
||||||
|
// This custom lazy deopt point is right after the callback. every() needs
|
||||||
|
// to pick up at the next step, which is either continuing to the next
|
||||||
|
// array element or returning false if {result} is false.
|
||||||
|
if (!ToBoolean(result)) {
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
numberK = numberK + 1;
|
||||||
|
|
||||||
|
return ArrayEveryLoopContinuation(
|
||||||
|
jsreceiver, callbackfn, thisArg, Undefined, jsreceiver, numberK,
|
||||||
|
numberLength, Undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
transitioning builtin ArrayEveryLoopContinuation(implicit context: Context)(
|
||||||
|
receiver: JSReceiver, callbackfn: Callable, thisArg: Object,
|
||||||
|
array: Object, o: JSReceiver, initialK: Number, length: Number,
|
||||||
|
initialTo: Object): Object {
|
||||||
|
// 5. Let k be 0.
|
||||||
|
// 6. Repeat, while k < len
|
||||||
|
for (let k: Number = initialK; k < length; k++) {
|
||||||
|
// 6a. 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.
|
||||||
|
|
||||||
|
// 6b. Let kPresent be ? HasProperty(O, Pk).
|
||||||
|
const kPresent: Boolean = HasProperty_Inline(o, k);
|
||||||
|
|
||||||
|
// 6c. If kPresent is true, then
|
||||||
|
if (kPresent == True) {
|
||||||
|
// 6c. i. Let kValue be ? Get(O, Pk).
|
||||||
|
const kValue: Object = GetProperty(o, k);
|
||||||
|
|
||||||
|
// 6c. ii. Perform ? Call(callbackfn, T, <kValue, k, O>).
|
||||||
|
const result: Object = Call(context, callbackfn, thisArg, kValue, k, o);
|
||||||
|
|
||||||
|
// iii. If selected is true, then...
|
||||||
|
if (!ToBoolean(result)) {
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6d. Increase k by 1. (done by the loop).
|
||||||
|
}
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
transitioning macro
|
||||||
|
EveryVisitAllElements<FixedArrayType: type>(implicit context: Context)(
|
||||||
|
o: FastJSArray, len: Smi, callbackfn: Callable,
|
||||||
|
thisArg: Object): Boolean labels Bailout(Smi) {
|
||||||
|
let k: Smi = 0;
|
||||||
|
let fastO = FastJSArrayWitness{o};
|
||||||
|
|
||||||
|
// Build a fast loop over the smi array.
|
||||||
|
for (; k < len; k++) {
|
||||||
|
// Ensure that we haven't walked beyond a possibly updated length.
|
||||||
|
if (k >= fastO.Get().length) goto Bailout(k);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const value: Object = LoadElementNoHole<FixedArrayType>(fastO.Get(), k)
|
||||||
|
otherwise FoundHole;
|
||||||
|
const result: Object =
|
||||||
|
Call(context, callbackfn, thisArg, value, k, fastO.Get());
|
||||||
|
if (!ToBoolean(result)) {
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label FoundHole {}
|
||||||
|
fastO.Recheck() otherwise goto Bailout(k + 1);
|
||||||
|
}
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
transitioning macro FastArrayEvery(implicit context: Context)(
|
||||||
|
o: JSReceiver, len: Number, callbackfn: Callable, thisArg: Object): Object
|
||||||
|
labels Bailout(Smi) {
|
||||||
|
let k: Smi = 0;
|
||||||
|
const smiLen = Cast<Smi>(len) otherwise goto Bailout(k);
|
||||||
|
let fastO = Cast<FastJSArray>(o) otherwise goto Bailout(k);
|
||||||
|
const elementsKind: ElementsKind = fastO.map.elements_kind;
|
||||||
|
if (IsElementsKindLessThanOrEqual(elementsKind, HOLEY_ELEMENTS)) {
|
||||||
|
return EveryVisitAllElements<FixedArray>(
|
||||||
|
fastO, smiLen, callbackfn, thisArg) otherwise Bailout;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(IsDoubleElementsKind(elementsKind));
|
||||||
|
return EveryVisitAllElements<FixedDoubleArray>(
|
||||||
|
fastO, smiLen, callbackfn, thisArg) otherwise Bailout;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://tc39.github.io/ecma262/#sec-array.prototype.every
|
||||||
|
transitioning javascript builtin
|
||||||
|
ArrayEvery(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;
|
||||||
|
|
||||||
|
// Special cases.
|
||||||
|
try {
|
||||||
|
return FastArrayEvery(o, len, callbackfn, thisArg)
|
||||||
|
otherwise Bailout;
|
||||||
|
}
|
||||||
|
label Bailout(kValue: Smi) deferred {
|
||||||
|
return ArrayEveryLoopContinuation(
|
||||||
|
o, callbackfn, thisArg, Undefined, o, kValue, len, Undefined);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label TypeError deferred {
|
||||||
|
ThrowTypeError(context, kCalledNonCallable, arguments[0]);
|
||||||
|
}
|
||||||
|
label NullOrUndefinedError deferred {
|
||||||
|
ThrowTypeError(
|
||||||
|
context, kCalledOnNullOrUndefined, 'Array.prototype.every');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,14 +14,12 @@ namespace array_filter {
|
|||||||
// Also, this great mass of casts is necessary because the signature
|
// Also, this great mass of casts is necessary because the signature
|
||||||
// of Torque javascript builtins requires Object type for all parameters
|
// of Torque javascript builtins requires Object type for all parameters
|
||||||
// other than {context}.
|
// other than {context}.
|
||||||
const jsreceiver: JSReceiver =
|
const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable;
|
||||||
Cast<JSReceiver>(receiver) otherwise unreachable;
|
const callbackfn = Cast<Callable>(callback) otherwise unreachable;
|
||||||
const callbackfn: Callable = Cast<Callable>(callback) otherwise unreachable;
|
const outputArray = Cast<JSReceiver>(array) otherwise unreachable;
|
||||||
const outputArray: JSReceiver =
|
const numberK = Cast<Number>(initialK) otherwise unreachable;
|
||||||
Cast<JSReceiver>(array) otherwise unreachable;
|
const numberTo = Cast<Number>(initialTo) otherwise unreachable;
|
||||||
const numberK: Number = Cast<Number>(initialK) otherwise unreachable;
|
const numberLength = Cast<Number>(length) otherwise unreachable;
|
||||||
const numberTo: Number = Cast<Number>(initialTo) otherwise unreachable;
|
|
||||||
const numberLength: Number = Cast<Number>(length) otherwise unreachable;
|
|
||||||
|
|
||||||
return ArrayFilterLoopContinuation(
|
return ArrayFilterLoopContinuation(
|
||||||
jsreceiver, callbackfn, thisArg, outputArray, jsreceiver, numberK,
|
jsreceiver, callbackfn, thisArg, outputArray, jsreceiver, numberK,
|
||||||
@ -36,14 +34,12 @@ namespace array_filter {
|
|||||||
// All continuation points in the optimized filter implementation are
|
// All continuation points in the optimized filter implementation are
|
||||||
// after the ToObject(O) call that ensures we are dealing with a
|
// after the ToObject(O) call that ensures we are dealing with a
|
||||||
// JSReceiver.
|
// JSReceiver.
|
||||||
const jsreceiver: JSReceiver =
|
const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable;
|
||||||
Cast<JSReceiver>(receiver) otherwise unreachable;
|
const callbackfn = Cast<Callable>(callback) otherwise unreachable;
|
||||||
const callbackfn: Callable = Cast<Callable>(callback) otherwise unreachable;
|
const outputArray = Cast<JSReceiver>(array) otherwise unreachable;
|
||||||
const outputArray: JSReceiver =
|
let numberK = Cast<Number>(initialK) otherwise unreachable;
|
||||||
Cast<JSReceiver>(array) otherwise unreachable;
|
let numberTo = Cast<Number>(initialTo) otherwise unreachable;
|
||||||
let numberK: Number = Cast<Number>(initialK) otherwise unreachable;
|
const numberLength = Cast<Number>(length) otherwise unreachable;
|
||||||
let numberTo: Number = Cast<Number>(initialTo) otherwise unreachable;
|
|
||||||
const numberLength: Number = Cast<Number>(length) otherwise unreachable;
|
|
||||||
|
|
||||||
// This custom lazy deopt point is right after the callback. filter() needs
|
// This custom lazy deopt point is right after the callback. filter() needs
|
||||||
// to pick up at the next step, which is setting the callback result in
|
// to pick up at the next step, which is setting the callback result in
|
||||||
@ -142,10 +138,9 @@ namespace array_filter {
|
|||||||
labels Bailout(Smi, Smi) {
|
labels Bailout(Smi, Smi) {
|
||||||
let k: Smi = 0;
|
let k: Smi = 0;
|
||||||
let to: Smi = 0;
|
let to: Smi = 0;
|
||||||
const smiLen: Smi = Cast<Smi>(len) otherwise goto Bailout(k, to);
|
const smiLen = Cast<Smi>(len) otherwise goto Bailout(k, to);
|
||||||
const fastArray: FastJSArray =
|
const fastArray = Cast<FastJSArray>(array) otherwise goto Bailout(k, to);
|
||||||
Cast<FastJSArray>(array) otherwise goto Bailout(k, to);
|
let fastO = Cast<FastJSArray>(o) otherwise goto Bailout(k, to);
|
||||||
let fastO: FastJSArray = Cast<FastJSArray>(o) otherwise goto Bailout(k, to);
|
|
||||||
EnsureArrayPushable(fastArray.map) otherwise goto Bailout(k, to);
|
EnsureArrayPushable(fastArray.map) otherwise goto Bailout(k, to);
|
||||||
const elementsKind: ElementsKind = fastO.map.elements_kind;
|
const elementsKind: ElementsKind = fastO.map.elements_kind;
|
||||||
if (IsElementsKindLessThanOrEqual(elementsKind, HOLEY_SMI_ELEMENTS)) {
|
if (IsElementsKindLessThanOrEqual(elementsKind, HOLEY_SMI_ELEMENTS)) {
|
||||||
@ -172,7 +167,7 @@ namespace array_filter {
|
|||||||
receiver: JSReceiver): JSReceiver labels Slow {
|
receiver: JSReceiver): JSReceiver labels Slow {
|
||||||
const len: Smi = 0;
|
const len: Smi = 0;
|
||||||
if (IsArraySpeciesProtectorCellInvalid()) goto Slow;
|
if (IsArraySpeciesProtectorCellInvalid()) goto Slow;
|
||||||
const o: FastJSArray = Cast<FastJSArray>(receiver) otherwise Slow;
|
const o = Cast<FastJSArray>(receiver) otherwise Slow;
|
||||||
const newMap: Map =
|
const newMap: Map =
|
||||||
LoadJSArrayElementsMap(o.map.elements_kind, LoadNativeContext(context));
|
LoadJSArrayElementsMap(o.map.elements_kind, LoadNativeContext(context));
|
||||||
return AllocateJSArray(PACKED_SMI_ELEMENTS, newMap, len, len);
|
return AllocateJSArray(PACKED_SMI_ELEMENTS, newMap, len, len);
|
||||||
@ -197,8 +192,7 @@ namespace array_filter {
|
|||||||
if (arguments.length == 0) {
|
if (arguments.length == 0) {
|
||||||
goto TypeError;
|
goto TypeError;
|
||||||
}
|
}
|
||||||
const callbackfn: Callable =
|
const callbackfn = Cast<Callable>(arguments[0]) otherwise TypeError;
|
||||||
Cast<Callable>(arguments[0]) otherwise TypeError;
|
|
||||||
|
|
||||||
// 4. If thisArg is present, let T be thisArg; else let T be undefined.
|
// 4. If thisArg is present, let T be thisArg; else let T be undefined.
|
||||||
const thisArg: Object = arguments.length > 1 ? arguments[1] : Undefined;
|
const thisArg: Object = arguments.length > 1 ? arguments[1] : Undefined;
|
||||||
|
@ -10,11 +10,10 @@ namespace array_foreach {
|
|||||||
// All continuation points in the optimized forEach implemntation are
|
// All continuation points in the optimized forEach implemntation are
|
||||||
// after the ToObject(O) call that ensures we are dealing with a
|
// after the ToObject(O) call that ensures we are dealing with a
|
||||||
// JSReceiver.
|
// JSReceiver.
|
||||||
const jsreceiver: JSReceiver =
|
const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable;
|
||||||
Cast<JSReceiver>(receiver) otherwise unreachable;
|
const callbackfn = Cast<Callable>(callback) otherwise unreachable;
|
||||||
const callbackfn: Callable = Cast<Callable>(callback) otherwise unreachable;
|
const numberK = Cast<Number>(initialK) otherwise unreachable;
|
||||||
const numberK: Number = Cast<Number>(initialK) otherwise unreachable;
|
const numberLength = Cast<Number>(length) otherwise unreachable;
|
||||||
const numberLength: Number = Cast<Number>(length) otherwise unreachable;
|
|
||||||
|
|
||||||
return ArrayForEachLoopContinuation(
|
return ArrayForEachLoopContinuation(
|
||||||
jsreceiver, callbackfn, thisArg, Undefined, jsreceiver, numberK,
|
jsreceiver, callbackfn, thisArg, Undefined, jsreceiver, numberK,
|
||||||
@ -28,11 +27,10 @@ namespace array_foreach {
|
|||||||
// All continuation points in the optimized forEach implemntation are
|
// All continuation points in the optimized forEach implemntation are
|
||||||
// after the ToObject(O) call that ensures we are dealing with a
|
// after the ToObject(O) call that ensures we are dealing with a
|
||||||
// JSReceiver.
|
// JSReceiver.
|
||||||
const jsreceiver: JSReceiver =
|
const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable;
|
||||||
Cast<JSReceiver>(receiver) otherwise unreachable;
|
const callbackfn = Cast<Callable>(callback) otherwise unreachable;
|
||||||
const callbackfn: Callable = Cast<Callable>(callback) otherwise unreachable;
|
const numberK = Cast<Number>(initialK) otherwise unreachable;
|
||||||
const numberK: Number = Cast<Number>(initialK) otherwise unreachable;
|
const numberLength = Cast<Number>(length) otherwise unreachable;
|
||||||
const numberLength: Number = Cast<Number>(length) otherwise unreachable;
|
|
||||||
|
|
||||||
return ArrayForEachLoopContinuation(
|
return ArrayForEachLoopContinuation(
|
||||||
jsreceiver, callbackfn, thisArg, Undefined, jsreceiver, numberK,
|
jsreceiver, callbackfn, thisArg, Undefined, jsreceiver, numberK,
|
||||||
@ -92,8 +90,8 @@ namespace array_foreach {
|
|||||||
o: JSReceiver, len: Number, callbackfn: Callable, thisArg: Object): Object
|
o: JSReceiver, len: Number, callbackfn: Callable, thisArg: Object): Object
|
||||||
labels Bailout(Smi) {
|
labels Bailout(Smi) {
|
||||||
let k: Smi = 0;
|
let k: Smi = 0;
|
||||||
const smiLen: Smi = Cast<Smi>(len) otherwise goto Bailout(k);
|
const smiLen = Cast<Smi>(len) otherwise goto Bailout(k);
|
||||||
let fastO: FastJSArray = Cast<FastJSArray>(o) otherwise goto Bailout(k);
|
let fastO = Cast<FastJSArray>(o) otherwise goto Bailout(k);
|
||||||
const elementsKind: ElementsKind = fastO.map.elements_kind;
|
const elementsKind: ElementsKind = fastO.map.elements_kind;
|
||||||
if (IsElementsKindGreaterThan(elementsKind, HOLEY_ELEMENTS)) {
|
if (IsElementsKindGreaterThan(elementsKind, HOLEY_ELEMENTS)) {
|
||||||
VisitAllElements<FixedDoubleArray>(fastO, smiLen, callbackfn, thisArg)
|
VisitAllElements<FixedDoubleArray>(fastO, smiLen, callbackfn, thisArg)
|
||||||
@ -123,8 +121,7 @@ namespace array_foreach {
|
|||||||
if (arguments.length == 0) {
|
if (arguments.length == 0) {
|
||||||
goto TypeError;
|
goto TypeError;
|
||||||
}
|
}
|
||||||
const callbackfn: Callable =
|
const callbackfn = Cast<Callable>(arguments[0]) otherwise TypeError;
|
||||||
Cast<Callable>(arguments[0]) otherwise TypeError;
|
|
||||||
|
|
||||||
// 4. If thisArg is present, let T be thisArg; else let T be undefined.
|
// 4. If thisArg is present, let T be thisArg; else let T be undefined.
|
||||||
const thisArg: Object = arguments.length > 1 ? arguments[1] : Undefined;
|
const thisArg: Object = arguments.length > 1 ? arguments[1] : Undefined;
|
||||||
|
@ -14,13 +14,11 @@ namespace array_map {
|
|||||||
// Also, this great mass of casts is necessary because the signature
|
// Also, this great mass of casts is necessary because the signature
|
||||||
// of Torque javascript builtins requires Object type for all parameters
|
// of Torque javascript builtins requires Object type for all parameters
|
||||||
// other than {context}.
|
// other than {context}.
|
||||||
const jsreceiver: JSReceiver =
|
const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable;
|
||||||
Cast<JSReceiver>(receiver) otherwise unreachable;
|
const callbackfn = Cast<Callable>(callback) otherwise unreachable;
|
||||||
const callbackfn: Callable = Cast<Callable>(callback) otherwise unreachable;
|
const outputArray = Cast<JSReceiver>(array) otherwise unreachable;
|
||||||
const outputArray: JSReceiver =
|
const numberK = Cast<Number>(initialK) otherwise unreachable;
|
||||||
Cast<JSReceiver>(array) otherwise unreachable;
|
const numberLength = Cast<Number>(length) otherwise unreachable;
|
||||||
const numberK: Number = Cast<Number>(initialK) otherwise unreachable;
|
|
||||||
const numberLength: Number = Cast<Number>(length) otherwise unreachable;
|
|
||||||
|
|
||||||
return ArrayMapLoopContinuation(
|
return ArrayMapLoopContinuation(
|
||||||
jsreceiver, callbackfn, thisArg, outputArray, jsreceiver, numberK,
|
jsreceiver, callbackfn, thisArg, outputArray, jsreceiver, numberK,
|
||||||
@ -34,13 +32,11 @@ namespace array_map {
|
|||||||
// All continuation points in the optimized filter implementation are
|
// All continuation points in the optimized filter implementation are
|
||||||
// after the ToObject(O) call that ensures we are dealing with a
|
// after the ToObject(O) call that ensures we are dealing with a
|
||||||
// JSReceiver.
|
// JSReceiver.
|
||||||
const jsreceiver: JSReceiver =
|
const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable;
|
||||||
Cast<JSReceiver>(receiver) otherwise unreachable;
|
const callbackfn = Cast<Callable>(callback) otherwise unreachable;
|
||||||
const callbackfn: Callable = Cast<Callable>(callback) otherwise unreachable;
|
const outputArray = Cast<JSReceiver>(array) otherwise unreachable;
|
||||||
const outputArray: JSReceiver =
|
let numberK = Cast<Number>(initialK) otherwise unreachable;
|
||||||
Cast<JSReceiver>(array) otherwise unreachable;
|
const numberLength = Cast<Number>(length) otherwise unreachable;
|
||||||
let numberK: Number = Cast<Number>(initialK) otherwise unreachable;
|
|
||||||
const numberLength: Number = Cast<Number>(length) otherwise unreachable;
|
|
||||||
|
|
||||||
// This custom lazy deopt point is right after the callback. map() needs
|
// 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
|
// to pick up at the next step, which is setting the callback result in
|
||||||
@ -220,7 +216,7 @@ namespace array_map {
|
|||||||
o: JSReceiver, len: Smi, callbackfn: Callable, thisArg: Object): JSArray
|
o: JSReceiver, len: Smi, callbackfn: Callable, thisArg: Object): JSArray
|
||||||
labels Bailout(JSArray, Smi) {
|
labels Bailout(JSArray, Smi) {
|
||||||
let k: Smi = 0;
|
let k: Smi = 0;
|
||||||
let fastO: FastJSArray = Cast<FastJSArray>(o) otherwise unreachable;
|
let fastO = Cast<FastJSArray>(o) otherwise unreachable;
|
||||||
let vector = Vector{len};
|
let vector = Vector{len};
|
||||||
const elementsKind: ElementsKind = fastO.map.elements_kind;
|
const elementsKind: ElementsKind = fastO.map.elements_kind;
|
||||||
try {
|
try {
|
||||||
@ -254,8 +250,8 @@ namespace array_map {
|
|||||||
macro FastMapSpeciesCreate(implicit context: Context)(
|
macro FastMapSpeciesCreate(implicit context: Context)(
|
||||||
receiver: JSReceiver, length: Number): JSArray labels Bailout {
|
receiver: JSReceiver, length: Number): JSArray labels Bailout {
|
||||||
if (IsArraySpeciesProtectorCellInvalid()) goto Bailout;
|
if (IsArraySpeciesProtectorCellInvalid()) goto Bailout;
|
||||||
const o: FastJSArray = Cast<FastJSArray>(receiver) otherwise Bailout;
|
const o = Cast<FastJSArray>(receiver) otherwise Bailout;
|
||||||
const smiLength: Smi = Cast<Smi>(length) otherwise Bailout;
|
const smiLength = Cast<Smi>(length) otherwise Bailout;
|
||||||
const newMap: Map =
|
const newMap: Map =
|
||||||
LoadJSArrayElementsMap(PACKED_SMI_ELEMENTS, LoadNativeContext(context));
|
LoadJSArrayElementsMap(PACKED_SMI_ELEMENTS, LoadNativeContext(context));
|
||||||
return AllocateJSArray(PACKED_SMI_ELEMENTS, newMap, smiLength, smiLength);
|
return AllocateJSArray(PACKED_SMI_ELEMENTS, newMap, smiLength, smiLength);
|
||||||
@ -276,8 +272,7 @@ namespace array_map {
|
|||||||
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
||||||
if (arguments.length == 0) goto TypeError;
|
if (arguments.length == 0) goto TypeError;
|
||||||
|
|
||||||
const callbackfn: Callable =
|
const callbackfn = Cast<Callable>(arguments[0]) otherwise TypeError;
|
||||||
Cast<Callable>(arguments[0]) otherwise TypeError;
|
|
||||||
|
|
||||||
// 4. If thisArg is present, let T be thisArg; else let T be undefined.
|
// 4. If thisArg is present, let T be thisArg; else let T be undefined.
|
||||||
const thisArg: Object = arguments.length > 1 ? arguments[1] : Undefined;
|
const thisArg: Object = arguments.length > 1 ? arguments[1] : Undefined;
|
||||||
|
171
src/builtins/array-some.tq
Normal file
171
src/builtins/array-some.tq
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
// 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 {
|
||||||
|
transitioning javascript builtin
|
||||||
|
ArraySomeLoopEagerDeoptContinuation(implicit context: Context)(
|
||||||
|
receiver: Object, callback: Object, thisArg: Object, initialK: Object,
|
||||||
|
length: Object): Object {
|
||||||
|
// All continuation points in the optimized some 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 numberK = Cast<Number>(initialK) otherwise unreachable;
|
||||||
|
const numberLength = Cast<Number>(length) otherwise unreachable;
|
||||||
|
|
||||||
|
return ArraySomeLoopContinuation(
|
||||||
|
jsreceiver, callbackfn, thisArg, Undefined, jsreceiver, numberK,
|
||||||
|
numberLength, Undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
transitioning javascript builtin
|
||||||
|
ArraySomeLoopLazyDeoptContinuation(implicit context: Context)(
|
||||||
|
receiver: Object, callback: Object, thisArg: Object, initialK: Object,
|
||||||
|
length: Object, result: Object): Object {
|
||||||
|
// All continuation points in the optimized some 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;
|
||||||
|
let numberK = Cast<Number>(initialK) otherwise unreachable;
|
||||||
|
const numberLength = Cast<Number>(length) otherwise unreachable;
|
||||||
|
|
||||||
|
// This custom lazy deopt point is right after the callback. some() needs
|
||||||
|
// to pick up at the next step: if the result is true, then return,
|
||||||
|
// otherwise, keep going through the array starting from k + 1.
|
||||||
|
if (ToBoolean(result)) {
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
numberK = numberK + 1;
|
||||||
|
|
||||||
|
return ArraySomeLoopContinuation(
|
||||||
|
jsreceiver, callbackfn, thisArg, Undefined, jsreceiver, numberK,
|
||||||
|
numberLength, Undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
transitioning builtin ArraySomeLoopContinuation(implicit context: Context)(
|
||||||
|
receiver: JSReceiver, callbackfn: Callable, thisArg: Object,
|
||||||
|
array: Object, o: JSReceiver, initialK: Number, length: Number,
|
||||||
|
initialTo: Object): Object {
|
||||||
|
// 5. Let k be 0.
|
||||||
|
// 6. Repeat, while k < len
|
||||||
|
for (let k: Number = initialK; k < length; k++) {
|
||||||
|
// 6a. 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.
|
||||||
|
|
||||||
|
// 6b. Let kPresent be ? HasProperty(O, Pk).
|
||||||
|
const kPresent: Boolean = HasProperty_Inline(o, k);
|
||||||
|
|
||||||
|
// 6c. If kPresent is true, then
|
||||||
|
if (kPresent == True) {
|
||||||
|
// 6c. i. Let kValue be ? Get(O, Pk).
|
||||||
|
const kValue: Object = GetProperty(o, k);
|
||||||
|
|
||||||
|
// 6c. ii. Perform ? Call(callbackfn, T, <kValue, k, O>).
|
||||||
|
const result: Object = Call(context, callbackfn, thisArg, kValue, k, o);
|
||||||
|
|
||||||
|
// iii. If selected is true, then...
|
||||||
|
if (ToBoolean(result)) {
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6d. Increase k by 1. (done by the loop).
|
||||||
|
}
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
transitioning macro
|
||||||
|
SomeVisitAllElements<FixedArrayType: type>(implicit context: Context)(
|
||||||
|
o: FastJSArray, len: Smi, callbackfn: Callable, thisArg: Object): Boolean
|
||||||
|
labels Bailout(Smi) {
|
||||||
|
let k: Smi = 0;
|
||||||
|
let fastO = FastJSArrayWitness{o};
|
||||||
|
|
||||||
|
// Build a fast loop over the smi array.
|
||||||
|
for (; k < len; k++) {
|
||||||
|
// Ensure that we haven't walked beyond a possibly updated length.
|
||||||
|
if (k >= fastO.Get().length) goto Bailout(k);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const value: Object = LoadElementNoHole<FixedArrayType>(fastO.Get(), k)
|
||||||
|
otherwise FoundHole;
|
||||||
|
const result: Object =
|
||||||
|
Call(context, callbackfn, thisArg, value, k, fastO.Get());
|
||||||
|
if (ToBoolean(result)) {
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label FoundHole {}
|
||||||
|
fastO.Recheck() otherwise goto Bailout(k + 1);
|
||||||
|
}
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
transitioning macro FastArraySome(implicit context: Context)(
|
||||||
|
o: JSReceiver, len: Number, callbackfn: Callable, thisArg: Object): Object
|
||||||
|
labels Bailout(Smi) {
|
||||||
|
let k: Smi = 0;
|
||||||
|
const smiLen = Cast<Smi>(len) otherwise goto Bailout(k);
|
||||||
|
let fastO = Cast<FastJSArray>(o) otherwise goto Bailout(k);
|
||||||
|
const elementsKind: ElementsKind = fastO.map.elements_kind;
|
||||||
|
if (IsElementsKindLessThanOrEqual(elementsKind, HOLEY_ELEMENTS)) {
|
||||||
|
return SomeVisitAllElements<FixedArray>(
|
||||||
|
fastO, smiLen, callbackfn, thisArg)
|
||||||
|
otherwise Bailout;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(IsDoubleElementsKind(elementsKind));
|
||||||
|
return SomeVisitAllElements<FixedDoubleArray>(
|
||||||
|
fastO, smiLen, callbackfn, thisArg) otherwise Bailout;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://tc39.github.io/ecma262/#sec-array.prototype.some
|
||||||
|
transitioning javascript builtin
|
||||||
|
ArraySome(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;
|
||||||
|
|
||||||
|
// Special cases.
|
||||||
|
try {
|
||||||
|
return FastArraySome(o, len, callbackfn, thisArg)
|
||||||
|
otherwise Bailout;
|
||||||
|
}
|
||||||
|
label Bailout(kValue: Smi) deferred {
|
||||||
|
return ArraySomeLoopContinuation(
|
||||||
|
o, callbackfn, thisArg, Undefined, o, kValue, len, Undefined);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label TypeError deferred {
|
||||||
|
ThrowTypeError(context, kCalledNonCallable, arguments[0]);
|
||||||
|
}
|
||||||
|
label NullOrUndefinedError deferred {
|
||||||
|
ThrowTypeError(context, kCalledOnNullOrUndefined, 'Array.prototype.some');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1609,87 +1609,6 @@ TF_BUILTIN(TypedArrayPrototypeForEach, ArrayBuiltinsAssembler) {
|
|||||||
&ArrayBuiltinsAssembler::NullPostLoopAction);
|
&ArrayBuiltinsAssembler::NullPostLoopAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
TF_BUILTIN(ArraySomeLoopLazyDeoptContinuation, ArrayBuiltinsAssembler) {
|
|
||||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
|
||||||
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
|
|
||||||
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
|
|
||||||
Node* this_arg = Parameter(Descriptor::kThisArg);
|
|
||||||
Node* initial_k = Parameter(Descriptor::kInitialK);
|
|
||||||
TNode<Number> len = CAST(Parameter(Descriptor::kLength));
|
|
||||||
Node* result = Parameter(Descriptor::kResult);
|
|
||||||
|
|
||||||
// This custom lazy deopt point is right after the callback. every() needs
|
|
||||||
// to pick up at the next step, which is either continuing to the next
|
|
||||||
// array element or returning false if {result} is false.
|
|
||||||
Label true_continue(this), false_continue(this);
|
|
||||||
|
|
||||||
// iii. If selected is true, then...
|
|
||||||
BranchIfToBooleanIsTrue(result, &true_continue, &false_continue);
|
|
||||||
BIND(&true_continue);
|
|
||||||
{ Return(TrueConstant()); }
|
|
||||||
BIND(&false_continue);
|
|
||||||
{
|
|
||||||
// Increment k.
|
|
||||||
initial_k = NumberInc(initial_k);
|
|
||||||
|
|
||||||
Return(CallBuiltin(Builtins::kArraySomeLoopContinuation, context, receiver,
|
|
||||||
callbackfn, this_arg, FalseConstant(), receiver,
|
|
||||||
initial_k, len, UndefinedConstant()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TF_BUILTIN(ArraySomeLoopEagerDeoptContinuation, ArrayBuiltinsAssembler) {
|
|
||||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
|
||||||
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
|
|
||||||
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
|
|
||||||
Node* this_arg = Parameter(Descriptor::kThisArg);
|
|
||||||
Node* initial_k = Parameter(Descriptor::kInitialK);
|
|
||||||
TNode<Number> len = CAST(Parameter(Descriptor::kLength));
|
|
||||||
|
|
||||||
Return(CallBuiltin(Builtins::kArraySomeLoopContinuation, context, receiver,
|
|
||||||
callbackfn, this_arg, FalseConstant(), receiver, initial_k,
|
|
||||||
len, UndefinedConstant()));
|
|
||||||
}
|
|
||||||
|
|
||||||
TF_BUILTIN(ArraySomeLoopContinuation, ArrayBuiltinsAssembler) {
|
|
||||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
|
||||||
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
|
|
||||||
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
|
|
||||||
Node* this_arg = Parameter(Descriptor::kThisArg);
|
|
||||||
Node* array = Parameter(Descriptor::kArray);
|
|
||||||
TNode<JSReceiver> object = CAST(Parameter(Descriptor::kObject));
|
|
||||||
Node* initial_k = Parameter(Descriptor::kInitialK);
|
|
||||||
TNode<Number> len = CAST(Parameter(Descriptor::kLength));
|
|
||||||
Node* to = Parameter(Descriptor::kTo);
|
|
||||||
|
|
||||||
InitIteratingArrayBuiltinLoopContinuation(context, receiver, callbackfn,
|
|
||||||
this_arg, array, object, initial_k,
|
|
||||||
len, to);
|
|
||||||
|
|
||||||
GenerateIteratingArrayBuiltinLoopContinuation(
|
|
||||||
&ArrayBuiltinsAssembler::SomeProcessor,
|
|
||||||
&ArrayBuiltinsAssembler::NullPostLoopAction, MissingPropertyMode::kSkip);
|
|
||||||
}
|
|
||||||
|
|
||||||
TF_BUILTIN(ArraySome, ArrayBuiltinsAssembler) {
|
|
||||||
TNode<IntPtrT> argc =
|
|
||||||
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
|
|
||||||
CodeStubArguments args(this, argc);
|
|
||||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
|
||||||
TNode<Object> receiver = args.GetReceiver();
|
|
||||||
Node* callbackfn = args.GetOptionalArgumentValue(0);
|
|
||||||
Node* this_arg = args.GetOptionalArgumentValue(1);
|
|
||||||
|
|
||||||
InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg, argc);
|
|
||||||
|
|
||||||
GenerateIteratingArrayBuiltinBody(
|
|
||||||
"Array.prototype.some", &ArrayBuiltinsAssembler::SomeResultGenerator,
|
|
||||||
&ArrayBuiltinsAssembler::SomeProcessor,
|
|
||||||
&ArrayBuiltinsAssembler::NullPostLoopAction,
|
|
||||||
Builtins::CallableFor(isolate(), Builtins::kArraySomeLoopContinuation),
|
|
||||||
MissingPropertyMode::kSkip);
|
|
||||||
}
|
|
||||||
|
|
||||||
TF_BUILTIN(TypedArrayPrototypeSome, ArrayBuiltinsAssembler) {
|
TF_BUILTIN(TypedArrayPrototypeSome, ArrayBuiltinsAssembler) {
|
||||||
TNode<IntPtrT> argc =
|
TNode<IntPtrT> argc =
|
||||||
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
|
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
|
||||||
@ -1708,87 +1627,6 @@ TF_BUILTIN(TypedArrayPrototypeSome, ArrayBuiltinsAssembler) {
|
|||||||
&ArrayBuiltinsAssembler::NullPostLoopAction);
|
&ArrayBuiltinsAssembler::NullPostLoopAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
TF_BUILTIN(ArrayEveryLoopLazyDeoptContinuation, ArrayBuiltinsAssembler) {
|
|
||||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
|
||||||
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
|
|
||||||
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
|
|
||||||
Node* this_arg = Parameter(Descriptor::kThisArg);
|
|
||||||
Node* initial_k = Parameter(Descriptor::kInitialK);
|
|
||||||
TNode<Number> len = CAST(Parameter(Descriptor::kLength));
|
|
||||||
Node* result = Parameter(Descriptor::kResult);
|
|
||||||
|
|
||||||
// This custom lazy deopt point is right after the callback. every() needs
|
|
||||||
// to pick up at the next step, which is either continuing to the next
|
|
||||||
// array element or returning false if {result} is false.
|
|
||||||
Label true_continue(this), false_continue(this);
|
|
||||||
|
|
||||||
// iii. If selected is true, then...
|
|
||||||
BranchIfToBooleanIsTrue(result, &true_continue, &false_continue);
|
|
||||||
BIND(&true_continue);
|
|
||||||
{
|
|
||||||
// Increment k.
|
|
||||||
initial_k = NumberInc(initial_k);
|
|
||||||
|
|
||||||
Return(CallBuiltin(Builtins::kArrayEveryLoopContinuation, context, receiver,
|
|
||||||
callbackfn, this_arg, TrueConstant(), receiver,
|
|
||||||
initial_k, len, UndefinedConstant()));
|
|
||||||
}
|
|
||||||
BIND(&false_continue);
|
|
||||||
{ Return(FalseConstant()); }
|
|
||||||
}
|
|
||||||
|
|
||||||
TF_BUILTIN(ArrayEveryLoopEagerDeoptContinuation, ArrayBuiltinsAssembler) {
|
|
||||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
|
||||||
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
|
|
||||||
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
|
|
||||||
Node* this_arg = Parameter(Descriptor::kThisArg);
|
|
||||||
Node* initial_k = Parameter(Descriptor::kInitialK);
|
|
||||||
TNode<Number> len = CAST(Parameter(Descriptor::kLength));
|
|
||||||
|
|
||||||
Return(CallBuiltin(Builtins::kArrayEveryLoopContinuation, context, receiver,
|
|
||||||
callbackfn, this_arg, TrueConstant(), receiver, initial_k,
|
|
||||||
len, UndefinedConstant()));
|
|
||||||
}
|
|
||||||
|
|
||||||
TF_BUILTIN(ArrayEveryLoopContinuation, ArrayBuiltinsAssembler) {
|
|
||||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
|
||||||
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
|
|
||||||
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
|
|
||||||
Node* this_arg = Parameter(Descriptor::kThisArg);
|
|
||||||
Node* array = Parameter(Descriptor::kArray);
|
|
||||||
TNode<JSReceiver> object = CAST(Parameter(Descriptor::kObject));
|
|
||||||
Node* initial_k = Parameter(Descriptor::kInitialK);
|
|
||||||
TNode<Number> len = CAST(Parameter(Descriptor::kLength));
|
|
||||||
Node* to = Parameter(Descriptor::kTo);
|
|
||||||
|
|
||||||
InitIteratingArrayBuiltinLoopContinuation(context, receiver, callbackfn,
|
|
||||||
this_arg, array, object, initial_k,
|
|
||||||
len, to);
|
|
||||||
|
|
||||||
GenerateIteratingArrayBuiltinLoopContinuation(
|
|
||||||
&ArrayBuiltinsAssembler::EveryProcessor,
|
|
||||||
&ArrayBuiltinsAssembler::NullPostLoopAction, MissingPropertyMode::kSkip);
|
|
||||||
}
|
|
||||||
|
|
||||||
TF_BUILTIN(ArrayEvery, ArrayBuiltinsAssembler) {
|
|
||||||
TNode<IntPtrT> argc =
|
|
||||||
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
|
|
||||||
CodeStubArguments args(this, argc);
|
|
||||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
|
||||||
TNode<Object> receiver = args.GetReceiver();
|
|
||||||
Node* callbackfn = args.GetOptionalArgumentValue(0);
|
|
||||||
Node* this_arg = args.GetOptionalArgumentValue(1);
|
|
||||||
|
|
||||||
InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg, argc);
|
|
||||||
|
|
||||||
GenerateIteratingArrayBuiltinBody(
|
|
||||||
"Array.prototype.every", &ArrayBuiltinsAssembler::EveryResultGenerator,
|
|
||||||
&ArrayBuiltinsAssembler::EveryProcessor,
|
|
||||||
&ArrayBuiltinsAssembler::NullPostLoopAction,
|
|
||||||
Builtins::CallableFor(isolate(), Builtins::kArrayEveryLoopContinuation),
|
|
||||||
MissingPropertyMode::kSkip);
|
|
||||||
}
|
|
||||||
|
|
||||||
TF_BUILTIN(TypedArrayPrototypeEvery, ArrayBuiltinsAssembler) {
|
TF_BUILTIN(TypedArrayPrototypeEvery, ArrayBuiltinsAssembler) {
|
||||||
TNode<IntPtrT> argc =
|
TNode<IntPtrT> argc =
|
||||||
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
|
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
|
||||||
|
@ -350,22 +350,6 @@ namespace internal {
|
|||||||
TFS(CloneFastJSArray, kSource) \
|
TFS(CloneFastJSArray, kSource) \
|
||||||
TFS(CloneFastJSArrayFillingHoles, kSource) \
|
TFS(CloneFastJSArrayFillingHoles, kSource) \
|
||||||
TFS(ExtractFastJSArray, kSource, kBegin, kCount) \
|
TFS(ExtractFastJSArray, kSource, kBegin, kCount) \
|
||||||
/* ES6 #sec-array.prototype.every */ \
|
|
||||||
TFS(ArrayEveryLoopContinuation, kReceiver, kCallbackFn, kThisArg, kArray, \
|
|
||||||
kObject, kInitialK, kLength, kTo) \
|
|
||||||
TFJ(ArrayEveryLoopEagerDeoptContinuation, 4, kReceiver, kCallbackFn, \
|
|
||||||
kThisArg, kInitialK, kLength) \
|
|
||||||
TFJ(ArrayEveryLoopLazyDeoptContinuation, 5, kReceiver, kCallbackFn, \
|
|
||||||
kThisArg, kInitialK, kLength, kResult) \
|
|
||||||
TFJ(ArrayEvery, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
|
|
||||||
/* ES6 #sec-array.prototype.some */ \
|
|
||||||
TFS(ArraySomeLoopContinuation, kReceiver, kCallbackFn, kThisArg, kArray, \
|
|
||||||
kObject, kInitialK, kLength, kTo) \
|
|
||||||
TFJ(ArraySomeLoopEagerDeoptContinuation, 4, kReceiver, kCallbackFn, \
|
|
||||||
kThisArg, kInitialK, kLength) \
|
|
||||||
TFJ(ArraySomeLoopLazyDeoptContinuation, 5, kReceiver, kCallbackFn, kThisArg, \
|
|
||||||
kInitialK, kLength, kResult) \
|
|
||||||
TFJ(ArraySome, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
|
|
||||||
/* ES6 #sec-array.prototype.reduce */ \
|
/* ES6 #sec-array.prototype.reduce */ \
|
||||||
TFS(ArrayReduceLoopContinuation, kReceiver, kCallbackFn, kThisArg, \
|
TFS(ArrayReduceLoopContinuation, kReceiver, kCallbackFn, kThisArg, \
|
||||||
kAccumulator, kObject, kInitialK, kLength, kTo) \
|
kAccumulator, kObject, kInitialK, kLength, kTo) \
|
||||||
|
Loading…
Reference in New Issue
Block a user