Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: runtime/vm/flow_graph_compiler_arm.cc

Issue 19200002: Change resolving of instance methods to check early for name mismatch. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/dart_entry.cc ('k') | runtime/vm/flow_graph_compiler_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
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 861 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 const Address copy_addr(R6, R8, LSL, 2); 872 const Address copy_addr(R6, R8, LSL, 2);
873 __ Bind(&loop); 873 __ Bind(&loop);
874 __ ldr(IP, argument_addr); 874 __ ldr(IP, argument_addr);
875 __ str(IP, copy_addr); 875 __ str(IP, copy_addr);
876 __ Bind(&loop_condition); 876 __ Bind(&loop_condition);
877 __ subs(R8, R8, ShifterOperand(1)); 877 __ subs(R8, R8, ShifterOperand(1));
878 __ b(&loop, PL); 878 __ b(&loop, PL);
879 879
880 // Copy or initialize optional named arguments. 880 // Copy or initialize optional named arguments.
881 Label all_arguments_processed; 881 Label all_arguments_processed;
882 #ifdef DEBUG
883 const bool check_correct_named_args = true;
884 #else
885 const bool check_correct_named_args = function.IsClosureFunction();
886 #endif
882 if (num_opt_named_params > 0) { 887 if (num_opt_named_params > 0) {
883 // Start by alphabetically sorting the names of the optional parameters. 888 // Start by alphabetically sorting the names of the optional parameters.
884 LocalVariable** opt_param = new LocalVariable*[num_opt_named_params]; 889 LocalVariable** opt_param = new LocalVariable*[num_opt_named_params];
885 int* opt_param_position = new int[num_opt_named_params]; 890 int* opt_param_position = new int[num_opt_named_params];
886 for (int pos = num_fixed_params; pos < num_params; pos++) { 891 for (int pos = num_fixed_params; pos < num_params; pos++) {
887 LocalVariable* parameter = scope->VariableAt(pos); 892 LocalVariable* parameter = scope->VariableAt(pos);
888 const String& opt_param_name = parameter->name(); 893 const String& opt_param_name = parameter->name();
889 int i = pos - num_fixed_params; 894 int i = pos - num_fixed_params;
890 while (--i >= 0) { 895 while (--i >= 0) {
891 LocalVariable* param_i = opt_param[i]; 896 LocalVariable* param_i = opt_param[i];
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
939 // Assign R5 to fp[kFirstLocalSlotFromFp - param_pos]. 944 // Assign R5 to fp[kFirstLocalSlotFromFp - param_pos].
940 // We do not use the final allocation index of the variable here, i.e. 945 // We do not use the final allocation index of the variable here, i.e.
941 // scope->VariableAt(i)->index(), because captured variables still need 946 // scope->VariableAt(i)->index(), because captured variables still need
942 // to be copied to the context that is not yet allocated. 947 // to be copied to the context that is not yet allocated.
943 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos; 948 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos;
944 const Address param_addr(FP, computed_param_pos * kWordSize); 949 const Address param_addr(FP, computed_param_pos * kWordSize);
945 __ str(R5, param_addr); 950 __ str(R5, param_addr);
946 } 951 }
947 delete[] opt_param; 952 delete[] opt_param;
948 delete[] opt_param_position; 953 delete[] opt_param_position;
949 // Check that R6 now points to the null terminator in the array descriptor. 954 if (check_correct_named_args) {
950 __ ldr(R5, Address(R6, 0)); 955 // Check that R6 now points to the null terminator in the arguments
951 __ CompareImmediate(R5, reinterpret_cast<int32_t>(Object::null())); 956 // descriptor.
952 __ b(&all_arguments_processed, EQ); 957 __ ldr(R5, Address(R6, 0));
958 __ CompareImmediate(R5, reinterpret_cast<int32_t>(Object::null()));
959 __ b(&all_arguments_processed, EQ);
960 }
953 } else { 961 } else {
954 ASSERT(num_opt_pos_params > 0); 962 ASSERT(num_opt_pos_params > 0);
955 __ ldr(R8, 963 __ ldr(R8,
956 FieldAddress(R4, ArgumentsDescriptor::positional_count_offset())); 964 FieldAddress(R4, ArgumentsDescriptor::positional_count_offset()));
957 __ SmiUntag(R8); 965 __ SmiUntag(R8);
958 for (int i = 0; i < num_opt_pos_params; i++) { 966 for (int i = 0; i < num_opt_pos_params; i++) {
959 Label next_parameter; 967 Label next_parameter;
960 // Handle this optional positional parameter only if k or fewer positional 968 // Handle this optional positional parameter only if k or fewer positional
961 // arguments have been passed, where k is param_pos, the position of this 969 // arguments have been passed, where k is param_pos, the position of this
962 // optional parameter in the formal parameter list. 970 // optional parameter in the formal parameter list.
963 const int param_pos = num_fixed_params + i; 971 const int param_pos = num_fixed_params + i;
964 __ CompareImmediate(R8, param_pos); 972 __ CompareImmediate(R8, param_pos);
965 __ b(&next_parameter, GT); 973 __ b(&next_parameter, GT);
966 // Load R5 with default argument. 974 // Load R5 with default argument.
967 const Object& value = Object::ZoneHandle( 975 const Object& value = Object::ZoneHandle(
968 parsed_function().default_parameter_values().At(i)); 976 parsed_function().default_parameter_values().At(i));
969 __ LoadObject(R5, value); 977 __ LoadObject(R5, value);
970 // Assign R5 to fp[kFirstLocalSlotFromFp - param_pos]. 978 // Assign R5 to fp[kFirstLocalSlotFromFp - param_pos].
971 // We do not use the final allocation index of the variable here, i.e. 979 // We do not use the final allocation index of the variable here, i.e.
972 // scope->VariableAt(i)->index(), because captured variables still need 980 // scope->VariableAt(i)->index(), because captured variables still need
973 // to be copied to the context that is not yet allocated. 981 // to be copied to the context that is not yet allocated.
974 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos; 982 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos;
975 const Address param_addr(FP, computed_param_pos * kWordSize); 983 const Address param_addr(FP, computed_param_pos * kWordSize);
976 __ str(R5, param_addr); 984 __ str(R5, param_addr);
977 __ Bind(&next_parameter); 985 __ Bind(&next_parameter);
978 } 986 }
979 __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset())); 987 if (check_correct_named_args) {
980 __ SmiUntag(R7); 988 __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
981 // Check that R8 equals R7, i.e. no named arguments passed. 989 __ SmiUntag(R7);
982 __ cmp(R8, ShifterOperand(R7)); 990 // Check that R8 equals R7, i.e. no named arguments passed.
983 __ b(&all_arguments_processed, EQ); 991 __ cmp(R8, ShifterOperand(R7));
992 __ b(&all_arguments_processed, EQ);
993 }
984 } 994 }
985 995
986 __ Bind(&wrong_num_arguments); 996 __ Bind(&wrong_num_arguments);
987 // Invoke noSuchMethod function passing the original name of the function. 997 if (function.IsClosureFunction()) {
988 // If the function is a closure function, use "call" as the original name. 998 // Invoke noSuchMethod function passing "call" as the original name.
989 const String& name = String::Handle( 999 const int kNumArgsChecked = 1;
990 function.IsClosureFunction() ? Symbols::Call().raw() : function.name()); 1000 const ICData& ic_data = ICData::ZoneHandle(
991 const int kNumArgsChecked = 1; 1001 ICData::New(function, Symbols::Call(), Object::null_array(),
992 const ICData& ic_data = ICData::ZoneHandle( 1002 Isolate::kNoDeoptId, kNumArgsChecked));
993 ICData::New(function, name, Object::null_array(), 1003 __ LoadObject(R5, ic_data);
994 Isolate::kNoDeoptId, kNumArgsChecked)); 1004 __ LeaveDartFrame(); // The arguments are still on the stack.
995 __ LoadObject(R5, ic_data); 1005 __ Branch(&StubCode::CallNoSuchMethodFunctionLabel());
996 __ LeaveDartFrame(); // The arguments are still on the stack. 1006 // The noSuchMethod call may return to the caller, but not here.
997 __ Branch(&StubCode::CallNoSuchMethodFunctionLabel()); 1007 __ bkpt(0);
998 // The noSuchMethod call may return to the caller, but not here. 1008 } else if (check_correct_named_args) {
999 __ bkpt(0); 1009 __ Stop("Wrong arguments");
1010 }
1000 1011
1001 __ Bind(&all_arguments_processed); 1012 __ Bind(&all_arguments_processed);
1002 // Nullify originally passed arguments only after they have been copied and 1013 // Nullify originally passed arguments only after they have been copied and
1003 // checked, otherwise noSuchMethod would not see their original values. 1014 // checked, otherwise noSuchMethod would not see their original values.
1004 // This step can be skipped in case we decide that formal parameters are 1015 // This step can be skipped in case we decide that formal parameters are
1005 // implicitly final, since garbage collecting the unmodified value is not 1016 // implicitly final, since garbage collecting the unmodified value is not
1006 // an issue anymore. 1017 // an issue anymore.
1007 1018
1008 // R4 : arguments descriptor array. 1019 // R4 : arguments descriptor array.
1009 __ ldr(R8, FieldAddress(R4, ArgumentsDescriptor::count_offset())); 1020 __ ldr(R8, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
(...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after
1868 DRegister dreg = EvenDRegisterOf(reg); 1879 DRegister dreg = EvenDRegisterOf(reg);
1869 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex)); 1880 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex));
1870 } 1881 }
1871 1882
1872 1883
1873 #undef __ 1884 #undef __
1874 1885
1875 } // namespace dart 1886 } // namespace dart
1876 1887
1877 #endif // defined TARGET_ARCH_ARM 1888 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/dart_entry.cc ('k') | runtime/vm/flow_graph_compiler_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698