| Index: runtime/vm/parser.cc
|
| ===================================================================
|
| --- runtime/vm/parser.cc (revision 23243)
|
| +++ runtime/vm/parser.cc (working copy)
|
| @@ -116,13 +116,6 @@
|
| }
|
|
|
|
|
| -LocalVariable* ParsedFunction::CreateArrayLiteralVar(intptr_t token_pos) {
|
| - return new LocalVariable(token_pos,
|
| - Symbols::ArrayLiteralVar(),
|
| - Type::ZoneHandle(Type::ArrayType()));
|
| -}
|
| -
|
| -
|
| void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) {
|
| ASSERT(node_sequence_ == NULL);
|
| ASSERT(node_sequence != NULL);
|
| @@ -788,10 +781,6 @@
|
| UNREACHABLE();
|
| }
|
|
|
| - parsed_function->set_array_literal_var(
|
| - ParsedFunction::CreateArrayLiteralVar(func.token_pos()));
|
| - node_sequence->scope()->AddVariable(parsed_function->array_literal_var());
|
| -
|
| if (!HasReturnNode(node_sequence)) {
|
| // Add implicit return node.
|
| node_sequence->Add(new ReturnNode(func.end_token_pos()));
|
| @@ -1409,18 +1398,6 @@
|
| }
|
|
|
|
|
| -LocalVariable* Parser::BuildArrayTempLocal(intptr_t token_pos) {
|
| - char name[64];
|
| - OS::SNPrint(name, 64, ":arrlit%"Pd, token_pos);
|
| - LocalVariable* temp =
|
| - new LocalVariable(token_pos,
|
| - String::ZoneHandle(Symbols::New(name)),
|
| - Type::ZoneHandle(Type::ArrayType()));
|
| - current_block_->scope->AddVariable(temp);
|
| - return temp;
|
| -}
|
| -
|
| -
|
| StaticCallNode* Parser::BuildInvocationMirrorAllocation(
|
| intptr_t call_pos,
|
| const String& function_name,
|
| @@ -1438,9 +1415,8 @@
|
| arguments->Add(new LiteralNode(args_pos, args_descriptor));
|
| // The third argument is an array containing the original function arguments,
|
| // including the receiver.
|
| - ArrayNode* args_array = new ArrayNode(
|
| - args_pos, Type::ZoneHandle(Type::ArrayType()),
|
| - *BuildArrayTempLocal(call_pos));
|
| + ArrayNode* args_array =
|
| + new ArrayNode(args_pos, Type::ZoneHandle(Type::ArrayType()));
|
| for (intptr_t i = 0; i < function_args.length(); i++) {
|
| args_array->AddElement(function_args.NodeAt(i));
|
| }
|
| @@ -7028,71 +7004,42 @@
|
| }
|
|
|
|
|
| -// A compound assignment consists of a store and a load part. In order
|
| -// to control inputs with potential side effects, the store part stores any
|
| -// side effect creating inputs into locals. The load part reads then from
|
| -// those locals. If expr may have side effects, it will be split into two new
|
| -// left and right nodes. 'expr' becomes the right node, left node is returned as
|
| -// result.
|
| -AstNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) {
|
| +LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) {
|
| AstNode* node = *expr;
|
| + intptr_t token_pos = node->token_pos();
|
| + LetNode* result = new LetNode(token_pos);
|
| if (node->IsLoadIndexedNode()) {
|
| - LoadIndexedNode* left_node = node->AsLoadIndexedNode();
|
| - LoadIndexedNode* right_node = left_node;
|
| - intptr_t token_pos = node->token_pos();
|
| - node = NULL; // Do not use it.
|
| - if (!IsSimpleLocalOrLiteralNode(left_node->array())) {
|
| - LocalVariable* temp =
|
| - CreateTempConstVariable(token_pos, "lia");
|
| - StoreLocalNode* save =
|
| - new StoreLocalNode(token_pos, temp, left_node->array());
|
| - left_node = new LoadIndexedNode(token_pos,
|
| - save,
|
| - left_node->index_expr(),
|
| - left_node->super_class());
|
| - right_node = new LoadIndexedNode(token_pos,
|
| - new LoadLocalNode(token_pos, temp),
|
| - right_node->index_expr(),
|
| - right_node->super_class());
|
| + LoadIndexedNode* load_indexed = node->AsLoadIndexedNode();
|
| + AstNode* array = load_indexed->array();
|
| + AstNode* index = load_indexed->index_expr();
|
| + if (!IsSimpleLocalOrLiteralNode(load_indexed->array())) {
|
| + LocalVariable* t0 = result->AddInitializer(load_indexed->array());
|
| + array = new LoadLocalNode(token_pos, t0);
|
| }
|
| - if (!IsSimpleLocalOrLiteralNode(left_node->index_expr())) {
|
| - LocalVariable* temp =
|
| - CreateTempConstVariable(token_pos, "lix");
|
| - StoreLocalNode* save =
|
| - new StoreLocalNode(token_pos, temp, left_node->index_expr());
|
| - left_node = new LoadIndexedNode(token_pos,
|
| - left_node->array(),
|
| - save,
|
| - left_node->super_class());
|
| - right_node = new LoadIndexedNode(token_pos,
|
| - right_node->array(),
|
| - new LoadLocalNode(token_pos, temp),
|
| - right_node->super_class());
|
| + if (!IsSimpleLocalOrLiteralNode(load_indexed->index_expr())) {
|
| + LocalVariable* t1 = result->AddInitializer(
|
| + load_indexed->index_expr());
|
| + index = new LoadLocalNode(token_pos, t1);
|
| }
|
| - *expr = right_node;
|
| - return left_node;
|
| + *expr = new LoadIndexedNode(token_pos,
|
| + array,
|
| + index,
|
| + load_indexed->super_class());
|
| + return result;
|
| }
|
| if (node->IsInstanceGetterNode()) {
|
| - InstanceGetterNode* left_node = node->AsInstanceGetterNode();
|
| - InstanceGetterNode* right_node = left_node;
|
| - intptr_t token_pos = node->token_pos();
|
| - node = NULL; // Do not use it.
|
| - if (!IsSimpleLocalOrLiteralNode(left_node->receiver())) {
|
| - LocalVariable* temp =
|
| - CreateTempConstVariable(token_pos, "igr");
|
| - StoreLocalNode* save =
|
| - new StoreLocalNode(token_pos, temp, left_node->receiver());
|
| - left_node = new InstanceGetterNode(token_pos,
|
| - save,
|
| - left_node->field_name());
|
| - right_node = new InstanceGetterNode(token_pos,
|
| - new LoadLocalNode(token_pos, temp),
|
| - right_node->field_name());
|
| + InstanceGetterNode* getter = node->AsInstanceGetterNode();
|
| + AstNode* receiver = getter->receiver();
|
| + if (!IsSimpleLocalOrLiteralNode(getter->receiver())) {
|
| + LocalVariable* t0 = result->AddInitializer(getter->receiver());
|
| + receiver = new LoadLocalNode(token_pos, t0);
|
| }
|
| - *expr = right_node;
|
| - return left_node;
|
| + *expr = new InstanceGetterNode(token_pos,
|
| + receiver,
|
| + getter->field_name());
|
| + return result;
|
| }
|
| - return *expr;
|
| + return result;
|
| }
|
|
|
|
|
| @@ -7123,12 +7070,12 @@
|
|
|
| AstNode* Parser::ParseCascades(AstNode* expr) {
|
| intptr_t cascade_pos = TokenPos();
|
| - LocalVariable* cascade_receiver_var =
|
| - CreateTempConstVariable(cascade_pos, "casc");
|
| + LetNode* result = new LetNode(cascade_pos);
|
| + LocalVariable* cascade_receiver_var = result->AddInitializer(expr);
|
| + // TODO(fschneider): Make LetNode support more than one body node and
|
| + // replace the SequenceNode here and CommaNode here and in postfix
|
| + // expressions.
|
| SequenceNode* cascade = new SequenceNode(cascade_pos, NULL);
|
| - StoreLocalNode* save_cascade =
|
| - new StoreLocalNode(cascade_pos, cascade_receiver_var, expr);
|
| - cascade->Add(save_cascade);
|
| while (CurrentToken() == Token::kCASCADE) {
|
| cascade_pos = TokenPos();
|
| LoadLocalNode* load_cascade_receiver =
|
| @@ -7150,30 +7097,42 @@
|
| const intptr_t assignment_pos = TokenPos();
|
| ConsumeToken();
|
| AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades);
|
| - AstNode* left_expr = expr;
|
| if (assignment_op != Token::kASSIGN) {
|
| // Compound assignment: store inputs with side effects into
|
| // temporary locals.
|
| - left_expr = PrepareCompoundAssignmentNodes(&expr);
|
| + LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr);
|
| + right_expr =
|
| + ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr);
|
| + AstNode* assign_expr = CreateAssignmentNode(expr, right_expr);
|
| + if (assign_expr == NULL) {
|
| + ErrorMsg(assignment_pos,
|
| + "left hand side of '%s' is not assignable",
|
| + Token::Str(assignment_op));
|
| + }
|
| + let_expr->set_body(assign_expr);
|
| + expr = let_expr;
|
| + } else {
|
| + right_expr =
|
| + ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr);
|
| + AstNode* assign_expr = CreateAssignmentNode(expr, right_expr);
|
| + if (assign_expr == NULL) {
|
| + ErrorMsg(assignment_pos,
|
| + "left hand side of '%s' is not assignable",
|
| + Token::Str(assignment_op));
|
| + }
|
| + expr = assign_expr;
|
| }
|
| - right_expr =
|
| - ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr);
|
| - AstNode* assign_expr = CreateAssignmentNode(left_expr, right_expr);
|
| - if (assign_expr == NULL) {
|
| - ErrorMsg(assignment_pos,
|
| - "left hand side of '%s' is not assignable",
|
| - Token::Str(assignment_op));
|
| - }
|
| - expr = assign_expr;
|
| }
|
| cascade->Add(expr);
|
| }
|
| // The result is a pair of the (side effects of the) cascade sequence
|
| // followed by the (value of the) receiver temp variable load.
|
| - return new CommaNode(
|
| + CommaNode* body = new CommaNode(
|
| cascade_pos,
|
| cascade,
|
| new LoadLocalNode(cascade_pos, cascade_receiver_var));
|
| + result->set_body(body);
|
| + return result;
|
| }
|
|
|
|
|
| @@ -7207,20 +7166,30 @@
|
| ErrorMsg(right_expr_pos, "expression must be a compile-time constant");
|
| }
|
| AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades);
|
| - AstNode* left_expr = expr;
|
| if (assignment_op != Token::kASSIGN) {
|
| // Compound assignment: store inputs with side effects into temp. locals.
|
| - left_expr = PrepareCompoundAssignmentNodes(&expr);
|
| + LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr);
|
| + AstNode* assigned_value =
|
| + ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr);
|
| + AstNode* assign_expr = CreateAssignmentNode(expr, assigned_value);
|
| + if (assign_expr == NULL) {
|
| + ErrorMsg(assignment_pos,
|
| + "left hand side of '%s' is not assignable",
|
| + Token::Str(assignment_op));
|
| + }
|
| + let_expr->set_body(assign_expr);
|
| + return let_expr;
|
| + } else {
|
| + AstNode* assigned_value =
|
| + ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr);
|
| + AstNode* assign_expr = CreateAssignmentNode(expr, assigned_value);
|
| + if (assign_expr == NULL) {
|
| + ErrorMsg(assignment_pos,
|
| + "left hand side of '%s' is not assignable",
|
| + Token::Str(assignment_op));
|
| + }
|
| + return assign_expr;
|
| }
|
| - right_expr =
|
| - ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr);
|
| - AstNode* assign_expr = CreateAssignmentNode(left_expr, right_expr);
|
| - if (assign_expr == NULL) {
|
| - ErrorMsg(assignment_pos,
|
| - "left hand side of '%s' is not assignable",
|
| - Token::Str(assignment_op));
|
| - }
|
| - return assign_expr;
|
| }
|
|
|
|
|
| @@ -7278,7 +7247,7 @@
|
| ErrorMsg("expression is not assignable");
|
| }
|
| // Is prefix.
|
| - AstNode* left_expr = PrepareCompoundAssignmentNodes(&expr);
|
| + LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr);
|
| Token::Kind binary_op =
|
| (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB;
|
| BinaryOpNode* add = new BinaryOpNode(
|
| @@ -7286,9 +7255,10 @@
|
| binary_op,
|
| expr,
|
| new LiteralNode(op_pos, Smi::ZoneHandle(Smi::New(1))));
|
| - AstNode* store = CreateAssignmentNode(left_expr, add);
|
| + AstNode* store = CreateAssignmentNode(expr, add);
|
| ASSERT(store != NULL);
|
| - expr = store;
|
| + let_expr->set_body(store);
|
| + expr = let_expr;
|
| } else {
|
| expr = ParsePostfixExpr();
|
| }
|
| @@ -7770,24 +7740,24 @@
|
| }
|
| ConsumeToken();
|
| // Not prefix.
|
| - AstNode* left_expr = PrepareCompoundAssignmentNodes(&postfix_expr);
|
| - const LocalVariable* temp = GetIncrementTempLocal();
|
| - AstNode* save =
|
| - new StoreLocalNode(postfix_expr_pos, temp, postfix_expr);
|
| + LetNode* let_expr = PrepareCompoundAssignmentNodes(&postfix_expr);
|
| + LocalVariable* temp = let_expr->AddInitializer(postfix_expr);
|
| Token::Kind binary_op =
|
| (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB;
|
| BinaryOpNode* add = new BinaryOpNode(
|
| postfix_expr_pos,
|
| binary_op,
|
| - save,
|
| + new LoadLocalNode(postfix_expr_pos, temp),
|
| new LiteralNode(postfix_expr_pos, Smi::ZoneHandle(Smi::New(1))));
|
| - AstNode* store = CreateAssignmentNode(left_expr, add);
|
| + AstNode* store = CreateAssignmentNode(postfix_expr, add);
|
| + ASSERT(store != NULL);
|
| // The result is a pair of the (side effects of the) store followed by
|
| // the (value of the) initial value temp variable load.
|
| - return new CommaNode(
|
| + let_expr->set_body(new CommaNode(
|
| postfix_expr_pos,
|
| store,
|
| - new LoadLocalNode(postfix_expr_pos, temp));
|
| + new LoadLocalNode(postfix_expr_pos, temp)));
|
| + return let_expr;
|
| }
|
| return postfix_expr;
|
| }
|
| @@ -8862,9 +8832,7 @@
|
| new LiteralNode(TokenPos(), empty_array);
|
| factory_param->Add(empty_array_literal);
|
| } else {
|
| - const LocalVariable& temp_local = *BuildArrayTempLocal(type_pos);
|
| - ArrayNode* list =
|
| - new ArrayNode(TokenPos(), type, temp_local, element_list);
|
| + ArrayNode* list = new ArrayNode(TokenPos(), type, element_list);
|
| factory_param->Add(list);
|
| }
|
| return CreateConstructorCallNode(literal_pos,
|
| @@ -8883,13 +8851,10 @@
|
| if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) {
|
| EnsureExpressionTemp();
|
| }
|
| - LocalVariable* allocated =
|
| - CreateTempConstVariable(token_pos, "alloc");
|
| return new ConstructorCallNode(token_pos,
|
| type_arguments,
|
| constructor,
|
| - arguments,
|
| - allocated);
|
| + arguments);
|
| }
|
|
|
|
|
| @@ -9087,7 +9052,6 @@
|
| ArrayNode* kv_pairs = new ArrayNode(
|
| TokenPos(),
|
| Type::ZoneHandle(Type::ArrayType()),
|
| - *BuildArrayTempLocal(type_pos),
|
| kv_pairs_list);
|
| factory_param->Add(kv_pairs);
|
| return CreateConstructorCallNode(literal_pos,
|
| @@ -9474,7 +9438,6 @@
|
| ArrayNode* values = new ArrayNode(
|
| TokenPos(),
|
| Type::ZoneHandle(Type::ArrayType()),
|
| - *BuildArrayTempLocal(TokenPos()),
|
| values_list);
|
| interpolate_arg->Add(values);
|
| primary = MakeStaticCall(Symbols::StringBase(),
|
|
|