Commit 176a43fb authored by danno's avatar danno Committed by Commit bot

[builtins] Implement Array.prototype.reduce in the CSA

BUG=v8:1956

Review-Url: https://codereview.chromium.org/2752273003
Cr-Commit-Position: refs/heads/master@{#43987}
parent 64ffea85
......@@ -216,6 +216,8 @@ class Genesis BASE_EMBEDDED {
HARMONY_SHIPPING(DECLARE_FEATURE_INITIALIZATION)
#undef DECLARE_FEATURE_INITIALIZATION
void InstallOneBuiltinFunction(const char* object, const char* method,
Builtins::Name name);
void InitializeGlobal_enable_fast_array_builtins();
Handle<JSFunction> InstallArrayBuffer(Handle<JSObject> target,
......@@ -3664,63 +3666,39 @@ void InstallPublicSymbol(Factory* factory, Handle<Context> native_context,
JSObject::AddProperty(symbol, name_string, value, attributes);
}
void Genesis::InitializeGlobal_enable_fast_array_builtins() {
if (!FLAG_enable_fast_array_builtins) return;
void Genesis::InstallOneBuiltinFunction(const char* object_name,
const char* method_name,
Builtins::Name builtin_name) {
Handle<JSGlobalObject> global(native_context()->global_object());
Isolate* isolate = global->GetIsolate();
Factory* factory = isolate->factory();
LookupIterator it1(global, factory->NewStringFromAsciiChecked("Array"),
LookupIterator it1(global, factory->NewStringFromAsciiChecked(object_name),
LookupIterator::OWN_SKIP_INTERCEPTOR);
Handle<Object> array_object = Object::GetProperty(&it1).ToHandleChecked();
LookupIterator it2(array_object,
factory->NewStringFromAsciiChecked("prototype"),
Handle<Object> object = Object::GetProperty(&it1).ToHandleChecked();
LookupIterator it2(object, factory->NewStringFromAsciiChecked("prototype"),
LookupIterator::OWN_SKIP_INTERCEPTOR);
Handle<Object> array_prototype = Object::GetProperty(&it2).ToHandleChecked();
Handle<Object> prototype = Object::GetProperty(&it2).ToHandleChecked();
LookupIterator it3(array_prototype,
factory->NewStringFromAsciiChecked("forEach"),
LookupIterator::OWN_SKIP_INTERCEPTOR);
Handle<Object> for_each_function =
Object::GetProperty(&it3).ToHandleChecked();
Handle<JSFunction>::cast(for_each_function)
->set_code(isolate->builtins()->builtin(Builtins::kArrayForEach));
Handle<JSFunction>::cast(for_each_function)
->shared()
->set_code(isolate->builtins()->builtin(Builtins::kArrayForEach));
LookupIterator it4(array_prototype,
factory->NewStringFromAsciiChecked("every"),
LookupIterator::OWN_SKIP_INTERCEPTOR);
Handle<Object> every_function = Object::GetProperty(&it4).ToHandleChecked();
Handle<JSFunction>::cast(every_function)
->set_code(isolate->builtins()->builtin(Builtins::kArrayEvery));
Handle<JSFunction>::cast(every_function)
->shared()
->set_code(isolate->builtins()->builtin(Builtins::kArrayEvery));
LookupIterator it5(array_prototype,
factory->NewStringFromAsciiChecked("some"),
LookupIterator it3(prototype, factory->NewStringFromAsciiChecked(method_name),
LookupIterator::OWN_SKIP_INTERCEPTOR);
Handle<Object> some_function = Object::GetProperty(&it5).ToHandleChecked();
Handle<JSFunction>::cast(some_function)
->set_code(isolate->builtins()->builtin(Builtins::kArraySome));
Handle<JSFunction>::cast(some_function)
->shared()
->set_code(isolate->builtins()->builtin(Builtins::kArraySome));
Handle<Object> function = Object::GetProperty(&it3).ToHandleChecked();
Handle<JSFunction>::cast(function)->set_code(
isolate->builtins()->builtin(builtin_name));
Handle<JSFunction>::cast(function)->shared()->set_code(
isolate->builtins()->builtin(builtin_name));
}
void Genesis::InitializeGlobal_enable_fast_array_builtins() {
if (!FLAG_enable_fast_array_builtins) return;
InstallOneBuiltinFunction("Array", "forEach", Builtins::kArrayForEach);
InstallOneBuiltinFunction("Array", "every", Builtins::kArrayEvery);
InstallOneBuiltinFunction("Array", "some", Builtins::kArraySome);
InstallOneBuiltinFunction("Array", "reduce", Builtins::kArrayReduce);
if (FLAG_experimental_array_builtins) {
LookupIterator it6(array_prototype,
factory->NewStringFromAsciiChecked("filter"),
LookupIterator::OWN_SKIP_INTERCEPTOR);
Handle<Object> filter_function =
Object::GetProperty(&it6).ToHandleChecked();
Handle<JSFunction>::cast(filter_function)
->set_code(isolate->builtins()->builtin(Builtins::kArrayFilter));
Handle<JSFunction>::cast(filter_function)
->shared()
->set_code(isolate->builtins()->builtin(Builtins::kArrayFilter));
InstallOneBuiltinFunction("Array", "filter", Builtins::kArrayFilter);
}
}
......
This diff is collapsed.
......@@ -296,6 +296,9 @@ class Isolate;
/* ES6 #sec-array.prototype.filter */ \
TFJ(ArrayFilterLoopContinuation, 6) \
TFJ(ArrayFilter, 2, kCallbackFn, kThisArg) \
/* ES6 #sec-array.prototype.reduce */ \
TFJ(ArrayReduceLoopContinuation, 6) \
TFJ(ArrayReduce, 2, kCallbackFn, kInitialValue) \
/* ES6 #sec-array.prototype.entries */ \
TFJ(ArrayPrototypeEntries, 0) \
/* ES6 #sec-array.prototype.keys */ \
......
......@@ -512,6 +512,12 @@ Callable CodeFactory::ArrayEveryLoopContinuation(Isolate* isolate) {
IteratingArrayBuiltinLoopContinuationDescriptor(isolate));
}
// static
Callable CodeFactory::ArrayReduceLoopContinuation(Isolate* isolate) {
return Callable(isolate->builtins()->ArrayReduceLoopContinuation(),
IteratingArrayBuiltinLoopContinuationDescriptor(isolate));
}
// static
Callable CodeFactory::FunctionPrototypeBind(Isolate* isolate) {
return Callable(isolate->builtins()->FunctionPrototypeBind(),
......
......@@ -185,6 +185,7 @@ class V8_EXPORT_PRIVATE CodeFactory final {
static Callable ArrayForEachLoopContinuation(Isolate* isolate);
static Callable ArraySomeLoopContinuation(Isolate* isolate);
static Callable ArrayEveryLoopContinuation(Isolate* isolate);
static Callable ArrayReduceLoopContinuation(Isolate* isolate);
static Callable FunctionPrototypeBind(Isolate* isolate);
static Callable PromiseHandleReject(Isolate* isolate);
};
......
......@@ -587,7 +587,7 @@ Node* CodeAssembler::CallStubR(const CallInterfaceDescriptor& descriptor,
#define INSTANTIATE(...) \
template V8_EXPORT_PRIVATE Node* CodeAssembler::CallStubR( \
const CallInterfaceDescriptor& descriptor, size_t, Node*, __VA_ARGS__);
REPEAT_1_TO_7(INSTANTIATE, Node*)
REPEAT_1_TO_8(INSTANTIATE, Node*)
#undef INSTANTIATE
Node* CodeAssembler::CallStubN(const CallInterfaceDescriptor& descriptor,
......@@ -766,7 +766,7 @@ bool CodeAssemblerVariable::IsBound() const { return impl_->value_ != nullptr; }
CodeAssemblerLabel::CodeAssemblerLabel(CodeAssembler* assembler,
size_t vars_count,
CodeAssemblerVariable** vars,
CodeAssemblerVariable* const* vars,
CodeAssemblerLabel::Type type)
: bound_(false),
merge_count_(0),
......
......@@ -462,8 +462,14 @@ class CodeAssemblerLabel {
: CodeAssemblerLabel(assembler, merged_variables.length(),
&(merged_variables[0]), type) {}
CodeAssemblerLabel(
CodeAssembler* assembler, size_t count, CodeAssemblerVariable** vars,
CodeAssembler* assembler, size_t count,
CodeAssemblerVariable* const* vars,
CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred);
CodeAssemblerLabel(
CodeAssembler* assembler,
std::initializer_list<CodeAssemblerVariable*> vars,
CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred)
: CodeAssemblerLabel(assembler, vars.size(), vars.begin(), type) {}
CodeAssemblerLabel(
CodeAssembler* assembler, CodeAssemblerVariable* merged_variable,
CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred)
......
......@@ -434,6 +434,7 @@ bool BuiltinHasNoSideEffect(Builtins::Name id) {
case Builtins::kArrayForEach:
case Builtins::kArrayEvery:
case Builtins::kArraySome:
case Builtins::kArrayReduce:
// Boolean bulitins.
case Builtins::kBooleanConstructor:
case Builtins::kBooleanPrototypeToString:
......
......@@ -408,6 +408,12 @@ testReduce("reduceRight", "ArrayWithNonElementPropertiesReduceRight", 6,
[5, 1, 0, arrayPlus, 6],
], arrayPlus, sum, 0);
// Test passing undefined as initial value (to test missing parameter
// detection).
[1].reduce((a, b) => { assertEquals(a, undefined); assertEquals(b, 1) },
undefined);
[1, 2].reduce((a, b) => { assertEquals(a, 1); assertEquals(b, 2); });
[1].reduce((a, b) => { assertTrue(false); });
// Test error conditions:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment