[Builtins] Provide a code-stub impl. of Array.prototype.map
BUG= Review-Url: https://codereview.chromium.org/2765293002 Cr-Commit-Position: refs/heads/master@{#44093}
This commit is contained in:
parent
f764a5c8c0
commit
69e02958d3
@ -3714,6 +3714,7 @@ void Genesis::InitializeGlobal_experimental_fast_array_builtins() {
|
||||
|
||||
// Insert experimental fast array builtins here.
|
||||
InstallOneBuiltinFunction("Array", "filter", Builtins::kArrayFilter);
|
||||
InstallOneBuiltinFunction("Array", "map", Builtins::kArrayMap);
|
||||
}
|
||||
|
||||
void Genesis::InitializeGlobal_harmony_sharedarraybuffer() {
|
||||
|
@ -129,24 +129,42 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
|
||||
}
|
||||
|
||||
Node* FilterProcessor(Node* k_value, Node* k) {
|
||||
Node* callback_result = CallJS(CodeFactory::Call(isolate()), context(),
|
||||
callbackfn(), this_arg(), k_value, k, o());
|
||||
// ii. Let selected be ToBoolean(? Call(callbackfn, T, kValue, k, O)).
|
||||
Node* selected = CallJS(CodeFactory::Call(isolate()), context(),
|
||||
callbackfn(), this_arg(), k_value, k, o());
|
||||
Label true_continue(this, &to_), false_continue(this);
|
||||
BranchIfToBooleanIsTrue(callback_result, &true_continue, &false_continue);
|
||||
BranchIfToBooleanIsTrue(selected, &true_continue, &false_continue);
|
||||
Bind(&true_continue);
|
||||
// iii. If selected is true, then...
|
||||
{
|
||||
// 1. Perform ? CreateDataPropertyOrThrow(A, ToString(to), kValue).
|
||||
CallRuntime(Runtime::kCreateDataProperty, context(), a(), to_.value(),
|
||||
k_value);
|
||||
|
||||
// 1. let status be CreateDataPropertyOrThrow(A, ToString(to), kValue).
|
||||
// 2. ReturnIfAbrupt(status)
|
||||
Node* const p_to = ToString(context(), to_.value());
|
||||
CallRuntime(Runtime::kCreateDataProperty, context(), a(), p_to, k_value);
|
||||
|
||||
// 3. Increase to by 1.
|
||||
to_.Bind(NumberInc(to_.value()));
|
||||
Goto(&false_continue);
|
||||
// 2. Increase to by 1.
|
||||
to_.Bind(NumberInc(to_.value()));
|
||||
Goto(&false_continue);
|
||||
}
|
||||
Bind(&false_continue);
|
||||
return a();
|
||||
}
|
||||
|
||||
Node* MapResultGenerator() {
|
||||
// 5. Let A be ? ArraySpeciesCreate(O, len).
|
||||
return ArraySpeciesCreate(context(), o(), len_);
|
||||
}
|
||||
|
||||
Node* MapProcessor(Node* k_value, Node* k) {
|
||||
// i. Let kValue be ? Get(O, Pk). Performed by the caller of MapProcessor.
|
||||
// ii. Let mappedValue be ? Call(callbackfn, T, kValue, k, O).
|
||||
Node* mappedValue = CallJS(CodeFactory::Call(isolate()), context(),
|
||||
callbackfn(), this_arg(), k_value, k, o());
|
||||
|
||||
// iii. Perform ? CreateDataPropertyOrThrow(A, Pk, mappedValue).
|
||||
CallRuntime(Runtime::kCreateDataProperty, context(), a(), k, mappedValue);
|
||||
return a();
|
||||
}
|
||||
|
||||
void NullPostLoopAction() {}
|
||||
|
||||
protected:
|
||||
@ -770,13 +788,50 @@ TF_BUILTIN(ArrayFilter, ArrayBuiltinCodeStubAssembler) {
|
||||
new_target);
|
||||
|
||||
GenerateIteratingArrayBuiltinBody(
|
||||
"Array.prototype.reduce",
|
||||
"Array.prototype.filter",
|
||||
&ArrayBuiltinCodeStubAssembler::FilterResultGenerator,
|
||||
&ArrayBuiltinCodeStubAssembler::FilterProcessor,
|
||||
&ArrayBuiltinCodeStubAssembler::NullPostLoopAction,
|
||||
CodeFactory::ArrayFilterLoopContinuation(isolate()));
|
||||
}
|
||||
|
||||
TF_BUILTIN(ArrayMapLoopContinuation, ArrayBuiltinCodeStubAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
|
||||
Node* this_arg = Parameter(Descriptor::kThisArg);
|
||||
Node* array = Parameter(Descriptor::kArray);
|
||||
Node* object = Parameter(Descriptor::kObject);
|
||||
Node* initial_k = Parameter(Descriptor::kInitialK);
|
||||
Node* len = Parameter(Descriptor::kLength);
|
||||
Node* to = Parameter(Descriptor::kTo);
|
||||
|
||||
InitIteratingArrayBuiltinLoopContinuation(context, receiver, callbackfn,
|
||||
this_arg, array, object, initial_k,
|
||||
len, to);
|
||||
|
||||
GenerateIteratingArrayBuiltinLoopContinuation(
|
||||
&ArrayBuiltinCodeStubAssembler::MapProcessor,
|
||||
&ArrayBuiltinCodeStubAssembler::NullPostLoopAction);
|
||||
}
|
||||
|
||||
TF_BUILTIN(ArrayMap, ArrayBuiltinCodeStubAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
|
||||
Node* this_arg = Parameter(Descriptor::kThisArg);
|
||||
Node* new_target = Parameter(Descriptor::kNewTarget);
|
||||
|
||||
InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg,
|
||||
new_target);
|
||||
|
||||
GenerateIteratingArrayBuiltinBody(
|
||||
"Array.prototype.map", &ArrayBuiltinCodeStubAssembler::MapResultGenerator,
|
||||
&ArrayBuiltinCodeStubAssembler::MapProcessor,
|
||||
&ArrayBuiltinCodeStubAssembler::NullPostLoopAction,
|
||||
CodeFactory::ArrayMapLoopContinuation(isolate()));
|
||||
}
|
||||
|
||||
TF_BUILTIN(ArrayIsArray, CodeStubAssembler) {
|
||||
Node* object = Parameter(Descriptor::kArg);
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
|
@ -300,6 +300,10 @@ class Isolate;
|
||||
TFJ(ArrayFilterLoopContinuation, 7, kCallbackFn, kThisArg, kArray, kObject, \
|
||||
kInitialK, kLength, kTo) \
|
||||
TFJ(ArrayFilter, 2, kCallbackFn, kThisArg) \
|
||||
/* ES6 #sec-array.prototype.foreach */ \
|
||||
TFJ(ArrayMapLoopContinuation, 7, kCallbackFn, kThisArg, kArray, kObject, \
|
||||
kInitialK, kLength, kTo) \
|
||||
TFJ(ArrayMap, 2, kCallbackFn, kThisArg) \
|
||||
/* ES6 #sec-array.prototype.reduce */ \
|
||||
TFJ(ArrayReduceLoopContinuation, 7, kCallbackFn, kThisArg, kAccumulator, \
|
||||
kObject, kInitialK, kLength, kTo) \
|
||||
|
@ -513,6 +513,12 @@ Callable CodeFactory::ArrayFilterLoopContinuation(Isolate* isolate) {
|
||||
IteratingArrayBuiltinLoopContinuationDescriptor(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::ArrayMapLoopContinuation(Isolate* isolate) {
|
||||
return Callable(isolate->builtins()->ArrayMapLoopContinuation(),
|
||||
IteratingArrayBuiltinLoopContinuationDescriptor(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::ArrayForEachLoopContinuation(Isolate* isolate) {
|
||||
return Callable(isolate->builtins()->ArrayForEachLoopContinuation(),
|
||||
|
@ -185,6 +185,7 @@ class V8_EXPORT_PRIVATE CodeFactory final {
|
||||
static Callable ArrayConstructor(Isolate* isolate);
|
||||
static Callable ArrayPush(Isolate* isolate);
|
||||
static Callable ArrayFilterLoopContinuation(Isolate* isolate);
|
||||
static Callable ArrayMapLoopContinuation(Isolate* isolate);
|
||||
static Callable ArrayForEachLoopContinuation(Isolate* isolate);
|
||||
static Callable ArraySomeLoopContinuation(Isolate* isolate);
|
||||
static Callable ArrayEveryLoopContinuation(Isolate* isolate);
|
||||
|
Loading…
Reference in New Issue
Block a user