Index: runtime/vm/flow_graph_compiler_arm.cc |
=================================================================== |
--- runtime/vm/flow_graph_compiler_arm.cc (revision 25002) |
+++ runtime/vm/flow_graph_compiler_arm.cc (working copy) |
@@ -879,6 +879,11 @@ |
// Copy or initialize optional named arguments. |
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]; |
@@ -946,10 +951,13 @@ |
} |
delete[] opt_param; |
delete[] opt_param_position; |
- // Check that R6 now points to the null terminator in the array descriptor. |
- __ ldr(R5, Address(R6, 0)); |
- __ CompareImmediate(R5, reinterpret_cast<int32_t>(Object::null())); |
- __ b(&all_arguments_processed, EQ); |
+ if (check_correct_named_args) { |
+ // Check that R6 now points to the null terminator in the arguments |
+ // descriptor. |
+ __ ldr(R5, Address(R6, 0)); |
+ __ CompareImmediate(R5, reinterpret_cast<int32_t>(Object::null())); |
+ __ b(&all_arguments_processed, EQ); |
+ } |
} else { |
ASSERT(num_opt_pos_params > 0); |
__ ldr(R8, |
@@ -976,27 +984,30 @@ |
__ str(R5, param_addr); |
__ Bind(&next_parameter); |
} |
- __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset())); |
- __ SmiUntag(R7); |
- // Check that R8 equals R7, i.e. no named arguments passed. |
- __ cmp(R8, ShifterOperand(R7)); |
- __ b(&all_arguments_processed, EQ); |
+ if (check_correct_named_args) { |
+ __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset())); |
+ __ SmiUntag(R7); |
+ // Check that R8 equals R7, i.e. no named arguments passed. |
+ __ cmp(R8, ShifterOperand(R7)); |
+ __ b(&all_arguments_processed, EQ); |
+ } |
} |
__ 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(R5, ic_data); |
- __ LeaveDartFrame(); // The arguments are still on the stack. |
- __ Branch(&StubCode::CallNoSuchMethodFunctionLabel()); |
- // The noSuchMethod call may return to the caller, but not here. |
- __ bkpt(0); |
+ 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(R5, ic_data); |
+ __ LeaveDartFrame(); // The arguments are still on the stack. |
+ __ Branch(&StubCode::CallNoSuchMethodFunctionLabel()); |
+ // The noSuchMethod call may return to the caller, but not here. |
+ __ bkpt(0); |
+ } else if (check_correct_named_args) { |
+ __ Stop("Wrong arguments"); |
+ } |
__ Bind(&all_arguments_processed); |
// Nullify originally passed arguments only after they have been copied and |