Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 105 UnhandledException& excp = UnhandledException::Handle(); | 105 UnhandledException& excp = UnhandledException::Handle(); |
| 106 excp ^= obj.raw(); | 106 excp ^= obj.raw(); |
| 107 const Instance& exception = Instance::ZoneHandle(excp.exception()); | 107 const Instance& exception = Instance::ZoneHandle(excp.exception()); |
| 108 const Instance& stack_trace = Instance::ZoneHandle(excp.stacktrace()); | 108 const Instance& stack_trace = Instance::ZoneHandle(excp.stacktrace()); |
| 109 return new ThrowNode(token_pos, | 109 return new ThrowNode(token_pos, |
| 110 new LiteralNode(token_pos, exception), | 110 new LiteralNode(token_pos, exception), |
| 111 new LiteralNode(token_pos, stack_trace)); | 111 new LiteralNode(token_pos, stack_trace)); |
| 112 } | 112 } |
| 113 | 113 |
| 114 | 114 |
| 115 LocalVariable* ParsedFunction::CreateExpressionTempVar(intptr_t token_index) { | |
| 116 return new LocalVariable(token_index, | |
| 117 String::ZoneHandle(String::NewSymbol(":expr_temp")), | |
| 118 Type::ZoneHandle(Type::DynamicType())); | |
| 119 } | |
| 120 | |
| 121 | |
| 115 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { | 122 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { |
| 116 ASSERT(node_sequence_ == NULL); | 123 ASSERT(node_sequence_ == NULL); |
| 117 ASSERT(node_sequence != NULL); | 124 ASSERT(node_sequence != NULL); |
| 118 node_sequence_ = node_sequence; | 125 node_sequence_ = node_sequence; |
| 119 const int num_fixed_params = function().num_fixed_parameters(); | 126 const int num_fixed_params = function().num_fixed_parameters(); |
| 120 const int num_opt_params = function().num_optional_parameters(); | 127 const int num_opt_params = function().num_optional_parameters(); |
| 121 // Allocated ids for parameters. | 128 // Allocated ids for parameters. |
| 122 intptr_t parameter_id = AstNode::kNoId; | 129 intptr_t parameter_id = AstNode::kNoId; |
| 123 for (intptr_t i = 0; i < num_fixed_params + num_opt_params; i++) { | 130 for (intptr_t i = 0; i < num_fixed_params + num_opt_params; i++) { |
| 124 parameter_id = AstNode::GetNextId(); | 131 parameter_id = AstNode::GetNextId(); |
| 125 if (i == 0) { | 132 if (i == 0) { |
| 126 node_sequence_->set_first_parameter_id(parameter_id); | 133 node_sequence_->set_first_parameter_id(parameter_id); |
| 127 } | 134 } |
| 128 } | 135 } |
| 129 node_sequence_->set_last_parameter_id(parameter_id); | 136 node_sequence_->set_last_parameter_id(parameter_id); |
| 130 } | 137 } |
| 131 | 138 |
| 139 | |
| 132 void ParsedFunction::AllocateVariables() { | 140 void ParsedFunction::AllocateVariables() { |
| 133 LocalScope* scope = node_sequence()->scope(); | 141 LocalScope* scope = node_sequence()->scope(); |
| 134 const int fixed_parameter_count = function().num_fixed_parameters(); | 142 const int fixed_parameter_count = function().num_fixed_parameters(); |
| 135 const int optional_parameter_count = function().num_optional_parameters(); | 143 const int optional_parameter_count = function().num_optional_parameters(); |
| 136 const int parameter_count = fixed_parameter_count + optional_parameter_count; | 144 const int parameter_count = fixed_parameter_count + optional_parameter_count; |
| 137 // Compute start indices to parameters and locals, and the number of | 145 // Compute start indices to parameters and locals, and the number of |
| 138 // parameters to copy. | 146 // parameters to copy. |
| 139 if (optional_parameter_count == 0) { | 147 if (optional_parameter_count == 0) { |
| 140 // Parameter i will be at fp[1 + parameter_count - i] and local variable | 148 // Parameter i will be at fp[1 + parameter_count - i] and local variable |
| 141 // j will be at fp[-1 - j]. | 149 // j will be at fp[-1 - j]. |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 221 | 229 |
| 222 DISALLOW_COPY_AND_ASSIGN(TryBlocks); | 230 DISALLOW_COPY_AND_ASSIGN(TryBlocks); |
| 223 }; | 231 }; |
| 224 | 232 |
| 225 | 233 |
| 226 void Parser::TryBlocks::AddNodeForFinallyInlining(AstNode* node) { | 234 void Parser::TryBlocks::AddNodeForFinallyInlining(AstNode* node) { |
| 227 inlined_finally_nodes_.Add(node); | 235 inlined_finally_nodes_.Add(node); |
| 228 } | 236 } |
| 229 | 237 |
| 230 | 238 |
| 231 Parser::Parser(const Script& script, const Library& library) | 239 Parser::Parser(const Script& script, |
| 240 const Library& library) | |
| 232 : script_(script), | 241 : script_(script), |
| 233 tokens_(TokenStream::Handle(script.tokens())), | 242 tokens_(TokenStream::Handle(script.tokens())), |
| 234 token_index_(0), | 243 token_index_(0), |
| 235 current_block_(NULL), | 244 current_block_(NULL), |
| 236 is_top_level_(false), | 245 is_top_level_(false), |
| 237 current_member_(NULL), | 246 current_member_(NULL), |
| 238 allow_function_literals_(true), | 247 allow_function_literals_(true), |
| 239 current_function_(Function::Handle()), | 248 current_function_(Function::Handle()), |
| 240 current_class_(Class::Handle()), | 249 current_class_(Class::Handle()), |
| 241 library_(library), | 250 library_(library), |
| 242 try_blocks_list_(NULL), | 251 try_blocks_list_(NULL), |
| 243 increment_temp_(NULL) { | 252 expression_temp_(NULL) { |
| 244 ASSERT(!tokens_.IsNull()); | 253 ASSERT(!tokens_.IsNull()); |
| 245 ASSERT(!library.IsNull()); | 254 ASSERT(!library.IsNull()); |
| 246 SetPosition(0); | 255 SetPosition(0); |
| 247 } | 256 } |
| 248 | 257 |
| 249 | 258 |
| 250 Parser::Parser(const Script& script, | 259 Parser::Parser(const Script& script, |
| 251 const Function& function, | 260 const Function& function, |
| 252 intptr_t token_index) | 261 intptr_t token_index) |
| 253 : script_(script), | 262 : script_(script), |
| 254 tokens_(TokenStream::Handle(script.tokens())), | 263 tokens_(TokenStream::Handle(script.tokens())), |
| 255 token_index_(0), | 264 token_index_(0), |
| 256 current_block_(NULL), | 265 current_block_(NULL), |
| 257 is_top_level_(false), | 266 is_top_level_(false), |
| 258 current_member_(NULL), | 267 current_member_(NULL), |
| 259 allow_function_literals_(true), | 268 allow_function_literals_(true), |
| 260 current_function_(function), | 269 current_function_(function), |
| 261 current_class_(Class::Handle(current_function_.owner())), | 270 current_class_(Class::Handle(current_function_.owner())), |
| 262 library_(Library::Handle(current_class_.library())), | 271 library_(Library::Handle(current_class_.library())), |
| 263 try_blocks_list_(NULL), | 272 try_blocks_list_(NULL), |
| 264 increment_temp_(NULL) { | 273 expression_temp_(NULL) { |
| 265 ASSERT(!tokens_.IsNull()); | 274 ASSERT(!tokens_.IsNull()); |
| 266 ASSERT(!function.IsNull()); | 275 ASSERT(!function.IsNull()); |
| 267 SetPosition(token_index); | 276 SetPosition(token_index); |
| 268 } | 277 } |
| 269 | 278 |
| 270 | 279 |
| 271 bool Parser::SetAllowFunctionLiterals(bool value) { | 280 bool Parser::SetAllowFunctionLiterals(bool value) { |
| 272 bool current_value = allow_function_literals_; | 281 bool current_value = allow_function_literals_; |
| 273 allow_function_literals_ = value; | 282 allow_function_literals_ = value; |
| 274 return current_value; | 283 return current_value; |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 678 node_sequence = parser.ParseStaticConstGetter(func); | 687 node_sequence = parser.ParseStaticConstGetter(func); |
| 679 break; | 688 break; |
| 680 default: | 689 default: |
| 681 UNREACHABLE(); | 690 UNREACHABLE(); |
| 682 } | 691 } |
| 683 | 692 |
| 684 if (!HasReturnNode(node_sequence)) { | 693 if (!HasReturnNode(node_sequence)) { |
| 685 // Add implicit return node. | 694 // Add implicit return node. |
| 686 node_sequence->Add(new ReturnNode(parser.token_index_)); | 695 node_sequence->Add(new ReturnNode(parser.token_index_)); |
| 687 } | 696 } |
| 688 if (parser.increment_temp_ != NULL) { | 697 if (parser.expression_temp_ != NULL) { |
| 689 node_sequence->scope()->AddVariable(parser.increment_temp_); | 698 parsed_function->set_expression_temp_var(parser.expression_temp_); |
| 699 } | |
| 700 if (parsed_function->has_expression_temp_var()) { | |
|
hausner
2012/05/09 20:52:08
This if statement is true iff the previous one was
srdjan
2012/05/09 21:25:45
Yes, but it can be true even if the previous one w
| |
| 701 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); | |
| 690 } | 702 } |
| 691 parsed_function->SetNodeSequence(node_sequence); | 703 parsed_function->SetNodeSequence(node_sequence); |
| 692 | 704 |
| 693 // The instantiator may be required at run time for generic type checks or | 705 // The instantiator may be required at run time for generic type checks or |
| 694 // allocation of generic types. | 706 // allocation of generic types. |
| 695 if (parser.IsInstantiatorRequired()) { | 707 if (parser.IsInstantiatorRequired()) { |
| 696 // In the case of a local function, only set the instantiator if the | 708 // In the case of a local function, only set the instantiator if the |
| 697 // receiver was captured. | 709 // receiver was captured. |
| 698 const bool kTestOnly = true; | 710 const bool kTestOnly = true; |
| 699 LocalVariable* receiver = | 711 LocalVariable* receiver = |
| (...skipping 4550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5250 AstNode* exception_type = new TypeNode(catch_pos, *exception_param.type); | 5262 AstNode* exception_type = new TypeNode(catch_pos, *exception_param.type); |
| 5251 AstNode* exception_var = new LoadLocalNode(catch_pos, *catch_excp_var); | 5263 AstNode* exception_var = new LoadLocalNode(catch_pos, *catch_excp_var); |
| 5252 AstNode* type_cond_expr = new ComparisonNode( | 5264 AstNode* type_cond_expr = new ComparisonNode( |
| 5253 catch_pos, Token::kIS, exception_var, exception_type); | 5265 catch_pos, Token::kIS, exception_var, exception_type); |
| 5254 if (catch_clause_count == 1) { | 5266 if (catch_clause_count == 1) { |
| 5255 // Null is also allowed, but check only in the first clause. | 5267 // Null is also allowed, but check only in the first clause. |
| 5256 AstNode* null_literal = | 5268 AstNode* null_literal = |
| 5257 new LiteralNode(catch_pos, Instance::ZoneHandle(Instance::null())); | 5269 new LiteralNode(catch_pos, Instance::ZoneHandle(Instance::null())); |
| 5258 AstNode* null_cond_expr = new ComparisonNode( | 5270 AstNode* null_cond_expr = new ComparisonNode( |
| 5259 catch_pos, Token::kEQ_STRICT, exception_var, null_literal); | 5271 catch_pos, Token::kEQ_STRICT, exception_var, null_literal); |
| 5272 EnsureExpressionTemp(); | |
| 5260 AstNode* or_node = new BinaryOpNode( | 5273 AstNode* or_node = new BinaryOpNode( |
| 5261 catch_pos, Token::kOR, null_cond_expr, type_cond_expr); | 5274 catch_pos, Token::kOR, null_cond_expr, type_cond_expr); |
| 5262 current_block_->statements->Add( | 5275 current_block_->statements->Add( |
| 5263 new IfNode(catch_pos, or_node, catch_handler, NULL)); | 5276 new IfNode(catch_pos, or_node, catch_handler, NULL)); |
| 5264 } else { | 5277 } else { |
| 5265 current_block_->statements->Add( | 5278 current_block_->statements->Add( |
| 5266 new IfNode(catch_pos, type_cond_expr, catch_handler, NULL)); | 5279 new IfNode(catch_pos, type_cond_expr, catch_handler, NULL)); |
| 5267 } | 5280 } |
| 5268 } else { | 5281 } else { |
| 5269 // No exception type exists in the catch specifier so execute the | 5282 // No exception type exists in the catch specifier so execute the |
| (...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5897 AstNode* expr = ParseExpr(kAllowConst); | 5910 AstNode* expr = ParseExpr(kAllowConst); |
| 5898 list->Add(expr); | 5911 list->Add(expr); |
| 5899 } | 5912 } |
| 5900 expressions = list; | 5913 expressions = list; |
| 5901 } | 5914 } |
| 5902 return expressions; | 5915 return expressions; |
| 5903 } | 5916 } |
| 5904 | 5917 |
| 5905 | 5918 |
| 5906 const LocalVariable& Parser::GetIncrementTempLocal() { | 5919 const LocalVariable& Parser::GetIncrementTempLocal() { |
| 5907 if (increment_temp_ == NULL) { | 5920 if (expression_temp_ == NULL) { |
| 5908 increment_temp_ = | 5921 expression_temp_ = ParsedFunction::CreateExpressionTempVar( |
| 5909 new LocalVariable(current_function_.token_index(), | 5922 current_function().token_index()); |
| 5910 String::ZoneHandle(String::NewSymbol(":incrtemp")), | |
| 5911 Type::ZoneHandle(Type::DynamicType())); | |
| 5912 } | 5923 } |
| 5913 return *increment_temp_; | 5924 return *expression_temp_; |
| 5914 } | 5925 } |
| 5915 | 5926 |
| 5927 | |
| 5928 void Parser::EnsureExpressionTemp() { | |
| 5929 // Temporary used later by the flow_graph_builder. | |
| 5930 GetIncrementTempLocal(); | |
| 5931 } | |
| 5932 | |
| 5933 | |
| 5916 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_index, | 5934 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_index, |
| 5917 intptr_t token_id, | 5935 intptr_t token_id, |
| 5918 const char* s) { | 5936 const char* s) { |
| 5919 char name[64]; | 5937 char name[64]; |
| 5920 OS::SNPrint(name, 64, ":%s%d", s, token_id); | 5938 OS::SNPrint(name, 64, ":%s%d", s, token_id); |
| 5921 LocalVariable* temp = | 5939 LocalVariable* temp = |
| 5922 new LocalVariable(token_index, | 5940 new LocalVariable(token_index, |
| 5923 String::ZoneHandle(String::NewSymbol(name)), | 5941 String::ZoneHandle(String::NewSymbol(name)), |
| 5924 Type::ZoneHandle(Type::DynamicType())); | 5942 Type::ZoneHandle(Type::DynamicType())); |
| 5925 temp->set_is_final(); | 5943 temp->set_is_final(); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 5942 dbl_obj ^= lhs_literal->literal().raw(); | 5960 dbl_obj ^= lhs_literal->literal().raw(); |
| 5943 double left_double = dbl_obj.value(); | 5961 double left_double = dbl_obj.value(); |
| 5944 dbl_obj ^= rhs_literal->literal().raw(); | 5962 dbl_obj ^= rhs_literal->literal().raw(); |
| 5945 double right_double = dbl_obj.value(); | 5963 double right_double = dbl_obj.value(); |
| 5946 if (binary_op == Token::kDIV) { | 5964 if (binary_op == Token::kDIV) { |
| 5947 dbl_obj = Double::NewCanonical((left_double / right_double)); | 5965 dbl_obj = Double::NewCanonical((left_double / right_double)); |
| 5948 return new LiteralNode(op_pos, dbl_obj); | 5966 return new LiteralNode(op_pos, dbl_obj); |
| 5949 } | 5967 } |
| 5950 } | 5968 } |
| 5951 } | 5969 } |
| 5970 if ((binary_op == Token::kAND) || (binary_op == Token::kOR)) { | |
|
hausner
2012/05/09 20:52:08
I thought you wanted to do constant folding in the
srdjan
2012/05/09 21:25:45
It turns out that constant folding is not needed.
| |
| 5971 EnsureExpressionTemp(); | |
| 5972 } | |
| 5952 return new BinaryOpNode(op_pos, binary_op, lhs, rhs); | 5973 return new BinaryOpNode(op_pos, binary_op, lhs, rhs); |
| 5953 } | 5974 } |
| 5954 | 5975 |
| 5955 | 5976 |
| 5956 AstNode* Parser::ExpandAssignableOp(intptr_t op_pos, | 5977 AstNode* Parser::ExpandAssignableOp(intptr_t op_pos, |
| 5957 Token::Kind assignment_op, | 5978 Token::Kind assignment_op, |
| 5958 AstNode* lhs, | 5979 AstNode* lhs, |
| 5959 AstNode* rhs) { | 5980 AstNode* rhs) { |
| 5960 TRACE_PARSER("ExpandAssignableOp"); | 5981 TRACE_PARSER("ExpandAssignableOp"); |
| 5961 switch (assignment_op) { | 5982 switch (assignment_op) { |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6112 ASSERT(expr->IsLiteralNode()); | 6133 ASSERT(expr->IsLiteralNode()); |
| 6113 return expr->AsLiteralNode(); | 6134 return expr->AsLiteralNode(); |
| 6114 } | 6135 } |
| 6115 | 6136 |
| 6116 | 6137 |
| 6117 AstNode* Parser::ParseConditionalExpr() { | 6138 AstNode* Parser::ParseConditionalExpr() { |
| 6118 TRACE_PARSER("ParseConditionalExpr"); | 6139 TRACE_PARSER("ParseConditionalExpr"); |
| 6119 const intptr_t expr_pos = token_index_; | 6140 const intptr_t expr_pos = token_index_; |
| 6120 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kOR)); | 6141 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kOR)); |
| 6121 if (CurrentToken() == Token::kCONDITIONAL) { | 6142 if (CurrentToken() == Token::kCONDITIONAL) { |
| 6143 EnsureExpressionTemp(); | |
| 6122 ConsumeToken(); | 6144 ConsumeToken(); |
| 6123 AstNode* expr1 = ParseExpr(kAllowConst); | 6145 AstNode* expr1 = ParseExpr(kAllowConst); |
| 6124 ExpectToken(Token::kCOLON); | 6146 ExpectToken(Token::kCOLON); |
| 6125 AstNode* expr2 = ParseExpr(kAllowConst); | 6147 AstNode* expr2 = ParseExpr(kAllowConst); |
| 6126 expr = new ConditionalExprNode(expr_pos, expr, expr1, expr2); | 6148 expr = new ConditionalExprNode(expr_pos, expr, expr1, expr2); |
| 6127 } | 6149 } |
| 6128 return expr; | 6150 return expr; |
| 6129 } | 6151 } |
| 6130 | 6152 |
| 6131 | 6153 |
| (...skipping 2302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8434 void Parser::SkipQualIdent() { | 8456 void Parser::SkipQualIdent() { |
| 8435 ASSERT(IsIdentifier()); | 8457 ASSERT(IsIdentifier()); |
| 8436 ConsumeToken(); | 8458 ConsumeToken(); |
| 8437 if (CurrentToken() == Token::kPERIOD) { | 8459 if (CurrentToken() == Token::kPERIOD) { |
| 8438 ConsumeToken(); // Consume the kPERIOD token. | 8460 ConsumeToken(); // Consume the kPERIOD token. |
| 8439 ExpectIdentifier("identifier expected after '.'"); | 8461 ExpectIdentifier("identifier expected after '.'"); |
| 8440 } | 8462 } |
| 8441 } | 8463 } |
| 8442 | 8464 |
| 8443 } // namespace dart | 8465 } // namespace dart |
| OLD | NEW |