[builtins] Implement Array#findFromLast and friends
This proposal reached Stage 3 at the July 2021 TC39. https://github.com/tc39/proposal-array-find-from-last Bug: v8:11990 Change-Id: I1364b46b7ed4bc56e4b3024d14bde799f9878b5a Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3037160 Commit-Queue: Shu-yu Guo <syg@chromium.org> Reviewed-by: Marja Hölttä <marja@chromium.org> Cr-Commit-Position: refs/heads/master@{#76007}
This commit is contained in:
parent
5e4e0126f1
commit
d63ca69c22
@ -617,6 +617,8 @@ filegroup(
|
||||
"src/builtins/array-filter.tq",
|
||||
"src/builtins/array-find.tq",
|
||||
"src/builtins/array-findindex.tq",
|
||||
"src/builtins/array-findlast.tq",
|
||||
"src/builtins/array-findlastindex.tq",
|
||||
"src/builtins/array-foreach.tq",
|
||||
"src/builtins/array-from.tq",
|
||||
"src/builtins/array-isarray.tq",
|
||||
@ -718,6 +720,8 @@ filegroup(
|
||||
"src/builtins/typed-array-filter.tq",
|
||||
"src/builtins/typed-array-find.tq",
|
||||
"src/builtins/typed-array-findindex.tq",
|
||||
"src/builtins/typed-array-findlast.tq",
|
||||
"src/builtins/typed-array-findlastindex.tq",
|
||||
"src/builtins/typed-array-foreach.tq",
|
||||
"src/builtins/typed-array-from.tq",
|
||||
"src/builtins/typed-array-keys.tq",
|
||||
|
4
BUILD.gn
4
BUILD.gn
@ -1413,6 +1413,8 @@ torque_files = [
|
||||
"src/builtins/array-filter.tq",
|
||||
"src/builtins/array-find.tq",
|
||||
"src/builtins/array-findindex.tq",
|
||||
"src/builtins/array-findlast.tq",
|
||||
"src/builtins/array-findlastindex.tq",
|
||||
"src/builtins/array-foreach.tq",
|
||||
"src/builtins/array-from.tq",
|
||||
"src/builtins/array-isarray.tq",
|
||||
@ -1514,6 +1516,8 @@ torque_files = [
|
||||
"src/builtins/typed-array-filter.tq",
|
||||
"src/builtins/typed-array-find.tq",
|
||||
"src/builtins/typed-array-findindex.tq",
|
||||
"src/builtins/typed-array-findlast.tq",
|
||||
"src/builtins/typed-array-findlastindex.tq",
|
||||
"src/builtins/typed-array-foreach.tq",
|
||||
"src/builtins/typed-array-from.tq",
|
||||
"src/builtins/typed-array-keys.tq",
|
||||
|
110
src/builtins/array-findlast.tq
Normal file
110
src/builtins/array-findlast.tq
Normal file
@ -0,0 +1,110 @@
|
||||
// Copyright 2021 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 {
|
||||
// https://tc39.es/proposal-array-find-from-last/index.html#sec-array.prototype.findlast
|
||||
transitioning builtin ArrayFindLastLoopContinuation(implicit context: Context)(
|
||||
predicate: Callable, thisArg: JSAny, o: JSReceiver,
|
||||
initialK: Number): JSAny {
|
||||
// 5. Repeat, while k >= 0
|
||||
for (let k: Number = initialK; k >= 0; k--) {
|
||||
// 5a. 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.
|
||||
|
||||
// 5b. Let kValue be ? Get(O, Pk).
|
||||
const value: JSAny = GetProperty(o, k);
|
||||
|
||||
// 5c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue,
|
||||
// 𝔽(k), O »)).
|
||||
const testResult: JSAny = Call(context, predicate, thisArg, value, k, o);
|
||||
|
||||
// 5d. If testResult is true, return kValue.
|
||||
if (ToBoolean(testResult)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// 5e. Set k to k - 1. (done by the loop).
|
||||
}
|
||||
|
||||
// 6. Return undefined.
|
||||
return Undefined;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-array-find-from-last/index.html#sec-array.prototype.findlast
|
||||
transitioning macro FastArrayFindLast(implicit context: Context)(
|
||||
o: JSReceiver, len: Number, predicate: Callable, thisArg: JSAny): JSAny
|
||||
labels Bailout(Number) {
|
||||
const smiLen = Cast<Smi>(len) otherwise goto Bailout(len - 1);
|
||||
// 4. Let k be len - 1.
|
||||
let k: Smi = smiLen - 1;
|
||||
const fastO = Cast<FastJSArray>(o) otherwise goto Bailout(k);
|
||||
let fastOW = NewFastJSArrayWitness(fastO);
|
||||
|
||||
// 5. Repeat, while k ≥ 0
|
||||
// Build a fast loop over the smi array.
|
||||
for (; k >= 0; k--) {
|
||||
fastOW.Recheck() otherwise goto Bailout(k);
|
||||
|
||||
// Ensure that we haven't walked beyond a possibly updated length.
|
||||
if (k >= fastOW.Get().length) goto Bailout(k);
|
||||
|
||||
// 5a. Let Pk be ! ToString(𝔽(k)).
|
||||
// k is guaranteed to be a positive integer, hence there is no need to
|
||||
// cast ToString for LoadElementOrUndefined.
|
||||
|
||||
// 5b. Let kValue be ? Get(O, Pk).
|
||||
const value: JSAny = fastOW.LoadElementOrUndefined(k);
|
||||
// 5c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue,
|
||||
// 𝔽(k), O »)).
|
||||
const testResult: JSAny =
|
||||
Call(context, predicate, thisArg, value, k, fastOW.Get());
|
||||
// 5d. If testResult is true, return kValue.
|
||||
if (ToBoolean(testResult)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// 5e. Set k to k - 1. (done by the loop).
|
||||
}
|
||||
|
||||
// 6. Return undefined.
|
||||
return Undefined;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-array-find-from-last/index.html#sec-array.prototype.findlast
|
||||
transitioning javascript builtin
|
||||
ArrayPrototypeFindLast(
|
||||
js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
|
||||
try {
|
||||
RequireObjectCoercible(receiver, 'Array.prototype.findLast');
|
||||
|
||||
// 1. Let O be ? ToObject(this value).
|
||||
const o: JSReceiver = ToObject_Inline(context, receiver);
|
||||
|
||||
// 2. Let len be ? LengthOfArrayLike(O).
|
||||
const len: Number = GetLengthProperty(o);
|
||||
|
||||
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
|
||||
if (arguments.length == 0) {
|
||||
goto NotCallableError;
|
||||
}
|
||||
const predicate = Cast<Callable>(arguments[0]) otherwise NotCallableError;
|
||||
|
||||
// If a thisArg parameter is provided, it will be used as the this value for
|
||||
// each invocation of predicate. If it is not provided, undefined is used
|
||||
// instead.
|
||||
const thisArg: JSAny = arguments[1];
|
||||
|
||||
// Special cases.
|
||||
try {
|
||||
return FastArrayFindLast(o, len, predicate, thisArg)
|
||||
otherwise Bailout;
|
||||
} label Bailout(k: Number) deferred {
|
||||
return ArrayFindLastLoopContinuation(predicate, thisArg, o, k);
|
||||
}
|
||||
} label NotCallableError deferred {
|
||||
ThrowTypeError(MessageTemplate::kCalledNonCallable, arguments[0]);
|
||||
}
|
||||
}
|
||||
}
|
111
src/builtins/array-findlastindex.tq
Normal file
111
src/builtins/array-findlastindex.tq
Normal file
@ -0,0 +1,111 @@
|
||||
// Copyright 2021 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 {
|
||||
// https://tc39.es/proposal-array-find-from-last/index.html#sec-array.prototype.findlastindex
|
||||
transitioning builtin ArrayFindLastIndexLoopContinuation(
|
||||
implicit context: Context)(
|
||||
predicate: Callable, thisArg: JSAny, o: JSReceiver,
|
||||
initialK: Number): Number {
|
||||
// 5. Repeat, while k >= 0
|
||||
for (let k: Number = initialK; k >= 0; k--) {
|
||||
// 5a. 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.
|
||||
|
||||
// 5b. Let kValue be ? Get(O, Pk).
|
||||
const value: JSAny = GetProperty(o, k);
|
||||
|
||||
// 5c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue,
|
||||
// 𝔽(k), O »)).
|
||||
const testResult: JSAny = Call(context, predicate, thisArg, value, k, o);
|
||||
|
||||
// 5d. If testResult is true, return 𝔽(k).
|
||||
if (ToBoolean(testResult)) {
|
||||
return k;
|
||||
}
|
||||
|
||||
// 5e. Set k to k - 1. (done by the loop).
|
||||
}
|
||||
|
||||
// 6. Return -1𝔽.
|
||||
return Convert<Smi>(-1);
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-array-find-from-last/index.html#sec-array.prototype.findlastindex
|
||||
transitioning macro FastArrayFindLastIndex(implicit context: Context)(
|
||||
o: JSReceiver, len: Number, predicate: Callable, thisArg: JSAny): Number
|
||||
labels Bailout(Number) {
|
||||
const smiLen = Cast<Smi>(len) otherwise goto Bailout(len - 1);
|
||||
// 4. Let k be len - 1.
|
||||
let k: Smi = smiLen - 1;
|
||||
const fastO = Cast<FastJSArray>(o) otherwise goto Bailout(k);
|
||||
let fastOW = NewFastJSArrayWitness(fastO);
|
||||
|
||||
// 5. Repeat, while k ≥ 0
|
||||
// Build a fast loop over the smi array.
|
||||
for (; k >= 0; k--) {
|
||||
fastOW.Recheck() otherwise goto Bailout(k);
|
||||
|
||||
// Ensure that we haven't walked beyond a possibly updated length.
|
||||
if (k >= fastOW.Get().length) goto Bailout(k);
|
||||
|
||||
// 5a. Let Pk be ! ToString(𝔽(k)).
|
||||
// k is guaranteed to be a positive integer, hence there is no need to
|
||||
// cast ToString for LoadElementOrUndefined.
|
||||
|
||||
// 5b. Let kValue be ? Get(O, Pk).
|
||||
const value: JSAny = fastOW.LoadElementOrUndefined(k);
|
||||
// 5c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue,
|
||||
// 𝔽(k), O »)).
|
||||
const testResult: JSAny =
|
||||
Call(context, predicate, thisArg, value, k, fastOW.Get());
|
||||
// 5d. If testResult is true, return 𝔽(k).
|
||||
if (ToBoolean(testResult)) {
|
||||
return k;
|
||||
}
|
||||
|
||||
// 5e. Set k to k - 1. (done by the loop).
|
||||
}
|
||||
|
||||
// 6. Return -1𝔽.
|
||||
return -1;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-array-find-from-last/index.html#sec-array.prototype.findlastindex
|
||||
transitioning javascript builtin
|
||||
ArrayPrototypeFindLastIndex(
|
||||
js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
|
||||
try {
|
||||
RequireObjectCoercible(receiver, 'Array.prototype.findLastIndex');
|
||||
|
||||
// 1. Let O be ? ToObject(this value).
|
||||
const o: JSReceiver = ToObject_Inline(context, receiver);
|
||||
|
||||
// 2. Let len be ? LengthOfArrayLike(O).
|
||||
const len: Number = GetLengthProperty(o);
|
||||
|
||||
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
|
||||
if (arguments.length == 0) {
|
||||
goto NotCallableError;
|
||||
}
|
||||
const predicate = Cast<Callable>(arguments[0]) otherwise NotCallableError;
|
||||
|
||||
// If a thisArg parameter is provided, it will be used as the this value for
|
||||
// each invocation of predicate. If it is not provided, undefined is used
|
||||
// instead.
|
||||
const thisArg: JSAny = arguments[1];
|
||||
|
||||
// Special cases.
|
||||
try {
|
||||
return FastArrayFindLastIndex(o, len, predicate, thisArg)
|
||||
otherwise Bailout;
|
||||
} label Bailout(k: Number) deferred {
|
||||
return ArrayFindLastIndexLoopContinuation(predicate, thisArg, o, k);
|
||||
}
|
||||
} label NotCallableError deferred {
|
||||
ThrowTypeError(MessageTemplate::kCalledNonCallable, arguments[0]);
|
||||
}
|
||||
}
|
||||
}
|
112
src/builtins/typed-array-findlast.tq
Normal file
112
src/builtins/typed-array-findlast.tq
Normal file
@ -0,0 +1,112 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
#include 'src/builtins/builtins-typed-array-gen.h'
|
||||
|
||||
namespace typed_array {
|
||||
const kBuiltinNameFindLast: constexpr string =
|
||||
'%TypedArray%.prototype.findLast';
|
||||
|
||||
// Continuation part of
|
||||
// https://tc39.es/proposal-array-find-from-last/index.html#sec-%typedarray%.prototype.findlast
|
||||
// when array buffer was detached.
|
||||
transitioning builtin FindLastAllElementsDetachedContinuation(
|
||||
implicit context: Context)(
|
||||
array: JSTypedArray, predicate: Callable, thisArg: JSAny,
|
||||
initialK: Number): JSAny {
|
||||
// 6. Repeat, while k ≥ 0
|
||||
for (let k: Number = initialK; k >= 0; k--) {
|
||||
// 6a. Let Pk be ! ToString(𝔽(k)).
|
||||
// there is no need to cast ToString to load elements.
|
||||
|
||||
// 6b. Let kValue be ! Get(O, Pk).
|
||||
// kValue must be undefined when the buffer was detached.
|
||||
|
||||
// 6c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue,
|
||||
// 𝔽(k), O »)).
|
||||
// TODO(v8:4153): Consider versioning this loop for Smi and non-Smi
|
||||
// indices to optimize Convert<Number>(k) for the most common case.
|
||||
const result =
|
||||
Call(context, predicate, thisArg, Undefined, Convert<Number>(k), array);
|
||||
// 6d. If testResult is true, return kValue.
|
||||
if (ToBoolean(result)) {
|
||||
return Undefined;
|
||||
}
|
||||
|
||||
// 6e. Set k to k - 1. (done by the loop).
|
||||
}
|
||||
|
||||
// 7. Return undefined.
|
||||
return Undefined;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-array-find-from-last/index.html#sec-%typedarray%.prototype.findlast
|
||||
transitioning macro FindLastAllElements(implicit context: Context)(
|
||||
array: typed_array::AttachedJSTypedArray, predicate: Callable,
|
||||
thisArg: JSAny): JSAny labels
|
||||
Bailout(Number) {
|
||||
let witness = typed_array::NewAttachedJSTypedArrayWitness(array);
|
||||
// 3. Let len be O.[[ArrayLength]].
|
||||
const length: uintptr = witness.Get().length;
|
||||
// 5. Let k be len - 1.
|
||||
// 6. Repeat, while k ≥ 0
|
||||
for (let k: uintptr = length; k-- > 0;) {
|
||||
witness.Recheck() otherwise goto Bailout(Convert<Number>(k));
|
||||
// 6a. Let Pk be ! ToString(𝔽(k)).
|
||||
// there is no need to cast ToString to load elements.
|
||||
|
||||
// 6b. Let kValue be ! Get(O, Pk).
|
||||
const value: JSAny = witness.Load(k);
|
||||
|
||||
// 6c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue,
|
||||
// 𝔽(k), O »)).
|
||||
// TODO(v8:4153): Consider versioning this loop for Smi and non-Smi
|
||||
// indices to optimize Convert<Number>(k) for the most common case.
|
||||
const result = Call(
|
||||
context, predicate, thisArg, value, Convert<Number>(k),
|
||||
witness.GetStable());
|
||||
// 6d. If testResult is true, return kValue.
|
||||
if (ToBoolean(result)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// 6e. Set k to k - 1. (done by the loop).
|
||||
}
|
||||
|
||||
// 7. Return undefined.
|
||||
return Undefined;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-array-find-from-last/index.html#sec-%typedarray%.prototype.findlast
|
||||
transitioning javascript builtin
|
||||
TypedArrayPrototypeFindLast(
|
||||
js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
|
||||
// arguments[0] = callback
|
||||
// arguments[1] = thisArg
|
||||
try {
|
||||
// 1. Let O be the this value.
|
||||
const array: JSTypedArray = Cast<JSTypedArray>(receiver)
|
||||
otherwise NotTypedArray;
|
||||
// 2. Perform ? ValidateTypedArray(O).
|
||||
const uarray = typed_array::EnsureAttached(array) otherwise IsDetached;
|
||||
|
||||
// 4. If IsCallable(predicate) is false, throw a TypeError exception.
|
||||
const predicate = Cast<Callable>(arguments[0]) otherwise NotCallable;
|
||||
const thisArg = arguments[1];
|
||||
try {
|
||||
return FindLastAllElements(uarray, predicate, thisArg)
|
||||
otherwise Bailout;
|
||||
} label Bailout(k: Number) deferred {
|
||||
return FindLastAllElementsDetachedContinuation(
|
||||
uarray, predicate, thisArg, k);
|
||||
}
|
||||
} label NotCallable deferred {
|
||||
ThrowTypeError(MessageTemplate::kCalledNonCallable, arguments[0]);
|
||||
} label NotTypedArray deferred {
|
||||
ThrowTypeError(MessageTemplate::kNotTypedArray, kBuiltinNameFindLast);
|
||||
} label IsDetached deferred {
|
||||
ThrowTypeError(MessageTemplate::kDetachedOperation, kBuiltinNameFindLast);
|
||||
}
|
||||
}
|
||||
}
|
115
src/builtins/typed-array-findlastindex.tq
Normal file
115
src/builtins/typed-array-findlastindex.tq
Normal file
@ -0,0 +1,115 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
#include 'src/builtins/builtins-typed-array-gen.h'
|
||||
|
||||
namespace typed_array {
|
||||
const kBuiltinNameFindLastIndex: constexpr string =
|
||||
'%TypedArray%.prototype.findIndexLast';
|
||||
|
||||
// Continuation part of
|
||||
// https://tc39.es/proposal-array-find-from-last/index.html#sec-%typedarray%.prototype.findlastindex
|
||||
// when array buffer was detached.
|
||||
transitioning builtin FindLastIndexAllElementsDetachedContinuation(
|
||||
implicit context: Context)(
|
||||
array: JSTypedArray, predicate: Callable, thisArg: JSAny,
|
||||
initialK: Number): Number {
|
||||
// 6. Repeat, while k ≥ 0
|
||||
for (let k: Number = initialK; k >= 0; k--) {
|
||||
// 6a. Let Pk be ! ToString(𝔽(k)).
|
||||
// there is no need to cast ToString to load elements.
|
||||
|
||||
// 6b. Let kValue be ! Get(O, Pk).
|
||||
// kValue must be undefined when the buffer was detached.
|
||||
|
||||
// 6c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue,
|
||||
// 𝔽(k), O »)).
|
||||
// TODO(v8:4153): Consider versioning this loop for Smi and non-Smi
|
||||
// indices to optimize Convert<Number>(k) for the most common case.
|
||||
const indexNumber: Number = Convert<Number>(k);
|
||||
const result =
|
||||
Call(context, predicate, thisArg, Undefined, indexNumber, array);
|
||||
// 6d. If testResult is true, return 𝔽(k).
|
||||
if (ToBoolean(result)) {
|
||||
return indexNumber;
|
||||
}
|
||||
|
||||
// 6e. Set k to k - 1. (done by the loop).
|
||||
}
|
||||
|
||||
// 7. Return -1𝔽.
|
||||
return -1;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-array-find-from-last/index.html#sec-%typedarray%.prototype.findlastindex
|
||||
transitioning macro FindLastIndexAllElements(implicit context: Context)(
|
||||
array: typed_array::AttachedJSTypedArray, predicate: Callable,
|
||||
thisArg: JSAny): Number labels
|
||||
Bailout(Number) {
|
||||
let witness = typed_array::NewAttachedJSTypedArrayWitness(array);
|
||||
// 3. Let len be O.[[ArrayLength]].
|
||||
const length: uintptr = witness.Get().length;
|
||||
// 5. Let k be len - 1.
|
||||
// 6. Repeat, while k ≥ 0
|
||||
for (let k: uintptr = length; k-- > 0;) {
|
||||
witness.Recheck() otherwise goto Bailout(Convert<Number>(k));
|
||||
// 6a. Let Pk be ! ToString(𝔽(k)).
|
||||
// there is no need to cast ToString to load elements.
|
||||
|
||||
// 6b. Let kValue be ! Get(O, Pk).
|
||||
const value: JSAny = witness.Load(k);
|
||||
|
||||
// 6c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue,
|
||||
// 𝔽(k), O »)).
|
||||
// TODO(v8:4153): Consider versioning this loop for Smi and non-Smi
|
||||
// indices to optimize Convert<Number>(k) for the most common case.
|
||||
const indexNumber: Number = Convert<Number>(k);
|
||||
const result = Call(
|
||||
context, predicate, thisArg, value, indexNumber, witness.GetStable());
|
||||
// 6d. If testResult is true, return 𝔽(k).
|
||||
if (ToBoolean(result)) {
|
||||
return indexNumber;
|
||||
}
|
||||
|
||||
// 6e. Set k to k - 1. (done by the loop).
|
||||
}
|
||||
|
||||
// 7. Return -1𝔽.
|
||||
return -1;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-array-find-from-last/index.html#sec-%typedarray%.prototype.findlastindex
|
||||
transitioning javascript builtin
|
||||
TypedArrayPrototypeFindLastIndex(
|
||||
js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
|
||||
// arguments[0] = callback
|
||||
// arguments[1] = thisArg.
|
||||
try {
|
||||
// 1. Let O be the this value.
|
||||
const array: JSTypedArray = Cast<JSTypedArray>(receiver)
|
||||
otherwise NotTypedArray;
|
||||
// 2. Perform ? ValidateTypedArray(O).
|
||||
const uarray = typed_array::EnsureAttached(array) otherwise IsDetached;
|
||||
|
||||
// 4. If IsCallable(predicate) is false, throw a TypeError exception.
|
||||
const predicate = Cast<Callable>(arguments[0]) otherwise NotCallable;
|
||||
const thisArg = arguments[1];
|
||||
|
||||
try {
|
||||
return FindLastIndexAllElements(uarray, predicate, thisArg)
|
||||
otherwise Bailout;
|
||||
} label Bailout(k: Number) deferred {
|
||||
return FindLastIndexAllElementsDetachedContinuation(
|
||||
uarray, predicate, thisArg, k);
|
||||
}
|
||||
} label NotCallable deferred {
|
||||
ThrowTypeError(MessageTemplate::kCalledNonCallable, arguments[0]);
|
||||
} label NotTypedArray deferred {
|
||||
ThrowTypeError(MessageTemplate::kNotTypedArray, kBuiltinNameFindLastIndex);
|
||||
} label IsDetached deferred {
|
||||
ThrowTypeError(
|
||||
MessageTemplate::kDetachedOperation, kBuiltinNameFindLastIndex);
|
||||
}
|
||||
}
|
||||
}
|
@ -283,7 +283,8 @@ DEFINE_BOOL(harmony_shipping, true, "enable all shipped harmony features")
|
||||
"harmony weak references with FinalizationRegistry.prototype.cleanupSome") \
|
||||
V(harmony_import_assertions, "harmony import assertions") \
|
||||
V(harmony_rab_gsab, \
|
||||
"harmony ResizableArrayBuffer / GrowableSharedArrayBuffer")
|
||||
"harmony ResizableArrayBuffer / GrowableSharedArrayBuffer") \
|
||||
V(harmony_array_find_last, "harmony array find last helpers")
|
||||
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#define HARMONY_INPROGRESS(V) HARMONY_INPROGRESS_BASE(V)
|
||||
|
@ -4405,6 +4405,39 @@ EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_more_timezone)
|
||||
|
||||
#undef EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE
|
||||
|
||||
void Genesis::InitializeGlobal_harmony_array_find_last() {
|
||||
if (!FLAG_harmony_array_find_last) return;
|
||||
|
||||
{
|
||||
Handle<JSFunction> array_function(native_context()->array_function(),
|
||||
isolate());
|
||||
Handle<JSObject> array_prototype(
|
||||
JSObject::cast(array_function->instance_prototype()), isolate());
|
||||
|
||||
SimpleInstallFunction(isolate_, array_prototype, "findLast",
|
||||
Builtin::kArrayPrototypeFindLast, 1, false);
|
||||
SimpleInstallFunction(isolate_, array_prototype, "findLastIndex",
|
||||
Builtin::kArrayPrototypeFindLastIndex, 1, false);
|
||||
|
||||
Handle<JSObject> unscopables = Handle<JSObject>::cast(
|
||||
JSObject::GetProperty(isolate(), array_prototype,
|
||||
isolate()->factory()->unscopables_symbol())
|
||||
.ToHandleChecked());
|
||||
|
||||
InstallTrueValuedProperty(isolate_, unscopables, "findLast");
|
||||
InstallTrueValuedProperty(isolate_, unscopables, "findLastIndex");
|
||||
}
|
||||
|
||||
{
|
||||
Handle<JSObject> prototype(native_context()->typed_array_prototype(),
|
||||
isolate());
|
||||
SimpleInstallFunction(isolate_, prototype, "findLast",
|
||||
Builtin::kTypedArrayPrototypeFindLast, 1, false);
|
||||
SimpleInstallFunction(isolate_, prototype, "findLastIndex",
|
||||
Builtin::kTypedArrayPrototypeFindLastIndex, 1, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Genesis::InitializeGlobal_harmony_object_has_own() {
|
||||
if (!FLAG_harmony_object_has_own) return;
|
||||
|
||||
|
15
test/mjsunit/harmony/array-findlast-unscopables.js
Normal file
15
test/mjsunit/harmony/array-findlast-unscopables.js
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
// Flags: --harmony-array-find-last
|
||||
|
||||
var findLast = 'local findLast';
|
||||
var findLastIndex = 'local findLastIndex';
|
||||
|
||||
var array = [];
|
||||
|
||||
with (array) {
|
||||
assertEquals('local findLast', findLast);
|
||||
assertEquals('local findLastIndex', findLastIndex);
|
||||
}
|
21
test/mjsunit/harmony/array-prototype-findlast.js
Normal file
21
test/mjsunit/harmony/array-prototype-findlast.js
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
// Flags: --harmony-array-find-last
|
||||
|
||||
(function () {
|
||||
var array = [,];
|
||||
|
||||
function findLast() {
|
||||
return array.findLast(v => v > 0);
|
||||
}
|
||||
|
||||
assertEquals(findLast(), undefined);
|
||||
|
||||
array.__proto__.push(6);
|
||||
assertEquals(findLast(), 6);
|
||||
|
||||
array = [6, -1, 5];
|
||||
assertEquals(findLast(), 5);
|
||||
})();
|
21
test/mjsunit/harmony/array-prototype-findlastindex.js
Normal file
21
test/mjsunit/harmony/array-prototype-findlastindex.js
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
// Flags: --harmony-array-find-last
|
||||
|
||||
(function () {
|
||||
var array = [,];
|
||||
|
||||
function findLastIndex() {
|
||||
return array.findLastIndex(v => v > 0);
|
||||
}
|
||||
|
||||
assertEquals(findLastIndex(), -1);
|
||||
|
||||
array.__proto__.push(6);
|
||||
assertEquals(findLastIndex(), 0);
|
||||
|
||||
array = [6, -1, 5];
|
||||
assertEquals(findLastIndex(), 2);
|
||||
})();
|
226
test/mjsunit/harmony/typedarray-findlast.js
Normal file
226
test/mjsunit/harmony/typedarray-findlast.js
Normal file
@ -0,0 +1,226 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
// Flags: --allow-natives-syntax --harmony-array-find-last
|
||||
|
||||
var typedArrayConstructors = [
|
||||
Uint8Array,
|
||||
Int8Array,
|
||||
Uint16Array,
|
||||
Int16Array,
|
||||
Uint32Array,
|
||||
Int32Array,
|
||||
Uint8ClampedArray,
|
||||
Float32Array,
|
||||
Float64Array];
|
||||
|
||||
for (var constructor of typedArrayConstructors) {
|
||||
|
||||
assertEquals(1, constructor.prototype.findLast.length);
|
||||
|
||||
var a = new constructor([21, 22, 23, 24]);
|
||||
assertEquals(undefined, a.findLast(function() { return false; }));
|
||||
assertEquals(24, a.findLast(function() { return true; }));
|
||||
assertEquals(undefined, a.findLast(function(val) { return 121 === val; }));
|
||||
assertEquals(24, a.findLast(function(val) { return 24 === val; }));
|
||||
assertEquals(23, a.findLast(function(val) { return 23 === val; }), null);
|
||||
assertEquals(22, a.findLast(function(val) { return 22 === val; }), undefined);
|
||||
|
||||
|
||||
//
|
||||
// Test predicate is not called when array is empty
|
||||
//
|
||||
(function() {
|
||||
var a = new constructor([]);
|
||||
var l = -1;
|
||||
var o = -1;
|
||||
var v = -1;
|
||||
var k = -1;
|
||||
|
||||
a.findLast(function(val, key, obj) {
|
||||
o = obj;
|
||||
l = obj.length;
|
||||
v = val;
|
||||
k = key;
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
assertEquals(-1, l);
|
||||
assertEquals(-1, o);
|
||||
assertEquals(-1, v);
|
||||
assertEquals(-1, k);
|
||||
})();
|
||||
|
||||
|
||||
//
|
||||
// Test predicate is called with correct arguments
|
||||
//
|
||||
(function() {
|
||||
var a = new constructor([5]);
|
||||
var l = -1;
|
||||
var o = -1;
|
||||
var v = -1;
|
||||
var k = -1;
|
||||
|
||||
var found = a.findLast(function(val, key, obj) {
|
||||
o = obj;
|
||||
l = obj.length;
|
||||
v = val;
|
||||
k = key;
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
assertArrayEquals(a, o);
|
||||
assertEquals(a.length, l);
|
||||
assertEquals(5, v);
|
||||
assertEquals(0, k);
|
||||
assertEquals(undefined, found);
|
||||
})();
|
||||
|
||||
|
||||
//
|
||||
// Test predicate is called array.length times
|
||||
//
|
||||
(function() {
|
||||
var a = new constructor([1, 2, 3, 4, 5]);
|
||||
var l = 0;
|
||||
var found = a.findLast(function() {
|
||||
l++;
|
||||
return false;
|
||||
});
|
||||
|
||||
assertEquals(a.length, l);
|
||||
assertEquals(undefined, found);
|
||||
})();
|
||||
|
||||
|
||||
//
|
||||
// Test array modifications
|
||||
//
|
||||
(function() {
|
||||
a = new constructor([1, 2, 3]);
|
||||
found = a.findLast(function(val, key) { a[key] = ++val; return false; });
|
||||
assertArrayEquals([2, 3, 4], a);
|
||||
assertEquals(3, a.length);
|
||||
assertEquals(undefined, found);
|
||||
})();
|
||||
|
||||
//
|
||||
// Test thisArg
|
||||
//
|
||||
(function() {
|
||||
// Test String as a thisArg
|
||||
var found = new constructor([1, 2, 3]).findLast(function(val, key) {
|
||||
return this.charAt(Number(key)) === String(val);
|
||||
}, "321");
|
||||
assertEquals(2, found);
|
||||
|
||||
// Test object as a thisArg
|
||||
var thisArg = {
|
||||
elementAt: function(key) {
|
||||
return this[key];
|
||||
}
|
||||
};
|
||||
Array.prototype.push.apply(thisArg, [3, 2, 1]);
|
||||
|
||||
found = new constructor([1, 2, 3]).findLast(function(val, key) {
|
||||
return this.elementAt(key) === val;
|
||||
}, thisArg);
|
||||
assertEquals(2, found);
|
||||
|
||||
// Create a new object in each function call when receiver is a
|
||||
// primitive value. See ECMA-262, Annex C.
|
||||
a = [];
|
||||
new constructor([1, 2]).findLast(function() { a.push(this) }, "");
|
||||
assertTrue(a[0] !== a[1]);
|
||||
|
||||
// Do not create a new object otherwise.
|
||||
a = [];
|
||||
new constructor([1, 2]).findLast(function() { a.push(this) }, {});
|
||||
assertEquals(a[0], a[1]);
|
||||
|
||||
// In strict mode primitive values should not be coerced to an object.
|
||||
a = [];
|
||||
new constructor([1, 2]).findLast(function() { 'use strict'; a.push(this); }, "");
|
||||
assertEquals("", a[0]);
|
||||
assertEquals(a[0], a[1]);
|
||||
|
||||
})();
|
||||
|
||||
// Test exceptions
|
||||
assertThrows('constructor.prototype.findLast.call(null, function() { })',
|
||||
TypeError);
|
||||
assertThrows('constructor.prototype.findLast.call(undefined, function() { })',
|
||||
TypeError);
|
||||
assertThrows('constructor.prototype.findLast.apply(null, function() { }, [])',
|
||||
TypeError);
|
||||
assertThrows('constructor.prototype.findLast.apply(undefined, function() { }, [])',
|
||||
TypeError);
|
||||
assertThrows('constructor.prototype.findLast.apply([], function() { }, [])',
|
||||
TypeError);
|
||||
assertThrows('constructor.prototype.findLast.apply({}, function() { }, [])',
|
||||
TypeError);
|
||||
assertThrows('constructor.prototype.findLast.apply("", function() { }, [])',
|
||||
TypeError);
|
||||
|
||||
assertThrows('new constructor([]).findLast(null)', TypeError);
|
||||
assertThrows('new constructor([]).findLast(undefined)', TypeError);
|
||||
assertThrows('new constructor([]).findLast(0)', TypeError);
|
||||
assertThrows('new constructor([]).findLast(true)', TypeError);
|
||||
assertThrows('new constructor([]).findLast(false)', TypeError);
|
||||
assertThrows('new constructor([]).findLast("")', TypeError);
|
||||
assertThrows('new constructor([]).findLast({})', TypeError);
|
||||
assertThrows('new constructor([]).findLast([])', TypeError);
|
||||
assertThrows('new constructor([]).findLast(/\d+/)', TypeError);
|
||||
|
||||
// Shadowing length doesn't affect findLast, unlike Array.prototype.findLast
|
||||
a = new constructor([1, 2]);
|
||||
Object.defineProperty(a, 'length', {value: 1});
|
||||
var x = 0;
|
||||
assertEquals(a.findLast(function(elt) { x += elt; return false; }), undefined);
|
||||
assertEquals(x, 3);
|
||||
assertEquals(Array.prototype.findLast.call(a,
|
||||
function(elt) { x += elt; return false; }), undefined);
|
||||
assertEquals(x, 4);
|
||||
|
||||
// Detached Operation
|
||||
var tmp = {
|
||||
[Symbol.toPrimitive]() {
|
||||
assertUnreachable("Parameter should not be processed when " +
|
||||
"array.[[ViewedArrayBuffer]] is detached.");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
%ArrayBufferDetach(array.buffer);
|
||||
|
||||
assertThrows(() => array.findLast(tmp), TypeError);
|
||||
|
||||
//
|
||||
// Test detaching in predicate.
|
||||
//
|
||||
(function() {
|
||||
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
var values = [];
|
||||
assertEquals(array.findLast((value) => {
|
||||
values.push(value);
|
||||
if (value === 5) {
|
||||
%ArrayBufferDetach(array.buffer);
|
||||
}
|
||||
}), undefined);
|
||||
assertEquals(values, [10, 9, 8, 7, 6, 5, undefined, undefined, undefined, undefined]);
|
||||
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
assertEquals(array.findLast((value, idx) => {
|
||||
if (value !== undefined) {
|
||||
%ArrayBufferDetach(array.buffer);
|
||||
}
|
||||
return idx === 0;
|
||||
}), undefined);
|
||||
})();
|
||||
}
|
224
test/mjsunit/harmony/typedarray-findlastindex.js
Normal file
224
test/mjsunit/harmony/typedarray-findlastindex.js
Normal file
@ -0,0 +1,224 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
// Flags: --allow-natives-syntax --harmony-array-find-last
|
||||
|
||||
var typedArrayConstructors = [
|
||||
Uint8Array,
|
||||
Int8Array,
|
||||
Uint16Array,
|
||||
Int16Array,
|
||||
Uint32Array,
|
||||
Int32Array,
|
||||
Uint8ClampedArray,
|
||||
Float32Array,
|
||||
Float64Array];
|
||||
|
||||
for (var constructor of typedArrayConstructors) {
|
||||
|
||||
assertEquals(1, constructor.prototype.findLastIndex.length);
|
||||
|
||||
var a = new constructor([21, 22, 23, 24]);
|
||||
assertEquals(-1, a.findLastIndex(function() { return false; }));
|
||||
assertEquals(-1, a.findLastIndex(function(val) { return 121 === val; }));
|
||||
assertEquals(3, a.findLastIndex(function() { return true; }));
|
||||
assertEquals(1, a.findLastIndex(function(val) { return 22 === val; }), undefined);
|
||||
assertEquals(2, a.findLastIndex(function(val) { return 23 === val; }), null);
|
||||
assertEquals(3, a.findLastIndex(function(val) { return 24 === val; }));
|
||||
|
||||
|
||||
//
|
||||
// Test predicate is not called when array is empty
|
||||
//
|
||||
(function() {
|
||||
var a = new constructor([]);
|
||||
var l = -1;
|
||||
var o = -1;
|
||||
var v = -1;
|
||||
var k = -1;
|
||||
|
||||
a.findLastIndex(function(val, key, obj) {
|
||||
o = obj;
|
||||
l = obj.length;
|
||||
v = val;
|
||||
k = key;
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
assertEquals(-1, l);
|
||||
assertEquals(-1, o);
|
||||
assertEquals(-1, v);
|
||||
assertEquals(-1, k);
|
||||
})();
|
||||
|
||||
|
||||
//
|
||||
// Test predicate is called with correct arguments
|
||||
//
|
||||
(function() {
|
||||
var a = new constructor([5]);
|
||||
var l = -1;
|
||||
var o = -1;
|
||||
var v = -1;
|
||||
var k = -1;
|
||||
|
||||
var index = a.findLastIndex(function(val, key, obj) {
|
||||
o = obj;
|
||||
l = obj.length;
|
||||
v = val;
|
||||
k = key;
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
assertArrayEquals(a, o);
|
||||
assertEquals(a.length, l);
|
||||
assertEquals(5, v);
|
||||
assertEquals(0, k);
|
||||
assertEquals(-1, index);
|
||||
})();
|
||||
|
||||
|
||||
//
|
||||
// Test predicate is called array.length times
|
||||
//
|
||||
(function() {
|
||||
var a = new constructor([1, 2, 3, 4, 5]);
|
||||
var l = 0;
|
||||
|
||||
a.findLastIndex(function() {
|
||||
l++;
|
||||
return false;
|
||||
});
|
||||
|
||||
assertEquals(a.length, l);
|
||||
})();
|
||||
|
||||
|
||||
//
|
||||
// Test array modifications
|
||||
//
|
||||
(function() {
|
||||
a = new constructor([1, 2, 3]);
|
||||
a.findLastIndex(function(val, key) { a[key] = ++val; return false; });
|
||||
assertArrayEquals([2, 3, 4], a);
|
||||
assertEquals(3, a.length);
|
||||
})();
|
||||
|
||||
|
||||
//
|
||||
// Test thisArg
|
||||
//
|
||||
(function() {
|
||||
// Test String as a thisArg
|
||||
var index = new constructor([1, 2, 3]).findLastIndex(function(val, key) {
|
||||
return this.charAt(Number(key)) === String(val);
|
||||
}, "321");
|
||||
assertEquals(1, index);
|
||||
|
||||
// Test object as a thisArg
|
||||
var thisArg = {
|
||||
elementAt: function(key) {
|
||||
return this[key];
|
||||
}
|
||||
};
|
||||
Array.prototype.push.apply(thisArg, [3, 2, 1]);
|
||||
|
||||
index = new constructor([1, 2, 3]).findLastIndex(function(val, key) {
|
||||
return this.elementAt(key) === val;
|
||||
}, thisArg);
|
||||
assertEquals(1, index);
|
||||
|
||||
// Create a new object in each function call when receiver is a
|
||||
// primitive value. See ECMA-262, Annex C.
|
||||
a = [];
|
||||
new constructor([1, 2]).findLastIndex(function() { a.push(this) }, "");
|
||||
assertTrue(a[0] !== a[1]);
|
||||
|
||||
// Do not create a new object otherwise.
|
||||
a = [];
|
||||
new constructor([1, 2]).findLastIndex(function() { a.push(this) }, {});
|
||||
assertEquals(a[0], a[1]);
|
||||
|
||||
// In strict mode primitive values should not be coerced to an object.
|
||||
a = [];
|
||||
new constructor([1, 2]).findLastIndex(function() { 'use strict'; a.push(this); }, "");
|
||||
assertEquals("", a[0]);
|
||||
assertEquals(a[0], a[1]);
|
||||
|
||||
})();
|
||||
|
||||
// Test exceptions
|
||||
assertThrows('constructor.prototype.findLastIndex.call(null, function() { })',
|
||||
TypeError);
|
||||
assertThrows('constructor.prototype.findLastIndex.call(undefined, function() { })',
|
||||
TypeError);
|
||||
assertThrows('constructor.prototype.findLastIndex.apply(null, function() { }, [])',
|
||||
TypeError);
|
||||
assertThrows('constructor.prototype.findLastIndex.apply(undefined, function() { }, [])',
|
||||
TypeError);
|
||||
assertThrows('constructor.prototype.findLastIndex.apply([], function() { }, [])',
|
||||
TypeError);
|
||||
assertThrows('constructor.prototype.findLastIndex.apply({}, function() { }, [])',
|
||||
TypeError);
|
||||
assertThrows('constructor.prototype.findLastIndex.apply("", function() { }, [])',
|
||||
TypeError);
|
||||
|
||||
assertThrows('new constructor([]).findLastIndex(null)', TypeError);
|
||||
assertThrows('new constructor([]).findLastIndex(undefined)', TypeError);
|
||||
assertThrows('new constructor([]).findLastIndex(0)', TypeError);
|
||||
assertThrows('new constructor([]).findLastIndex(true)', TypeError);
|
||||
assertThrows('new constructor([]).findLastIndex(false)', TypeError);
|
||||
assertThrows('new constructor([]).findLastIndex("")', TypeError);
|
||||
assertThrows('new constructor([]).findLastIndex({})', TypeError);
|
||||
assertThrows('new constructor([]).findLastIndex([])', TypeError);
|
||||
assertThrows('new constructor([]).findLastIndex(/\d+/)', TypeError);
|
||||
|
||||
// Shadowing length doesn't affect findLastIndex, unlike Array.prototype.findLastIndex
|
||||
a = new constructor([1, 2]);
|
||||
Object.defineProperty(a, 'length', {value: 1});
|
||||
var x = 0;
|
||||
assertEquals(a.findLastIndex(function(elt) { x += elt; return false; }), -1);
|
||||
assertEquals(x, 3);
|
||||
assertEquals(Array.prototype.findLastIndex.call(a,
|
||||
function(elt) { x += elt; return false; }), -1);
|
||||
assertEquals(x, 4);
|
||||
|
||||
// Detached Operation
|
||||
var tmp = {
|
||||
[Symbol.toPrimitive]() {
|
||||
assertUnreachable("Parameter should not be processed when " +
|
||||
"array.[[ViewedArrayBuffer]] is detached.");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
%ArrayBufferDetach(array.buffer);
|
||||
assertThrows(() => array.findLastIndex(tmp), TypeError);
|
||||
|
||||
//
|
||||
// Test detaching in predicate.
|
||||
//
|
||||
(function() {
|
||||
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
var values = [];
|
||||
assertEquals(array.findLastIndex((value, idx) => {
|
||||
values.push(value);
|
||||
if (value === 5) {
|
||||
%ArrayBufferDetach(array.buffer);
|
||||
}
|
||||
}), -1);
|
||||
assertEquals(values, [10, 9, 8, 7, 6, 5, undefined, undefined, undefined, undefined]);
|
||||
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
assertEquals(array.findLastIndex((value, idx) => {
|
||||
if (value !== undefined) {
|
||||
%ArrayBufferDetach(array.buffer);
|
||||
}
|
||||
return idx === 0;
|
||||
}), 0);
|
||||
})();
|
||||
}
|
@ -475,27 +475,27 @@ KNOWN_OBJECTS = {
|
||||
("old_space", 0x029b5): "StringSplitCache",
|
||||
("old_space", 0x02dbd): "RegExpMultipleCache",
|
||||
("old_space", 0x031c5): "BuiltinsConstantsTable",
|
||||
("old_space", 0x035d5): "AsyncFunctionAwaitRejectSharedFun",
|
||||
("old_space", 0x035f9): "AsyncFunctionAwaitResolveSharedFun",
|
||||
("old_space", 0x0361d): "AsyncGeneratorAwaitRejectSharedFun",
|
||||
("old_space", 0x03641): "AsyncGeneratorAwaitResolveSharedFun",
|
||||
("old_space", 0x03665): "AsyncGeneratorYieldResolveSharedFun",
|
||||
("old_space", 0x03689): "AsyncGeneratorReturnResolveSharedFun",
|
||||
("old_space", 0x036ad): "AsyncGeneratorReturnClosedRejectSharedFun",
|
||||
("old_space", 0x036d1): "AsyncGeneratorReturnClosedResolveSharedFun",
|
||||
("old_space", 0x036f5): "AsyncIteratorValueUnwrapSharedFun",
|
||||
("old_space", 0x03719): "PromiseAllResolveElementSharedFun",
|
||||
("old_space", 0x0373d): "PromiseAllSettledResolveElementSharedFun",
|
||||
("old_space", 0x03761): "PromiseAllSettledRejectElementSharedFun",
|
||||
("old_space", 0x03785): "PromiseAnyRejectElementSharedFun",
|
||||
("old_space", 0x037a9): "PromiseCapabilityDefaultRejectSharedFun",
|
||||
("old_space", 0x037cd): "PromiseCapabilityDefaultResolveSharedFun",
|
||||
("old_space", 0x037f1): "PromiseCatchFinallySharedFun",
|
||||
("old_space", 0x03815): "PromiseGetCapabilitiesExecutorSharedFun",
|
||||
("old_space", 0x03839): "PromiseThenFinallySharedFun",
|
||||
("old_space", 0x0385d): "PromiseThrowerFinallySharedFun",
|
||||
("old_space", 0x03881): "PromiseValueThunkFinallySharedFun",
|
||||
("old_space", 0x038a5): "ProxyRevokeSharedFun",
|
||||
("old_space", 0x035e5): "AsyncFunctionAwaitRejectSharedFun",
|
||||
("old_space", 0x03609): "AsyncFunctionAwaitResolveSharedFun",
|
||||
("old_space", 0x0362d): "AsyncGeneratorAwaitRejectSharedFun",
|
||||
("old_space", 0x03651): "AsyncGeneratorAwaitResolveSharedFun",
|
||||
("old_space", 0x03675): "AsyncGeneratorYieldResolveSharedFun",
|
||||
("old_space", 0x03699): "AsyncGeneratorReturnResolveSharedFun",
|
||||
("old_space", 0x036bd): "AsyncGeneratorReturnClosedRejectSharedFun",
|
||||
("old_space", 0x036e1): "AsyncGeneratorReturnClosedResolveSharedFun",
|
||||
("old_space", 0x03705): "AsyncIteratorValueUnwrapSharedFun",
|
||||
("old_space", 0x03729): "PromiseAllResolveElementSharedFun",
|
||||
("old_space", 0x0374d): "PromiseAllSettledResolveElementSharedFun",
|
||||
("old_space", 0x03771): "PromiseAllSettledRejectElementSharedFun",
|
||||
("old_space", 0x03795): "PromiseAnyRejectElementSharedFun",
|
||||
("old_space", 0x037b9): "PromiseCapabilityDefaultRejectSharedFun",
|
||||
("old_space", 0x037dd): "PromiseCapabilityDefaultResolveSharedFun",
|
||||
("old_space", 0x03801): "PromiseCatchFinallySharedFun",
|
||||
("old_space", 0x03825): "PromiseGetCapabilitiesExecutorSharedFun",
|
||||
("old_space", 0x03849): "PromiseThenFinallySharedFun",
|
||||
("old_space", 0x0386d): "PromiseThrowerFinallySharedFun",
|
||||
("old_space", 0x03891): "PromiseValueThunkFinallySharedFun",
|
||||
("old_space", 0x038b5): "ProxyRevokeSharedFun",
|
||||
}
|
||||
|
||||
# Lower 32 bits of first page addresses for various heap spaces.
|
||||
|
Loading…
Reference in New Issue
Block a user