Index: runtime/vm/flow_graph_compiler_ia32.cc |
=================================================================== |
--- runtime/vm/flow_graph_compiler_ia32.cc (revision 25039) |
+++ runtime/vm/flow_graph_compiler_ia32.cc (working copy) |
@@ -899,6 +899,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]; |
@@ -966,9 +971,12 @@ |
} |
delete[] opt_param; |
delete[] opt_param_position; |
- // Check that EDI now points to the null terminator in the array descriptor. |
- __ cmpl(Address(EDI, 0), raw_null); |
- __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); |
+ if (check_correct_named_args) { |
+ // Check that EDI now points to the null terminator in the arguments |
+ // descriptor. |
+ __ cmpl(Address(EDI, 0), raw_null); |
+ __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); |
+ } |
} else { |
ASSERT(num_opt_pos_params > 0); |
__ movl(ECX, |
@@ -995,27 +1003,30 @@ |
__ movl(param_addr, EAX); |
__ Bind(&next_parameter); |
} |
- __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
- __ SmiUntag(EBX); |
- // Check that ECX equals EBX, i.e. no named arguments passed. |
- __ cmpl(ECX, EBX); |
- __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); |
+ if (check_correct_named_args) { |
+ __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
+ __ SmiUntag(EBX); |
+ // Check that ECX equals EBX, i.e. no named arguments passed. |
+ __ cmpl(ECX, EBX); |
+ __ 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(ECX, 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(ECX, 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 |