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

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

Issue 188703004: Fix invocation of closures via .call in the VM (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 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
« 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 "platform/utils.h" 8 #include "platform/utils.h"
9 #include "vm/bootstrap.h" 9 #include "vm/bootstrap.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 node_sequence = parser.ParseMethodExtractor(func); 803 node_sequence = parser.ParseMethodExtractor(func);
804 break; 804 break;
805 case RawFunction::kNoSuchMethodDispatcher: 805 case RawFunction::kNoSuchMethodDispatcher:
806 node_sequence = 806 node_sequence =
807 parser.ParseNoSuchMethodDispatcher(func, default_parameter_values); 807 parser.ParseNoSuchMethodDispatcher(func, default_parameter_values);
808 break; 808 break;
809 case RawFunction::kInvokeFieldDispatcher: 809 case RawFunction::kInvokeFieldDispatcher:
810 node_sequence = 810 node_sequence =
811 parser.ParseInvokeFieldDispatcher(func, default_parameter_values); 811 parser.ParseInvokeFieldDispatcher(func, default_parameter_values);
812 break; 812 break;
813 case RawFunction::kInvokeClosureDispatcher:
814 node_sequence =
815 parser.ParseInvokeClosureDispatcher(func, default_parameter_values);
816 break;
813 default: 817 default:
814 UNREACHABLE(); 818 UNREACHABLE();
815 } 819 }
816 820
817 if (!HasReturnNode(node_sequence)) { 821 if (!HasReturnNode(node_sequence)) {
818 // Add implicit return node. 822 // Add implicit return node.
819 node_sequence->Add(new ReturnNode(func.end_token_pos())); 823 node_sequence->Add(new ReturnNode(func.end_token_pos()));
820 } 824 }
821 if (parsed_function->has_expression_temp_var()) { 825 if (parsed_function->has_expression_temp_var()) {
822 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); 826 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var());
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after
1398 ClosureCallNode* closure_call = new ClosureCallNode(token_pos, 1402 ClosureCallNode* closure_call = new ClosureCallNode(token_pos,
1399 getter_call, 1403 getter_call,
1400 closure_args); 1404 closure_args);
1401 1405
1402 ReturnNode* return_node = new ReturnNode(token_pos, closure_call); 1406 ReturnNode* return_node = new ReturnNode(token_pos, closure_call);
1403 current_block_->statements->Add(return_node); 1407 current_block_->statements->Add(return_node);
1404 return CloseBlock(); 1408 return CloseBlock();
1405 } 1409 }
1406 1410
1407 1411
1412 SequenceNode* Parser::ParseInvokeClosureDispatcher(const Function& func,
1413 Array& default_values) {
1414 TRACE_PARSER("ParseInvokeClosureDispatcher");
1415
1416 ASSERT(func.IsInvokeClosureDispatcher());
1417 intptr_t token_pos = func.token_pos();
1418 ASSERT(func.token_pos() == 0);
1419 ASSERT(current_class().raw() == func.Owner());
1420
1421 const Array& args_desc = Array::Handle(func.saved_args_desc());
1422 ArgumentsDescriptor desc(args_desc);
1423 ASSERT(desc.Count() > 0);
1424
1425 // Set up scope for this function.
1426 BuildDispatcherScope(func, desc, default_values);
1427
1428 // Receiver is local 0.
1429 LocalScope* scope = current_block_->scope;
1430 LoadLocalNode* receiver = new LoadLocalNode(token_pos, scope->VariableAt(0));
1431
1432 // Pass arguments 1..n to the closure call.
1433 ArgumentListNode* closure_args = new ArgumentListNode(token_pos);
1434 const Array& names = Array::Handle(Array::New(desc.NamedCount(), Heap::kOld));
1435 // Positional parameters.
1436 intptr_t i = 1;
1437 for (; i < desc.PositionalCount(); ++i) {
1438 closure_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i)));
1439 }
1440 // Named parameters.
1441 for (; i < desc.Count(); i++) {
1442 closure_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i)));
1443 intptr_t index = i - desc.PositionalCount();
1444 names.SetAt(index, String::Handle(desc.NameAt(index)));
1445 }
1446 closure_args->set_names(names);
1447
1448 EnsureSavedCurrentContext();
1449 ClosureCallNode* closure_call = new ClosureCallNode(token_pos,
1450 receiver,
1451 closure_args);
1452
1453 ReturnNode* return_node = new ReturnNode(token_pos, closure_call);
1454 current_block_->statements->Add(return_node);
1455 return CloseBlock();
1456 }
1457
1458
1408 void Parser::SkipBlock() { 1459 void Parser::SkipBlock() {
1409 ASSERT(CurrentToken() == Token::kLBRACE); 1460 ASSERT(CurrentToken() == Token::kLBRACE);
1410 GrowableArray<Token::Kind> token_stack(8); 1461 GrowableArray<Token::Kind> token_stack(8);
1411 // Adding the first kLBRACE here, because it will be consumed in the loop 1462 // Adding the first kLBRACE here, because it will be consumed in the loop
1412 // right away. 1463 // right away.
1413 token_stack.Add(CurrentToken()); 1464 token_stack.Add(CurrentToken());
1414 const intptr_t block_start_pos = TokenPos(); 1465 const intptr_t block_start_pos = TokenPos();
1415 bool is_match = true; 1466 bool is_match = true;
1416 bool unexpected_token_found = false; 1467 bool unexpected_token_found = false;
1417 Token::Kind token; 1468 Token::Kind token;
(...skipping 9361 matching lines...) Expand 10 before | Expand all | Expand 10 after
10779 void Parser::SkipQualIdent() { 10830 void Parser::SkipQualIdent() {
10780 ASSERT(IsIdentifier()); 10831 ASSERT(IsIdentifier());
10781 ConsumeToken(); 10832 ConsumeToken();
10782 if (CurrentToken() == Token::kPERIOD) { 10833 if (CurrentToken() == Token::kPERIOD) {
10783 ConsumeToken(); // Consume the kPERIOD token. 10834 ConsumeToken(); // Consume the kPERIOD token.
10784 ExpectIdentifier("identifier expected after '.'"); 10835 ExpectIdentifier("identifier expected after '.'");
10785 } 10836 }
10786 } 10837 }
10787 10838
10788 } // namespace dart 10839 } // 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