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 { ...@@ -216,6 +216,8 @@ class Genesis BASE_EMBEDDED {
HARMONY_SHIPPING(DECLARE_FEATURE_INITIALIZATION) HARMONY_SHIPPING(DECLARE_FEATURE_INITIALIZATION)
#undef DECLARE_FEATURE_INITIALIZATION #undef DECLARE_FEATURE_INITIALIZATION
void InstallOneBuiltinFunction(const char* object, const char* method,
Builtins::Name name);
void InitializeGlobal_enable_fast_array_builtins(); void InitializeGlobal_enable_fast_array_builtins();
Handle<JSFunction> InstallArrayBuffer(Handle<JSObject> target, Handle<JSFunction> InstallArrayBuffer(Handle<JSObject> target,
...@@ -3664,63 +3666,39 @@ void InstallPublicSymbol(Factory* factory, Handle<Context> native_context, ...@@ -3664,63 +3666,39 @@ void InstallPublicSymbol(Factory* factory, Handle<Context> native_context,
JSObject::AddProperty(symbol, name_string, value, attributes); JSObject::AddProperty(symbol, name_string, value, attributes);
} }
void Genesis::InitializeGlobal_enable_fast_array_builtins() { void Genesis::InstallOneBuiltinFunction(const char* object_name,
if (!FLAG_enable_fast_array_builtins) return; const char* method_name,
Builtins::Name builtin_name) {
Handle<JSGlobalObject> global(native_context()->global_object()); Handle<JSGlobalObject> global(native_context()->global_object());
Isolate* isolate = global->GetIsolate(); Isolate* isolate = global->GetIsolate();
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
LookupIterator it1(global, factory->NewStringFromAsciiChecked("Array"), LookupIterator it1(global, factory->NewStringFromAsciiChecked(object_name),
LookupIterator::OWN_SKIP_INTERCEPTOR); LookupIterator::OWN_SKIP_INTERCEPTOR);
Handle<Object> array_object = Object::GetProperty(&it1).ToHandleChecked(); Handle<Object> object = Object::GetProperty(&it1).ToHandleChecked();
LookupIterator it2(array_object, LookupIterator it2(object, factory->NewStringFromAsciiChecked("prototype"),
factory->NewStringFromAsciiChecked("prototype"),
LookupIterator::OWN_SKIP_INTERCEPTOR); LookupIterator::OWN_SKIP_INTERCEPTOR);
Handle<Object> array_prototype = Object::GetProperty(&it2).ToHandleChecked(); Handle<Object> prototype = Object::GetProperty(&it2).ToHandleChecked();
LookupIterator it3(array_prototype, LookupIterator it3(prototype, factory->NewStringFromAsciiChecked(method_name),
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::OWN_SKIP_INTERCEPTOR); LookupIterator::OWN_SKIP_INTERCEPTOR);
Handle<Object> some_function = Object::GetProperty(&it5).ToHandleChecked(); Handle<Object> function = Object::GetProperty(&it3).ToHandleChecked();
Handle<JSFunction>::cast(some_function) Handle<JSFunction>::cast(function)->set_code(
->set_code(isolate->builtins()->builtin(Builtins::kArraySome)); isolate->builtins()->builtin(builtin_name));
Handle<JSFunction>::cast(some_function) Handle<JSFunction>::cast(function)->shared()->set_code(
->shared() isolate->builtins()->builtin(builtin_name));
->set_code(isolate->builtins()->builtin(Builtins::kArraySome)); }
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) { if (FLAG_experimental_array_builtins) {
LookupIterator it6(array_prototype, InstallOneBuiltinFunction("Array", "filter", Builtins::kArrayFilter);
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));
} }
} }
......
This diff is collapsed.
...@@ -296,6 +296,9 @@ class Isolate; ...@@ -296,6 +296,9 @@ class Isolate;
/* ES6 #sec-array.prototype.filter */ \ /* ES6 #sec-array.prototype.filter */ \
TFJ(ArrayFilterLoopContinuation, 6) \ TFJ(ArrayFilterLoopContinuation, 6) \
TFJ(ArrayFilter, 2, kCallbackFn, kThisArg) \ TFJ(ArrayFilter, 2, kCallbackFn, kThisArg) \
/* ES6 #sec-array.prototype.reduce */ \
TFJ(ArrayReduceLoopContinuation, 6) \
TFJ(ArrayReduce, 2, kCallbackFn, kInitialValue) \
/* ES6 #sec-array.prototype.entries */ \ /* ES6 #sec-array.prototype.entries */ \
TFJ(ArrayPrototypeEntries, 0) \ TFJ(ArrayPrototypeEntries, 0) \
/* ES6 #sec-array.prototype.keys */ \ /* ES6 #sec-array.prototype.keys */ \
......
...@@ -512,6 +512,12 @@ Callable CodeFactory::ArrayEveryLoopContinuation(Isolate* isolate) { ...@@ -512,6 +512,12 @@ Callable CodeFactory::ArrayEveryLoopContinuation(Isolate* isolate) {
IteratingArrayBuiltinLoopContinuationDescriptor(isolate)); IteratingArrayBuiltinLoopContinuationDescriptor(isolate));
} }
// static
Callable CodeFactory::ArrayReduceLoopContinuation(Isolate* isolate) {
return Callable(isolate->builtins()->ArrayReduceLoopContinuation(),
IteratingArrayBuiltinLoopContinuationDescriptor(isolate));
}
// static // static
Callable CodeFactory::FunctionPrototypeBind(Isolate* isolate) { Callable CodeFactory::FunctionPrototypeBind(Isolate* isolate) {
return Callable(isolate->builtins()->FunctionPrototypeBind(), return Callable(isolate->builtins()->FunctionPrototypeBind(),
......
...@@ -185,6 +185,7 @@ class V8_EXPORT_PRIVATE CodeFactory final { ...@@ -185,6 +185,7 @@ class V8_EXPORT_PRIVATE CodeFactory final {
static Callable ArrayForEachLoopContinuation(Isolate* isolate); static Callable ArrayForEachLoopContinuation(Isolate* isolate);
static Callable ArraySomeLoopContinuation(Isolate* isolate); static Callable ArraySomeLoopContinuation(Isolate* isolate);
static Callable ArrayEveryLoopContinuation(Isolate* isolate); static Callable ArrayEveryLoopContinuation(Isolate* isolate);
static Callable ArrayReduceLoopContinuation(Isolate* isolate);
static Callable FunctionPrototypeBind(Isolate* isolate); static Callable FunctionPrototypeBind(Isolate* isolate);
static Callable PromiseHandleReject(Isolate* isolate); static Callable PromiseHandleReject(Isolate* isolate);
}; };
......
...@@ -587,7 +587,7 @@ Node* CodeAssembler::CallStubR(const CallInterfaceDescriptor& descriptor, ...@@ -587,7 +587,7 @@ Node* CodeAssembler::CallStubR(const CallInterfaceDescriptor& descriptor,
#define INSTANTIATE(...) \ #define INSTANTIATE(...) \
template V8_EXPORT_PRIVATE Node* CodeAssembler::CallStubR( \ template V8_EXPORT_PRIVATE Node* CodeAssembler::CallStubR( \
const CallInterfaceDescriptor& descriptor, size_t, Node*, __VA_ARGS__); const CallInterfaceDescriptor& descriptor, size_t, Node*, __VA_ARGS__);
REPEAT_1_TO_7(INSTANTIATE, Node*) REPEAT_1_TO_8(INSTANTIATE, Node*)
#undef INSTANTIATE #undef INSTANTIATE
Node* CodeAssembler::CallStubN(const CallInterfaceDescriptor& descriptor, Node* CodeAssembler::CallStubN(const CallInterfaceDescriptor& descriptor,
...@@ -766,7 +766,7 @@ bool CodeAssemblerVariable::IsBound() const { return impl_->value_ != nullptr; } ...@@ -766,7 +766,7 @@ bool CodeAssemblerVariable::IsBound() const { return impl_->value_ != nullptr; }
CodeAssemblerLabel::CodeAssemblerLabel(CodeAssembler* assembler, CodeAssemblerLabel::CodeAssemblerLabel(CodeAssembler* assembler,
size_t vars_count, size_t vars_count,
CodeAssemblerVariable** vars, CodeAssemblerVariable* const* vars,
CodeAssemblerLabel::Type type) CodeAssemblerLabel::Type type)
: bound_(false), : bound_(false),
merge_count_(0), merge_count_(0),
......
...@@ -462,8 +462,14 @@ class CodeAssemblerLabel { ...@@ -462,8 +462,14 @@ class CodeAssemblerLabel {
: CodeAssemblerLabel(assembler, merged_variables.length(), : CodeAssemblerLabel(assembler, merged_variables.length(),
&(merged_variables[0]), type) {} &(merged_variables[0]), type) {}
CodeAssemblerLabel( CodeAssemblerLabel(
CodeAssembler* assembler, size_t count, CodeAssemblerVariable** vars, CodeAssembler* assembler, size_t count,
CodeAssemblerVariable* const* vars,
CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred); 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( CodeAssemblerLabel(
CodeAssembler* assembler, CodeAssemblerVariable* merged_variable, CodeAssembler* assembler, CodeAssemblerVariable* merged_variable,
CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred) CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred)
......
...@@ -434,6 +434,7 @@ bool BuiltinHasNoSideEffect(Builtins::Name id) { ...@@ -434,6 +434,7 @@ bool BuiltinHasNoSideEffect(Builtins::Name id) {
case Builtins::kArrayForEach: case Builtins::kArrayForEach:
case Builtins::kArrayEvery: case Builtins::kArrayEvery:
case Builtins::kArraySome: case Builtins::kArraySome:
case Builtins::kArrayReduce:
// Boolean bulitins. // Boolean bulitins.
case Builtins::kBooleanConstructor: case Builtins::kBooleanConstructor:
case Builtins::kBooleanPrototypeToString: case Builtins::kBooleanPrototypeToString:
......
...@@ -408,6 +408,12 @@ testReduce("reduceRight", "ArrayWithNonElementPropertiesReduceRight", 6, ...@@ -408,6 +408,12 @@ testReduce("reduceRight", "ArrayWithNonElementPropertiesReduceRight", 6,
[5, 1, 0, arrayPlus, 6], [5, 1, 0, arrayPlus, 6],
], arrayPlus, sum, 0); ], 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: // 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