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

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

Issue 18750004: Faster invocation of fields as methods. (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/parser.h ('k') | runtime/vm/raw_object.h » ('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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/parser.h" 5 #include "vm/parser.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/bigint_operations.h" 8 #include "vm/bigint_operations.h"
9 #include "vm/class_finalizer.h" 9 #include "vm/class_finalizer.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 case RawFunction::kConstImplicitGetter: 769 case RawFunction::kConstImplicitGetter:
770 node_sequence = parser.ParseStaticConstGetter(func); 770 node_sequence = parser.ParseStaticConstGetter(func);
771 break; 771 break;
772 case RawFunction::kMethodExtractor: 772 case RawFunction::kMethodExtractor:
773 node_sequence = parser.ParseMethodExtractor(func); 773 node_sequence = parser.ParseMethodExtractor(func);
774 break; 774 break;
775 case RawFunction::kNoSuchMethodDispatcher: 775 case RawFunction::kNoSuchMethodDispatcher:
776 node_sequence = 776 node_sequence =
777 parser.ParseNoSuchMethodDispatcher(func, default_parameter_values); 777 parser.ParseNoSuchMethodDispatcher(func, default_parameter_values);
778 break; 778 break;
779 case RawFunction::kInvokeFieldDispatcher:
780 node_sequence =
781 parser.ParseInvokeFieldDispatcher(func, default_parameter_values);
782 break;
779 default: 783 default:
780 UNREACHABLE(); 784 UNREACHABLE();
781 } 785 }
782 786
783 if (!HasReturnNode(node_sequence)) { 787 if (!HasReturnNode(node_sequence)) {
784 // Add implicit return node. 788 // Add implicit return node.
785 node_sequence->Add(new ReturnNode(func.end_token_pos())); 789 node_sequence->Add(new ReturnNode(func.end_token_pos()));
786 } 790 }
787 if (parsed_function->has_expression_temp_var()) { 791 if (parsed_function->has_expression_temp_var()) {
788 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); 792 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var());
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
1101 Function::ZoneHandle(func.extracted_method_closure()), 1105 Function::ZoneHandle(func.extracted_method_closure()),
1102 load_receiver, 1106 load_receiver,
1103 NULL); 1107 NULL);
1104 1108
1105 ReturnNode* return_node = new ReturnNode(ident_pos, closure); 1109 ReturnNode* return_node = new ReturnNode(ident_pos, closure);
1106 current_block_->statements->Add(return_node); 1110 current_block_->statements->Add(return_node);
1107 return CloseBlock(); 1111 return CloseBlock();
1108 } 1112 }
1109 1113
1110 1114
1111 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func, 1115 void Parser::BuildDispatcherScope(const Function& func,
1112 Array& default_values) { 1116 const ArgumentsDescriptor& desc,
1113 TRACE_PARSER("ParseNoSuchMethodDispatcher"); 1117 Array& default_values) {
1114 1118 ParamList params;
1115 ASSERT(func.IsNoSuchMethodDispatcher()); 1119 // Receiver first.
1116 intptr_t token_pos = func.token_pos(); 1120 intptr_t token_pos = func.token_pos();
1117 ASSERT(func.token_pos() == 0);
1118 ASSERT(current_class().raw() == func.Owner());
1119
1120 ArgumentsDescriptor desc(Array::Handle(func.saved_args_desc()));
1121 ASSERT(desc.Count() > 0);
1122
1123 // Create parameter list. Receiver first.
1124 ParamList params;
1125 params.AddReceiver(ReceiverType(), token_pos); 1121 params.AddReceiver(ReceiverType(), token_pos);
1126
1127 // Remaining positional parameters. 1122 // Remaining positional parameters.
1128 intptr_t i = 1; 1123 intptr_t i = 1;
1129 for (; i < desc.PositionalCount(); ++i) { 1124 for (; i < desc.PositionalCount(); ++i) {
1130 ParamDesc p; 1125 ParamDesc p;
1131 char name[64]; 1126 char name[64];
1132 OS::SNPrint(name, 64, ":p%"Pd, i); 1127 OS::SNPrint(name, 64, ":p%"Pd, i);
1133 p.name = &String::ZoneHandle(Symbols::New(name)); 1128 p.name = &String::ZoneHandle(Symbols::New(name));
1134 p.type = &Type::ZoneHandle(Type::DynamicType()); 1129 p.type = &Type::ZoneHandle(Type::DynamicType());
1135 params.parameters->Add(p); 1130 params.parameters->Add(p);
1136 params.num_fixed_parameters++; 1131 params.num_fixed_parameters++;
1137 } 1132 }
1133 ASSERT(desc.PositionalCount() == params.num_fixed_parameters);
1134
1138 // Named parameters. 1135 // Named parameters.
1139 for (; i < desc.Count(); ++i) { 1136 for (; i < desc.Count(); ++i) {
1140 ParamDesc p; 1137 ParamDesc p;
1141 intptr_t index = i - desc.PositionalCount(); 1138 intptr_t index = i - desc.PositionalCount();
1142 p.name = &String::ZoneHandle(desc.NameAt(index)); 1139 p.name = &String::ZoneHandle(desc.NameAt(index));
1143 p.type = &Type::ZoneHandle(Type::DynamicType()); 1140 p.type = &Type::ZoneHandle(Type::DynamicType());
1144 p.default_value = &Object::ZoneHandle(); 1141 p.default_value = &Object::ZoneHandle();
1145 params.parameters->Add(p); 1142 params.parameters->Add(p);
1146 params.num_optional_parameters++; 1143 params.num_optional_parameters++;
1147 params.has_optional_named_parameters = true; 1144 params.has_optional_named_parameters = true;
1148 } 1145 }
1146 ASSERT(desc.NamedCount() == params.num_optional_parameters);
1149 1147
1150 SetupDefaultsForOptionalParams(&params, default_values); 1148 SetupDefaultsForOptionalParams(&params, default_values);
1151 1149
1152 // Build local scope for function and populate with the formal parameters. 1150 // Build local scope for function and populate with the formal parameters.
1153 OpenFunctionBlock(func); 1151 OpenFunctionBlock(func);
1154 LocalScope* scope = current_block_->scope; 1152 AddFormalParamsToScope(&params, current_block_->scope);
1155 AddFormalParamsToScope(&params, scope); 1153 }
1154
1155 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func,
1156 Array& default_values) {
1157 TRACE_PARSER("ParseNoSuchMethodDispatcher");
1158
1159 ASSERT(func.IsNoSuchMethodDispatcher());
1160 intptr_t token_pos = func.token_pos();
1161 ASSERT(func.token_pos() == 0);
1162 ASSERT(current_class().raw() == func.Owner());
1163
1164 ArgumentsDescriptor desc(Array::Handle(func.saved_args_desc()));
1165 ASSERT(desc.Count() > 0);
1166
1167 // Set up scope for this function.
1168 BuildDispatcherScope(func, desc, default_values);
1156 1169
1157 // Receiver is local 0. 1170 // Receiver is local 0.
1171 LocalScope* scope = current_block_->scope;
1158 ArgumentListNode* func_args = new ArgumentListNode(token_pos); 1172 ArgumentListNode* func_args = new ArgumentListNode(token_pos);
1159 for (intptr_t i = 0; i < desc.Count(); ++i) { 1173 for (intptr_t i = 0; i < desc.Count(); ++i) {
1160 func_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); 1174 func_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i)));
1161 } 1175 }
1162 1176
1163 if (params.num_optional_parameters > 0) { 1177 if (desc.NamedCount() > 0) {
1164 const Array& arg_names = 1178 const Array& arg_names =
1165 Array::ZoneHandle(Array::New(params.num_optional_parameters)); 1179 Array::ZoneHandle(Array::New(desc.NamedCount()));
1166 for (intptr_t i = 0; i < arg_names.Length(); ++i) { 1180 for (intptr_t i = 0; i < arg_names.Length(); ++i) {
1167 arg_names.SetAt(i, String::Handle(desc.NameAt(i))); 1181 arg_names.SetAt(i, String::Handle(desc.NameAt(i)));
1168 } 1182 }
1169 func_args->set_names(arg_names); 1183 func_args->set_names(arg_names);
1170 } 1184 }
1171 1185
1172 const String& func_name = String::ZoneHandle(func.name()); 1186 const String& func_name = String::ZoneHandle(func.name());
1173 ArgumentListNode* arguments = BuildNoSuchMethodArguments(token_pos, 1187 ArgumentListNode* arguments = BuildNoSuchMethodArguments(token_pos,
1174 func_name, 1188 func_name,
1175 *func_args); 1189 *func_args);
1176 const Function& no_such_method = Function::ZoneHandle( 1190 const Function& no_such_method = Function::ZoneHandle(
1177 Resolver::ResolveDynamicAnyArgs(Class::Handle(func.Owner()), 1191 Resolver::ResolveDynamicAnyArgs(Class::Handle(func.Owner()),
1178 Symbols::NoSuchMethod())); 1192 Symbols::NoSuchMethod()));
1179 StaticCallNode* call = 1193 StaticCallNode* call =
1180 new StaticCallNode(token_pos, no_such_method, arguments); 1194 new StaticCallNode(token_pos, no_such_method, arguments);
1181 1195
1182 1196
1183 ReturnNode* return_node = new ReturnNode(token_pos, call); 1197 ReturnNode* return_node = new ReturnNode(token_pos, call);
1184 current_block_->statements->Add(return_node); 1198 current_block_->statements->Add(return_node);
1185 return CloseBlock(); 1199 return CloseBlock();
1186 } 1200 }
1187 1201
1188 1202
1203 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func,
1204 Array& default_values) {
1205 TRACE_PARSER("ParseInvokeFieldDispatcher");
1206
1207 ASSERT(func.IsInvokeFieldDispatcher());
1208 intptr_t token_pos = func.token_pos();
1209 ASSERT(func.token_pos() == 0);
1210 ASSERT(current_class().raw() == func.Owner());
1211
1212 const Array& args_desc = Array::Handle(func.saved_args_desc());
1213 ArgumentsDescriptor desc(args_desc);
1214 ASSERT(desc.Count() > 0);
1215
1216 // Set up scope for this function.
1217 BuildDispatcherScope(func, desc, default_values);
1218
1219 // Receiver is local 0.
1220 LocalScope* scope = current_block_->scope;
1221 ArgumentListNode* no_args = new ArgumentListNode(token_pos);
1222 LoadLocalNode* receiver = new LoadLocalNode(token_pos, scope->VariableAt(0));
1223
1224 const String& name = String::Handle(func.name());
1225 const String& getter_name =
1226 String::ZoneHandle(Symbols::New(String::Handle(Field::GetterName(name))));
1227 InstanceCallNode* getter_call = new InstanceCallNode(token_pos,
1228 receiver,
1229 getter_name,
1230 no_args);
1231
1232 // Pass arguments 1..n to the closure call.
1233 ArgumentListNode* closure_args = new ArgumentListNode(token_pos);
1234 const Array& names = Array::Handle(Array::New(desc.NamedCount(), Heap::kOld));
1235 // Positional parameters.
1236 intptr_t i = 1;
1237 for (; i < desc.PositionalCount(); ++i) {
1238 closure_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i)));
1239 }
1240 // Named parameters.
1241 for (; i < desc.Count(); i++) {
1242 closure_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i)));
1243 intptr_t index = i - desc.PositionalCount();
1244 names.SetAt(index, String::Handle(desc.NameAt(index)));
1245 }
1246 closure_args->set_names(names);
1247
1248 EnsureSavedCurrentContext();
1249 ClosureCallNode* closure_call = new ClosureCallNode(token_pos,
1250 getter_call,
1251 closure_args);
1252
1253 ReturnNode* return_node = new ReturnNode(token_pos, closure_call);
1254 current_block_->statements->Add(return_node);
1255 return CloseBlock();
1256 }
1257
1258
1189 void Parser::SkipBlock() { 1259 void Parser::SkipBlock() {
1190 ASSERT(CurrentToken() == Token::kLBRACE); 1260 ASSERT(CurrentToken() == Token::kLBRACE);
1191 GrowableArray<Token::Kind> token_stack(8); 1261 GrowableArray<Token::Kind> token_stack(8);
1192 const intptr_t block_start_pos = TokenPos(); 1262 const intptr_t block_start_pos = TokenPos();
1193 bool is_match = true; 1263 bool is_match = true;
1194 bool unexpected_token_found = false; 1264 bool unexpected_token_found = false;
1195 Token::Kind token; 1265 Token::Kind token;
1196 intptr_t token_pos; 1266 intptr_t token_pos;
1197 do { 1267 do {
1198 token = CurrentToken(); 1268 token = CurrentToken();
(...skipping 8935 matching lines...) Expand 10 before | Expand all | Expand 10 after
10134 void Parser::SkipQualIdent() { 10204 void Parser::SkipQualIdent() {
10135 ASSERT(IsIdentifier()); 10205 ASSERT(IsIdentifier());
10136 ConsumeToken(); 10206 ConsumeToken();
10137 if (CurrentToken() == Token::kPERIOD) { 10207 if (CurrentToken() == Token::kPERIOD) {
10138 ConsumeToken(); // Consume the kPERIOD token. 10208 ConsumeToken(); // Consume the kPERIOD token.
10139 ExpectIdentifier("identifier expected after '.'"); 10209 ExpectIdentifier("identifier expected after '.'");
10140 } 10210 }
10141 } 10211 }
10142 10212
10143 } // namespace dart 10213 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698