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

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

Issue 10448059: Use temporary variable for StoreIndexed that returns a value. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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') | no next file » | 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 "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/class_finalizer.h" 8 #include "vm/class_finalizer.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/compiler_stats.h" 10 #include "vm/compiler_stats.h"
(...skipping 4821 matching lines...) Expand 10 before | Expand all | Expand 10 after
4832 AstNode* loop_var_assignment = NULL; 4832 AstNode* loop_var_assignment = NULL;
4833 if (loop_var != NULL) { 4833 if (loop_var != NULL) {
4834 // The for loop declares a new variable. Add it to the loop body scope. 4834 // The for loop declares a new variable. Add it to the loop body scope.
4835 current_block_->scope->AddVariable(loop_var); 4835 current_block_->scope->AddVariable(loop_var);
4836 loop_var_assignment = 4836 loop_var_assignment =
4837 new StoreLocalNode(loop_var_pos, *loop_var, iterator_next); 4837 new StoreLocalNode(loop_var_pos, *loop_var, iterator_next);
4838 } else { 4838 } else {
4839 AstNode* loop_var_primary = ResolveVarOrField(loop_var_pos, *loop_var_name); 4839 AstNode* loop_var_primary = ResolveVarOrField(loop_var_pos, *loop_var_name);
4840 ASSERT(!loop_var_primary->IsPrimaryNode()); 4840 ASSERT(!loop_var_primary->IsPrimaryNode());
4841 loop_var_assignment = 4841 loop_var_assignment =
4842 loop_var_primary->MakeAssignmentNode(iterator_next); 4842 CreateAssignmentNode(loop_var_primary, iterator_next);
4843 if (loop_var_assignment == NULL) { 4843 if (loop_var_assignment == NULL) {
4844 ErrorMsg(loop_var_pos, "variable or field '%s' is not assignable", 4844 ErrorMsg(loop_var_pos, "variable or field '%s' is not assignable",
4845 loop_var_name->ToCString()); 4845 loop_var_name->ToCString());
4846 } 4846 }
4847 } 4847 }
4848 current_block_->statements->Add(loop_var_assignment); 4848 current_block_->statements->Add(loop_var_assignment);
4849 4849
4850 // Now parse the for-in loop statement or block. 4850 // Now parse the for-in loop statement or block.
4851 if (CurrentToken() == Token::kLBRACE) { 4851 if (CurrentToken() == Token::kLBRACE) {
4852 ConsumeToken(); 4852 ConsumeToken();
(...skipping 1249 matching lines...) Expand 10 before | Expand all | Expand 10 after
6102 new LoadLocalNode(token_index, *temp), 6102 new LoadLocalNode(token_index, *temp),
6103 right_node->field_name()); 6103 right_node->field_name());
6104 } 6104 }
6105 *expr = right_node; 6105 *expr = right_node;
6106 return left_node; 6106 return left_node;
6107 } 6107 }
6108 return *expr; 6108 return *expr;
6109 } 6109 }
6110 6110
6111 6111
6112 // Ensure that the expression temp is allocated for nodes that may need it.
6113 AstNode* Parser::CreateAssignmentNode(AstNode* original, AstNode* rhs) {
6114 AstNode* result = original->MakeAssignmentNode(rhs);
6115 if ((result != NULL) && result->IsStoreIndexedNode()) {
6116 EnsureExpressionTemp();
6117 }
6118 return result;
6119 }
6120
6121
6112 AstNode* Parser::ParseExpr(bool require_compiletime_const) { 6122 AstNode* Parser::ParseExpr(bool require_compiletime_const) {
6113 TRACE_PARSER("ParseExpr"); 6123 TRACE_PARSER("ParseExpr");
6114 const intptr_t expr_pos = token_index_; 6124 const intptr_t expr_pos = token_index_;
6115 AstNode* expr = ParseConditionalExpr(); 6125 AstNode* expr = ParseConditionalExpr();
6116 if (!Token::IsAssignmentOperator(CurrentToken())) { 6126 if (!Token::IsAssignmentOperator(CurrentToken())) {
6117 if (require_compiletime_const) { 6127 if (require_compiletime_const) {
6118 expr = FoldConstExpr(expr_pos, expr); 6128 expr = FoldConstExpr(expr_pos, expr);
6119 } 6129 }
6120 return expr; 6130 return expr;
6121 } 6131 }
6122 // Assignment expressions. 6132 // Assignment expressions.
6123 Token::Kind assignment_op = CurrentToken(); 6133 Token::Kind assignment_op = CurrentToken();
6124 const intptr_t assignment_pos = token_index_; 6134 const intptr_t assignment_pos = token_index_;
6125 ConsumeToken(); 6135 ConsumeToken();
6126 const intptr_t right_expr_pos = token_index_; 6136 const intptr_t right_expr_pos = token_index_;
6127 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { 6137 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) {
6128 ErrorMsg(right_expr_pos, "expression must be a compile time constant"); 6138 ErrorMsg(right_expr_pos, "expression must be a compile time constant");
6129 } 6139 }
6130 AstNode* right_expr = ParseExpr(require_compiletime_const); 6140 AstNode* right_expr = ParseExpr(require_compiletime_const);
6131 AstNode* left_expr = expr; 6141 AstNode* left_expr = expr;
6132 if (assignment_op != Token::kASSIGN) { 6142 if (assignment_op != Token::kASSIGN) {
6133 // Compound assignment: store inputs with side effects into temp. locals. 6143 // Compound assignment: store inputs with side effects into temp. locals.
6134 left_expr = PrepareCompoundAssignmentNodes(&expr); 6144 left_expr = PrepareCompoundAssignmentNodes(&expr);
6135 } 6145 }
6136 right_expr = 6146 right_expr =
6137 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); 6147 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr);
6138 AstNode* assign_expr = left_expr->MakeAssignmentNode(right_expr); 6148 AstNode* assign_expr = CreateAssignmentNode(left_expr, right_expr);
6139 if (assign_expr == NULL) { 6149 if (assign_expr == NULL) {
6140 ErrorMsg(assignment_pos, 6150 ErrorMsg(assignment_pos,
6141 "left hand side of '%s' is not assignable", 6151 "left hand side of '%s' is not assignable",
6142 Token::Str(assignment_op)); 6152 Token::Str(assignment_op));
6143 } 6153 }
6144 return assign_expr; 6154 return assign_expr;
6145 } 6155 }
6146 6156
6147 6157
6148 LiteralNode* Parser::ParseConstExpr() { 6158 LiteralNode* Parser::ParseConstExpr() {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
6195 } 6205 }
6196 // Is prefix. 6206 // Is prefix.
6197 AstNode* left_expr = PrepareCompoundAssignmentNodes(&expr); 6207 AstNode* left_expr = PrepareCompoundAssignmentNodes(&expr);
6198 Token::Kind binary_op = 6208 Token::Kind binary_op =
6199 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; 6209 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB;
6200 BinaryOpNode* add = new BinaryOpNode( 6210 BinaryOpNode* add = new BinaryOpNode(
6201 op_pos, 6211 op_pos,
6202 binary_op, 6212 binary_op,
6203 expr, 6213 expr,
6204 new LiteralNode(op_pos, Smi::ZoneHandle(Smi::New(1)))); 6214 new LiteralNode(op_pos, Smi::ZoneHandle(Smi::New(1))));
6205 AstNode* store = left_expr->MakeAssignmentNode(add); 6215 AstNode* store = CreateAssignmentNode(left_expr, add);
6206 expr = store; 6216 expr = store;
6207 } else { 6217 } else {
6208 expr = ParsePostfixExpr(); 6218 expr = ParsePostfixExpr();
6209 } 6219 }
6210 return expr; 6220 return expr;
6211 } 6221 }
6212 6222
6213 6223
6214 ArgumentListNode* Parser::ParseActualParameters( 6224 ArgumentListNode* Parser::ParseActualParameters(
6215 ArgumentListNode* implicit_arguments, 6225 ArgumentListNode* implicit_arguments,
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
6360 ConsumeToken(); 6370 ConsumeToken();
6361 AstNode* value = ParseExpr(kAllowConst); 6371 AstNode* value = ParseExpr(kAllowConst);
6362 AstNode* load_access = 6372 AstNode* load_access =
6363 new InstanceGetterNode(call_pos, receiver, field_name); 6373 new InstanceGetterNode(call_pos, receiver, field_name);
6364 AstNode* left_load_access = load_access; 6374 AstNode* left_load_access = load_access;
6365 if (assignment_op != Token::kASSIGN) { 6375 if (assignment_op != Token::kASSIGN) {
6366 // Compound assignment: store inputs with side effects into temp. locals. 6376 // Compound assignment: store inputs with side effects into temp. locals.
6367 left_load_access = PrepareCompoundAssignmentNodes(&load_access); 6377 left_load_access = PrepareCompoundAssignmentNodes(&load_access);
6368 } 6378 }
6369 value = ExpandAssignableOp(call_pos, assignment_op, load_access, value); 6379 value = ExpandAssignableOp(call_pos, assignment_op, load_access, value);
6370 access = left_load_access->MakeAssignmentNode(value); 6380 access = CreateAssignmentNode(left_load_access, value);
6371 } else { 6381 } else {
6372 access = CallGetter(call_pos, receiver, field_name); 6382 access = CallGetter(call_pos, receiver, field_name);
6373 } 6383 }
6374 return access; 6384 return access;
6375 } 6385 }
6376 6386
6377 6387
6378 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, 6388 AstNode* Parser::GenerateStaticFieldLookup(const Field& field,
6379 intptr_t ident_pos) { 6389 intptr_t ident_pos) {
6380 // If the static field has an initializer, initialize the field at compile 6390 // If the static field has an initializer, initialize the field at compile
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
6443 // Field has been marked as final, report an error as the field 6453 // Field has been marked as final, report an error as the field
6444 // is not settable. 6454 // is not settable.
6445 ErrorMsg(ident_pos, 6455 ErrorMsg(ident_pos,
6446 "field '%s' is const static, cannot assign to it", 6456 "field '%s' is const static, cannot assign to it",
6447 field_name.ToCString()); 6457 field_name.ToCString());
6448 return access; 6458 return access;
6449 } 6459 }
6450 load_access = GenerateStaticFieldLookup(field, token_index_); 6460 load_access = GenerateStaticFieldLookup(field, token_index_);
6451 } 6461 }
6452 value = ExpandAssignableOp(call_pos, assignment_op, load_access, value); 6462 value = ExpandAssignableOp(call_pos, assignment_op, load_access, value);
6453 access = load_access->MakeAssignmentNode(value); 6463 access = CreateAssignmentNode(load_access, value);
6454 } else { // Not Token::IsAssignmentOperator(CurrentToken()). 6464 } else { // Not Token::IsAssignmentOperator(CurrentToken()).
6455 if (field.IsNull()) { 6465 if (field.IsNull()) {
6456 // No field, check if we have an explicit getter function. 6466 // No field, check if we have an explicit getter function.
6457 const String& getter_name = 6467 const String& getter_name =
6458 String::ZoneHandle(Field::GetterName(field_name)); 6468 String::ZoneHandle(Field::GetterName(field_name));
6459 const int kNumArguments = 0; // no arguments. 6469 const int kNumArguments = 0; // no arguments.
6460 const Array& kNoArgumentNames = Array::Handle(); 6470 const Array& kNoArgumentNames = Array::Handle();
6461 func = Resolver::ResolveStatic(cls, 6471 func = Resolver::ResolveStatic(cls,
6462 getter_name, 6472 getter_name,
6463 kNumArguments, 6473 kNumArguments,
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
6686 const LocalVariable& temp = GetIncrementTempLocal(); 6696 const LocalVariable& temp = GetIncrementTempLocal();
6687 AstNode* save = 6697 AstNode* save =
6688 new StoreLocalNode(postfix_expr_pos, temp, postfix_expr); 6698 new StoreLocalNode(postfix_expr_pos, temp, postfix_expr);
6689 Token::Kind binary_op = 6699 Token::Kind binary_op =
6690 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; 6700 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB;
6691 BinaryOpNode* add = new BinaryOpNode( 6701 BinaryOpNode* add = new BinaryOpNode(
6692 postfix_expr_pos, 6702 postfix_expr_pos,
6693 binary_op, 6703 binary_op,
6694 save, 6704 save,
6695 new LiteralNode(postfix_expr_pos, Smi::ZoneHandle(Smi::New(1)))); 6705 new LiteralNode(postfix_expr_pos, Smi::ZoneHandle(Smi::New(1))));
6696 AstNode* store = left_expr->MakeAssignmentNode(add); 6706 AstNode* store = CreateAssignmentNode(left_expr, add);
6697 LoadLocalNode* load_res = 6707 LoadLocalNode* load_res =
6698 new LoadLocalNode(postfix_expr_pos, temp, store); 6708 new LoadLocalNode(postfix_expr_pos, temp, store);
6699 return load_res; 6709 return load_res;
6700 } 6710 }
6701 return postfix_expr; 6711 return postfix_expr;
6702 } 6712 }
6703 6713
6704 6714
6705 // Resolve the given type and its type arguments from the given scope class 6715 // Resolve the given type and its type arguments from the given scope class
6706 // according to the given type finalization mode. 6716 // according to the given type finalization mode.
(...skipping 1799 matching lines...) Expand 10 before | Expand all | Expand 10 after
8506 void Parser::SkipQualIdent() { 8516 void Parser::SkipQualIdent() {
8507 ASSERT(IsIdentifier()); 8517 ASSERT(IsIdentifier());
8508 ConsumeToken(); 8518 ConsumeToken();
8509 if (CurrentToken() == Token::kPERIOD) { 8519 if (CurrentToken() == Token::kPERIOD) {
8510 ConsumeToken(); // Consume the kPERIOD token. 8520 ConsumeToken(); // Consume the kPERIOD token.
8511 ExpectIdentifier("identifier expected after '.'"); 8521 ExpectIdentifier("identifier expected after '.'");
8512 } 8522 }
8513 } 8523 }
8514 8524
8515 } // namespace dart 8525 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698