Index: runtime/vm/flow_graph_compiler_x64.cc |
=================================================================== |
--- runtime/vm/flow_graph_compiler_x64.cc (revision 25039) |
+++ runtime/vm/flow_graph_compiler_x64.cc (working copy) |
@@ -893,6 +893,11 @@ |
const Immediate& raw_null = |
Immediate(reinterpret_cast<intptr_t>(Object::null())); |
Label all_arguments_processed; |
+#ifdef DEBUG |
+ const bool check_correct_named_args = true; |
+#else |
+ const bool check_correct_named_args = function.IsClosureFunction(); |
+#endif |
if (num_opt_named_params > 0) { |
// Start by alphabetically sorting the names of the optional parameters. |
LocalVariable** opt_param = new LocalVariable*[num_opt_named_params]; |
@@ -960,9 +965,12 @@ |
} |
delete[] opt_param; |
delete[] opt_param_position; |
- // Check that RDI now points to the null terminator in the array descriptor. |
- __ cmpq(Address(RDI, 0), raw_null); |
- __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); |
+ if (check_correct_named_args) { |
+ // Check that RDI now points to the null terminator in the arguments |
+ // descriptor. |
+ __ cmpq(Address(RDI, 0), raw_null); |
+ __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); |
+ } |
} else { |
ASSERT(num_opt_pos_params > 0); |
__ movq(RCX, |
@@ -989,27 +997,30 @@ |
__ movq(param_addr, RAX); |
__ Bind(&next_parameter); |
} |
- __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
- __ SmiUntag(RBX); |
- // Check that RCX equals RBX, i.e. no named arguments passed. |
- __ cmpq(RCX, RBX); |
- __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); |
+ if (check_correct_named_args) { |
+ __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
+ __ SmiUntag(RBX); |
+ // Check that RCX equals RBX, i.e. no named arguments passed. |
+ __ cmpq(RCX, RBX); |
+ __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); |
+ } |
} |
__ Bind(&wrong_num_arguments); |
- // Invoke noSuchMethod function passing the original name of the function. |
- // If the function is a closure function, use "call" as the original name. |
- const String& name = String::Handle( |
- function.IsClosureFunction() ? Symbols::Call().raw() : function.name()); |
- const int kNumArgsChecked = 1; |
- const ICData& ic_data = ICData::ZoneHandle( |
- ICData::New(function, name, Object::null_array(), |
- Isolate::kNoDeoptId, kNumArgsChecked)); |
- __ LoadObject(RBX, ic_data); |
- __ LeaveFrame(); // The arguments are still on the stack. |
- __ jmp(&StubCode::CallNoSuchMethodFunctionLabel()); |
- // The noSuchMethod call may return to the caller, but not here. |
- __ int3(); |
+ if (function.IsClosureFunction()) { |
+ // Invoke noSuchMethod function passing "call" as the original name. |
+ const int kNumArgsChecked = 1; |
+ const ICData& ic_data = ICData::ZoneHandle( |
+ ICData::New(function, Symbols::Call(), Object::null_array(), |
+ Isolate::kNoDeoptId, kNumArgsChecked)); |
+ __ LoadObject(RBX, ic_data); |
+ __ LeaveFrame(); // The arguments are still on the stack. |
+ __ jmp(&StubCode::CallNoSuchMethodFunctionLabel()); |
+ // The noSuchMethod call may return to the caller, but not here. |
+ __ int3(); |
+ } else if (check_correct_named_args) { |
+ __ Stop("Wrong arguments"); |
+ } |
__ Bind(&all_arguments_processed); |
// Nullify originally passed arguments only after they have been copied and |