| Index: src/compiler/js-typed-lowering.cc
|
| diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc
|
| index 62861b3c1c70cd3d82fa1a14a464e5d186ad684c..5fa1d82fe96ae6cc2cff29acf9556f51b9cfe6d0 100644
|
| --- a/src/compiler/js-typed-lowering.cc
|
| +++ b/src/compiler/js-typed-lowering.cc
|
| @@ -1505,6 +1505,35 @@ Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) {
|
|
|
| namespace {
|
|
|
| +static const int kStubAndReceiver = 2;
|
| +
|
| +// Adapts arguments if required and returns the number of JS arguments. This
|
| +// is always the number of formal arguments if we're adapting, and the current
|
| +// arity otherwise.
|
| +int MaybeAdaptArguments(Isolate* isolate, JSGraph* jsgraph, Node* node,
|
| + int arity, SharedFunctionInfo* shared) {
|
| + const int formal_parameter_count = shared->internal_formal_parameter_count();
|
| + const bool should_adapt_arguments =
|
| + formal_parameter_count != SharedFunctionInfo::kDontAdaptArgumentsSentinel;
|
| +
|
| + if (!should_adapt_arguments) return arity;
|
| +
|
| + if (arity < formal_parameter_count) {
|
| + // Fewer actual than formal parameters, push the rest as undefined.
|
| + Node* undefined = jsgraph->UndefinedConstant();
|
| + for (int i = arity; i < formal_parameter_count; i++) {
|
| + node->InsertInput(jsgraph->zone(), arity + kStubAndReceiver, undefined);
|
| + }
|
| + } else if (arity > formal_parameter_count) {
|
| + // More actual than formal parameters, remove trailing parameters.
|
| + for (int i = formal_parameter_count; i < arity; i++) {
|
| + node->RemoveInput(formal_parameter_count + kStubAndReceiver);
|
| + }
|
| + }
|
| +
|
| + return formal_parameter_count;
|
| +}
|
| +
|
| void ReduceBuiltin(Isolate* isolate, JSGraph* jsgraph, Node* node,
|
| int builtin_index, int arity, CallDescriptor::Flags flags) {
|
| // Patch {node} to a direct CEntryStub call.
|
| @@ -1529,20 +1558,22 @@ void ReduceBuiltin(Isolate* isolate, JSGraph* jsgraph, Node* node,
|
|
|
| DCHECK(Builtins::HasCppImplementation(builtin_index));
|
|
|
| + Zone* zone = jsgraph->zone();
|
| Node* target = NodeProperties::GetValueInput(node, 0);
|
| Node* new_target = is_construct
|
| ? NodeProperties::GetValueInput(node, arity + 1)
|
| : jsgraph->UndefinedConstant();
|
|
|
| + Type* target_type = NodeProperties::GetType(target);
|
| + DCHECK(target_type->IsConstant());
|
| +
|
| // API and CPP builtins are implemented in C++, and we can inline both.
|
| // CPP builtins create a builtin exit frame, API builtins don't.
|
| const bool has_builtin_exit_frame = Builtins::IsCpp(builtin_index);
|
| -
|
| Node* stub = jsgraph->CEntryStubConstant(1, kDontSaveFPRegs, kArgvOnStack,
|
| has_builtin_exit_frame);
|
| node->ReplaceInput(0, stub);
|
|
|
| - Zone* zone = jsgraph->zone();
|
| if (is_construct) {
|
| // Unify representations between construct and call nodes.
|
| // Remove new target and add receiver as a stack parameter.
|
| @@ -1551,19 +1582,25 @@ void ReduceBuiltin(Isolate* isolate, JSGraph* jsgraph, Node* node,
|
| node->InsertInput(zone, 1, receiver);
|
| }
|
|
|
| - const int argc = arity + BuiltinArguments::kNumExtraArgsWithReceiver;
|
| + Handle<JSFunction> function =
|
| + Handle<JSFunction>::cast(target_type->AsConstant()->Value());
|
| + const int adapted_arity =
|
| + MaybeAdaptArguments(isolate, jsgraph, node, arity, function->shared());
|
| +
|
| + const int argc = adapted_arity + BuiltinArguments::kNumExtraArgsWithReceiver;
|
| Node* argc_node = jsgraph->Int32Constant(argc);
|
|
|
| - node->InsertInput(zone, arity + 2, argc_node);
|
| - node->InsertInput(zone, arity + 3, target);
|
| - node->InsertInput(zone, arity + 4, new_target);
|
| + int cursor = adapted_arity + kStubAndReceiver;
|
| + node->InsertInput(zone, cursor++, argc_node);
|
| + node->InsertInput(zone, cursor++, target);
|
| + node->InsertInput(zone, cursor++, new_target);
|
|
|
| Address entry = Builtins::CppEntryOf(builtin_index);
|
| ExternalReference entry_ref(ExternalReference(entry, isolate));
|
| Node* entry_node = jsgraph->ExternalConstant(entry_ref);
|
|
|
| - node->InsertInput(zone, arity + 5, entry_node);
|
| - node->InsertInput(zone, arity + 6, argc_node);
|
| + node->InsertInput(zone, cursor++, entry_node);
|
| + node->InsertInput(zone, cursor++, argc_node);
|
|
|
| static const int kReturnCount = 1;
|
| const char* debug_name = Builtins::name(builtin_index);
|
| @@ -1598,10 +1635,7 @@ Reduction JSTypedLowering::ReduceJSCallConstruct(Node* node) {
|
|
|
| CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
|
|
|
| - if (is_builtin && Builtins::HasCppImplementation(builtin_index) &&
|
| - (shared->internal_formal_parameter_count() == arity ||
|
| - shared->internal_formal_parameter_count() ==
|
| - SharedFunctionInfo::kDontAdaptArgumentsSentinel)) {
|
| + if (is_builtin && Builtins::HasCppImplementation(builtin_index)) {
|
| // Patch {node} to a direct CEntryStub call.
|
|
|
| // Load the context from the {target}.
|
| @@ -1713,10 +1747,7 @@ Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) {
|
|
|
| Node* new_target = jsgraph()->UndefinedConstant();
|
| Node* argument_count = jsgraph()->Int32Constant(arity);
|
| - if (is_builtin && Builtins::HasCppImplementation(builtin_index) &&
|
| - (shared->internal_formal_parameter_count() == arity ||
|
| - shared->internal_formal_parameter_count() ==
|
| - SharedFunctionInfo::kDontAdaptArgumentsSentinel)) {
|
| + if (is_builtin && Builtins::HasCppImplementation(builtin_index)) {
|
| // Patch {node} to a direct CEntryStub call.
|
| ReduceBuiltin(isolate(), jsgraph(), node, builtin_index, arity, flags);
|
| } else if (shared->internal_formal_parameter_count() == arity ||
|
|
|