OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
7 | 7 |
8 #include "vm/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
9 | 9 |
10 #include "lib/error.h" | 10 #include "lib/error.h" |
(...skipping 887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
898 __ addu(T4, T1, T2); | 898 __ addu(T4, T1, T2); |
899 __ lw(T3, Address(T4, -kWordSize)); | 899 __ lw(T3, Address(T4, -kWordSize)); |
900 __ addiu(T2, T2, Immediate(-kWordSize)); | 900 __ addiu(T2, T2, Immediate(-kWordSize)); |
901 __ addu(T5, T0, T2); | 901 __ addu(T5, T0, T2); |
902 __ bgtz(T2, &loop); | 902 __ bgtz(T2, &loop); |
903 __ delay_slot()->sw(T3, Address(T5)); | 903 __ delay_slot()->sw(T3, Address(T5)); |
904 __ Bind(&loop_exit); | 904 __ Bind(&loop_exit); |
905 | 905 |
906 // Copy or initialize optional named arguments. | 906 // Copy or initialize optional named arguments. |
907 Label all_arguments_processed; | 907 Label all_arguments_processed; |
| 908 #ifdef DEBUG |
| 909 const bool check_correct_named_args = true; |
| 910 #else |
| 911 const bool check_correct_named_args = function.IsClosureFunction(); |
| 912 #endif |
908 if (num_opt_named_params > 0) { | 913 if (num_opt_named_params > 0) { |
909 __ Comment("There are named parameters"); | 914 __ Comment("There are named parameters"); |
910 // Start by alphabetically sorting the names of the optional parameters. | 915 // Start by alphabetically sorting the names of the optional parameters. |
911 LocalVariable** opt_param = new LocalVariable*[num_opt_named_params]; | 916 LocalVariable** opt_param = new LocalVariable*[num_opt_named_params]; |
912 int* opt_param_position = new int[num_opt_named_params]; | 917 int* opt_param_position = new int[num_opt_named_params]; |
913 for (int pos = num_fixed_params; pos < num_params; pos++) { | 918 for (int pos = num_fixed_params; pos < num_params; pos++) { |
914 LocalVariable* parameter = scope->VariableAt(pos); | 919 LocalVariable* parameter = scope->VariableAt(pos); |
915 const String& opt_param_name = parameter->name(); | 920 const String& opt_param_name = parameter->name(); |
916 int i = pos - num_fixed_params; | 921 int i = pos - num_fixed_params; |
917 while (--i >= 0) { | 922 while (--i >= 0) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
967 __ Bind(&assign_optional_parameter); | 972 __ Bind(&assign_optional_parameter); |
968 // Assign T3 to fp[kFirstLocalSlotFromFp - param_pos]. | 973 // Assign T3 to fp[kFirstLocalSlotFromFp - param_pos]. |
969 // We do not use the final allocation index of the variable here, i.e. | 974 // We do not use the final allocation index of the variable here, i.e. |
970 // scope->VariableAt(i)->index(), because captured variables still need | 975 // scope->VariableAt(i)->index(), because captured variables still need |
971 // to be copied to the context that is not yet allocated. | 976 // to be copied to the context that is not yet allocated. |
972 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos; | 977 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos; |
973 __ sw(T3, Address(FP, computed_param_pos * kWordSize)); | 978 __ sw(T3, Address(FP, computed_param_pos * kWordSize)); |
974 } | 979 } |
975 delete[] opt_param; | 980 delete[] opt_param; |
976 delete[] opt_param_position; | 981 delete[] opt_param_position; |
977 // Check that T0 now points to the null terminator in the array descriptor. | 982 if (check_correct_named_args) { |
978 __ lw(T3, Address(T0)); | 983 // Check that T0 now points to the null terminator in the arguments |
979 __ BranchEqual(T3, reinterpret_cast<int32_t>(Object::null()), | 984 // descriptor. |
980 &all_arguments_processed); | 985 __ lw(T3, Address(T0)); |
| 986 __ BranchEqual(T3, reinterpret_cast<int32_t>(Object::null()), |
| 987 &all_arguments_processed); |
| 988 } |
981 } else { | 989 } else { |
982 ASSERT(num_opt_pos_params > 0); | 990 ASSERT(num_opt_pos_params > 0); |
983 __ Comment("There are optional positional parameters"); | 991 __ Comment("There are optional positional parameters"); |
984 __ lw(T2, | 992 __ lw(T2, |
985 FieldAddress(S4, ArgumentsDescriptor::positional_count_offset())); | 993 FieldAddress(S4, ArgumentsDescriptor::positional_count_offset())); |
986 __ SmiUntag(T2); | 994 __ SmiUntag(T2); |
987 for (int i = 0; i < num_opt_pos_params; i++) { | 995 for (int i = 0; i < num_opt_pos_params; i++) { |
988 Label next_parameter; | 996 Label next_parameter; |
989 // Handle this optional positional parameter only if k or fewer positional | 997 // Handle this optional positional parameter only if k or fewer positional |
990 // arguments have been passed, where k is param_pos, the position of this | 998 // arguments have been passed, where k is param_pos, the position of this |
991 // optional parameter in the formal parameter list. | 999 // optional parameter in the formal parameter list. |
992 const int param_pos = num_fixed_params + i; | 1000 const int param_pos = num_fixed_params + i; |
993 __ BranchSignedGreater(T2, param_pos, &next_parameter); | 1001 __ BranchSignedGreater(T2, param_pos, &next_parameter); |
994 // Load T3 with default argument. | 1002 // Load T3 with default argument. |
995 const Object& value = Object::ZoneHandle( | 1003 const Object& value = Object::ZoneHandle( |
996 parsed_function().default_parameter_values().At(i)); | 1004 parsed_function().default_parameter_values().At(i)); |
997 __ LoadObject(T3, value); | 1005 __ LoadObject(T3, value); |
998 // Assign T3 to fp[kFirstLocalSlotFromFp - param_pos]. | 1006 // Assign T3 to fp[kFirstLocalSlotFromFp - param_pos]. |
999 // We do not use the final allocation index of the variable here, i.e. | 1007 // We do not use the final allocation index of the variable here, i.e. |
1000 // scope->VariableAt(i)->index(), because captured variables still need | 1008 // scope->VariableAt(i)->index(), because captured variables still need |
1001 // to be copied to the context that is not yet allocated. | 1009 // to be copied to the context that is not yet allocated. |
1002 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos; | 1010 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos; |
1003 __ sw(T3, Address(FP, computed_param_pos * kWordSize)); | 1011 __ sw(T3, Address(FP, computed_param_pos * kWordSize)); |
1004 __ Bind(&next_parameter); | 1012 __ Bind(&next_parameter); |
1005 } | 1013 } |
1006 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); | 1014 if (check_correct_named_args) { |
1007 __ SmiUntag(T1); | 1015 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); |
1008 // Check that T2 equals T1, i.e. no named arguments passed. | 1016 __ SmiUntag(T1); |
1009 __ beq(T2, T1, &all_arguments_processed); | 1017 // Check that T2 equals T1, i.e. no named arguments passed. |
| 1018 __ beq(T2, T1, &all_arguments_processed); |
| 1019 } |
1010 } | 1020 } |
1011 | 1021 |
1012 __ Bind(&wrong_num_arguments); | 1022 __ Bind(&wrong_num_arguments); |
1013 // Invoke noSuchMethod function passing the original name of the function. | 1023 if (function.IsClosureFunction()) { |
1014 // If the function is a closure function, use "call" as the original name. | 1024 // Invoke noSuchMethod function passing "call" as the original name. |
1015 const String& name = String::Handle( | 1025 const int kNumArgsChecked = 1; |
1016 function.IsClosureFunction() ? Symbols::Call().raw() : function.name()); | 1026 const ICData& ic_data = ICData::ZoneHandle( |
1017 const int kNumArgsChecked = 1; | 1027 ICData::New(function, Symbols::Call(), Object::null_array(), |
1018 const ICData& ic_data = ICData::ZoneHandle( | 1028 Isolate::kNoDeoptId, kNumArgsChecked)); |
1019 ICData::New(function, name, Object::null_array(), | 1029 __ LoadObject(S5, ic_data); |
1020 Isolate::kNoDeoptId, kNumArgsChecked)); | 1030 __ LeaveDartFrame(); // The arguments are still on the stack. |
1021 __ LoadObject(S5, ic_data); | 1031 __ Branch(&StubCode::CallNoSuchMethodFunctionLabel()); |
1022 __ LeaveDartFrame(); // The arguments are still on the stack. | 1032 // The noSuchMethod call may return to the caller, but not here. |
1023 __ Branch(&StubCode::CallNoSuchMethodFunctionLabel()); | 1033 __ break_(0); |
1024 // The noSuchMethod call may return to the caller, but not here. | 1034 } else if (check_correct_named_args) { |
1025 __ break_(0); | 1035 __ Stop("Wrong arguments"); |
| 1036 } |
1026 | 1037 |
1027 __ Bind(&all_arguments_processed); | 1038 __ Bind(&all_arguments_processed); |
1028 // Nullify originally passed arguments only after they have been copied and | 1039 // Nullify originally passed arguments only after they have been copied and |
1029 // checked, otherwise noSuchMethod would not see their original values. | 1040 // checked, otherwise noSuchMethod would not see their original values. |
1030 // This step can be skipped in case we decide that formal parameters are | 1041 // This step can be skipped in case we decide that formal parameters are |
1031 // implicitly final, since garbage collecting the unmodified value is not | 1042 // implicitly final, since garbage collecting the unmodified value is not |
1032 // an issue anymore. | 1043 // an issue anymore. |
1033 | 1044 |
1034 // S4 : arguments descriptor array. | 1045 // S4 : arguments descriptor array. |
1035 __ lw(T2, FieldAddress(S4, ArgumentsDescriptor::count_offset())); | 1046 __ lw(T2, FieldAddress(S4, ArgumentsDescriptor::count_offset())); |
(...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2001 __ AddImmediate(SP, kDoubleSize); | 2012 __ AddImmediate(SP, kDoubleSize); |
2002 } | 2013 } |
2003 | 2014 |
2004 | 2015 |
2005 #undef __ | 2016 #undef __ |
2006 | 2017 |
2007 | 2018 |
2008 } // namespace dart | 2019 } // namespace dart |
2009 | 2020 |
2010 #endif // defined TARGET_ARCH_MIPS | 2021 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |