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

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

Issue 1024563004: Compile implicit closures as dispatchers instead of duplicating the original method's code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 9 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
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 "platform/utils.h" 8 #include "platform/utils.h"
9 #include "vm/ast_transformer.h" 9 #include "vm/ast_transformer.h"
10 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
(...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); 853 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer);
854 CompilerStats::num_functions_compiled++; 854 CompilerStats::num_functions_compiled++;
855 ASSERT(isolate->long_jump_base()->IsSafeToJump()); 855 ASSERT(isolate->long_jump_base()->IsSafeToJump());
856 ASSERT(parsed_function != NULL); 856 ASSERT(parsed_function != NULL);
857 const Function& func = parsed_function->function(); 857 const Function& func = parsed_function->function();
858 const Script& script = Script::Handle(zone, func.script()); 858 const Script& script = Script::Handle(zone, func.script());
859 Parser parser(script, parsed_function, func.token_pos()); 859 Parser parser(script, parsed_function, func.token_pos());
860 SequenceNode* node_sequence = NULL; 860 SequenceNode* node_sequence = NULL;
861 Array& default_parameter_values = Array::ZoneHandle(zone, Array::null()); 861 Array& default_parameter_values = Array::ZoneHandle(zone, Array::null());
862 switch (func.kind()) { 862 switch (func.kind()) {
863 case RawFunction::kClosureFunction:
864 if (func.IsImplicitClosureFunction()) {
865 parser.SkipFunctionPreamble();
866 node_sequence =
867 parser.ParseImplicitClosure(func, &default_parameter_values);
868 break;
869 }
870 // Fall-through: Handle non-implicit closures.
863 case RawFunction::kRegularFunction: 871 case RawFunction::kRegularFunction:
864 case RawFunction::kClosureFunction:
865 case RawFunction::kGetterFunction: 872 case RawFunction::kGetterFunction:
866 case RawFunction::kSetterFunction: 873 case RawFunction::kSetterFunction:
867 case RawFunction::kConstructor: 874 case RawFunction::kConstructor:
868 // The call to a redirecting factory is redirected. 875 // The call to a redirecting factory is redirected.
869 ASSERT(!func.IsRedirectingFactory()); 876 ASSERT(!func.IsRedirectingFactory());
870 if (!func.IsImplicitConstructor()) { 877 if (!func.IsImplicitConstructor()) {
871 parser.SkipFunctionPreamble(); 878 parser.SkipFunctionPreamble();
872 } 879 }
873 node_sequence = parser.ParseFunc(func, &default_parameter_values); 880 node_sequence = parser.ParseFunc(func, &default_parameter_values);
874 break; 881 break;
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
1296 1303
1297 EnsureExpressionTemp(); 1304 EnsureExpressionTemp();
1298 StoreInstanceFieldNode* store_field = 1305 StoreInstanceFieldNode* store_field =
1299 new StoreInstanceFieldNode(ident_pos, receiver, field, value); 1306 new StoreInstanceFieldNode(ident_pos, receiver, field, value);
1300 current_block_->statements->Add(store_field); 1307 current_block_->statements->Add(store_field);
1301 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); 1308 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos));
1302 return CloseBlock(); 1309 return CloseBlock();
1303 } 1310 }
1304 1311
1305 1312
1313 SequenceNode* Parser::ParseImplicitClosure(const Function& func,
1314 Array* default_values) {
1315 TRACE_PARSER("ParseImplicitClosure");
1316
1317 intptr_t token_pos = func.token_pos();
Florian Schneider 2015/03/23 13:45:37 0 (Scanner::kNoSourcePos) does not work since it c
1318
1319 OpenFunctionBlock(func);
1320
1321 ParamList params;
1322
1323 params.AddFinalParameter(
1324 token_pos,
1325 &Symbols::ClosureParameter(),
1326 &Type::ZoneHandle(Type::DynamicType()));
1327
1328 const bool allow_explicit_default_values = true;
1329 ParseFormalParameterList(allow_explicit_default_values, false, &params);
hausner 2015/03/23 17:44:48 Can there be an implicit closure of a getter? If s
Florian Schneider 2015/03/24 09:19:38 Done. Added assertion and a comment.
1330 SetupDefaultsForOptionalParams(&params, default_values);
1331
1332 // Populate function scope with the formal parameters.
1333 LocalScope* scope = current_block_->scope;
1334 AddFormalParamsToScope(&params, scope);
1335
1336 ArgumentListNode* func_args = new ArgumentListNode(token_pos);
1337 if (!func.is_static()) {
1338 func_args->Add(LoadReceiver(token_pos));
1339 }
1340 // Skip implicit parameter at 0.
1341 for (intptr_t i = 1; i < func.NumParameters(); ++i) {
1342 func_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i)));
1343 }
1344
1345 if (func.HasOptionalNamedParameters()) {
1346 const Array& arg_names =
1347 Array::ZoneHandle(Array::New(func.NumOptionalParameters()));
1348 for (intptr_t i = 0; i < arg_names.Length(); ++i) {
1349 intptr_t index = func.num_fixed_parameters() + i;
1350 arg_names.SetAt(i, String::Handle(func.ParameterNameAt(index)));
1351 }
1352 func_args->set_names(arg_names);
1353 }
1354 const Function& parent = Function::ZoneHandle(func.parent_function());
1355 StaticCallNode* call = new StaticCallNode(token_pos, parent, func_args);
1356 ReturnNode* return_node = new ReturnNode(token_pos, call);
1357 current_block_->statements->Add(return_node);
1358 return CloseBlock();
1359 }
1360
1361
1306 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { 1362 SequenceNode* Parser::ParseMethodExtractor(const Function& func) {
1307 TRACE_PARSER("ParseMethodExtractor"); 1363 TRACE_PARSER("ParseMethodExtractor");
1308 ParamList params; 1364 ParamList params;
1309 1365
1310 const intptr_t ident_pos = func.token_pos(); 1366 const intptr_t ident_pos = func.token_pos();
1311 ASSERT(func.token_pos() == 0); 1367 ASSERT(func.token_pos() == 0);
1312 ASSERT(current_class().raw() == func.Owner()); 1368 ASSERT(current_class().raw() == func.Owner());
1313 params.AddReceiver(ReceiverType(current_class()), ident_pos); 1369 params.AddReceiver(ReceiverType(current_class()), ident_pos);
1314 ASSERT(func.num_fixed_parameters() == 1); // Receiver. 1370 ASSERT(func.num_fixed_parameters() == 1); // Receiver.
1315 ASSERT(!func.HasOptionalParameters()); 1371 ASSERT(!func.HasOptionalParameters());
(...skipping 11907 matching lines...) Expand 10 before | Expand all | Expand 10 after
13223 void Parser::SkipQualIdent() { 13279 void Parser::SkipQualIdent() {
13224 ASSERT(IsIdentifier()); 13280 ASSERT(IsIdentifier());
13225 ConsumeToken(); 13281 ConsumeToken();
13226 if (CurrentToken() == Token::kPERIOD) { 13282 if (CurrentToken() == Token::kPERIOD) {
13227 ConsumeToken(); // Consume the kPERIOD token. 13283 ConsumeToken(); // Consume the kPERIOD token.
13228 ExpectIdentifier("identifier expected after '.'"); 13284 ExpectIdentifier("identifier expected after '.'");
13229 } 13285 }
13230 } 13286 }
13231 13287
13232 } // namespace dart 13288 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698