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 #include "vm/flags.h" | 6 #include "vm/flags.h" | 
| 7 | 7 | 
| 8 #ifndef DART_PRECOMPILED | 8 #ifndef DART_PRECOMPILED | 
| 9 | 9 | 
| 10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" | 
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 118 ~BoolScope() { | 118 ~BoolScope() { | 
| 119 *_addr = _saved_value; | 119 *_addr = _saved_value; | 
| 120 } | 120 } | 
| 121 | 121 | 
| 122 private: | 122 private: | 
| 123 bool* _addr; | 123 bool* _addr; | 
| 124 bool _saved_value; | 124 bool _saved_value; | 
| 125 }; | 125 }; | 
| 126 | 126 | 
| 127 | 127 | 
| 128 class RecursionChecker : public ValueObject { | |
| 129 public: | |
| 130 explicit RecursionChecker(Parser* p) : parser_(p) { | |
| 131 parser_->recursion_counter_++; | |
| 132 // No need to check the stack unless the parser is in an unusually deep | |
| 133 // recurive state. Thus, we omit the more expensive stack checks in | |
| 134 // the common case. | |
| 135 const int kMaxUncheckedDepth = 100; // Somewhat arbitrary. | |
| 136 if (parser_->recursion_counter_ > kMaxUncheckedDepth) { | |
| 137 parser_->CheckStack(); | |
| 138 } | |
| 139 } | |
| 140 ~RecursionChecker() { | |
| 141 parser_->recursion_counter_--; | |
| 142 } | |
| 143 | |
| 144 private: | |
| 145 Parser* parser_; | |
| 146 }; | |
| 147 | |
| 148 | |
| 128 static RawTypeArguments* NewTypeArguments( | 149 static RawTypeArguments* NewTypeArguments( | 
| 129 const GrowableArray<AbstractType*>& objs) { | 150 const GrowableArray<AbstractType*>& objs) { | 
| 130 const TypeArguments& a = | 151 const TypeArguments& a = | 
| 131 TypeArguments::Handle(TypeArguments::New(objs.length())); | 152 TypeArguments::Handle(TypeArguments::New(objs.length())); | 
| 132 for (int i = 0; i < objs.length(); i++) { | 153 for (int i = 0; i < objs.length(); i++) { | 
| 133 a.SetTypeAt(i, *objs.At(i)); | 154 a.SetTypeAt(i, *objs.At(i)); | 
| 134 } | 155 } | 
| 135 // Cannot canonicalize TypeArgument yet as its types may not have been | 156 // Cannot canonicalize TypeArgument yet as its types may not have been | 
| 136 // finalized yet. | 157 // finalized yet. | 
| 137 return a.raw(); | 158 return a.raw(); | 
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 340 allow_function_literals_(true), | 361 allow_function_literals_(true), | 
| 341 parsed_function_(NULL), | 362 parsed_function_(NULL), | 
| 342 innermost_function_(Function::Handle(zone())), | 363 innermost_function_(Function::Handle(zone())), | 
| 343 literal_token_(LiteralToken::Handle(zone())), | 364 literal_token_(LiteralToken::Handle(zone())), | 
| 344 current_class_(Class::Handle(zone())), | 365 current_class_(Class::Handle(zone())), | 
| 345 library_(Library::Handle(zone(), library.raw())), | 366 library_(Library::Handle(zone(), library.raw())), | 
| 346 try_stack_(NULL), | 367 try_stack_(NULL), | 
| 347 last_used_try_index_(0), | 368 last_used_try_index_(0), | 
| 348 unregister_pending_function_(false), | 369 unregister_pending_function_(false), | 
| 349 async_temp_scope_(NULL), | 370 async_temp_scope_(NULL), | 
| 350 trace_indent_(0) { | 371 trace_indent_(0), | 
| 372 recursion_counter_(0) { | |
| 351 ASSERT(tokens_iterator_.IsValid()); | 373 ASSERT(tokens_iterator_.IsValid()); | 
| 352 ASSERT(!library.IsNull()); | 374 ASSERT(!library.IsNull()); | 
| 353 } | 375 } | 
| 354 | 376 | 
| 355 | 377 | 
| 356 // For parsing a function. | 378 // For parsing a function. | 
| 357 Parser::Parser(const Script& script, | 379 Parser::Parser(const Script& script, | 
| 358 ParsedFunction* parsed_function, | 380 ParsedFunction* parsed_function, | 
| 359 intptr_t token_position) | 381 intptr_t token_position) | 
| 360 : isolate_(Thread::Current()->isolate()), | 382 : isolate_(Thread::Current()->isolate()), | 
| (...skipping 13 matching lines...) Expand all Loading... | |
| 374 literal_token_(LiteralToken::Handle(zone())), | 396 literal_token_(LiteralToken::Handle(zone())), | 
| 375 current_class_(Class::Handle(zone(), | 397 current_class_(Class::Handle(zone(), | 
| 376 parsed_function->function().Owner())), | 398 parsed_function->function().Owner())), | 
| 377 library_(Library::Handle(zone(), Class::Handle( | 399 library_(Library::Handle(zone(), Class::Handle( | 
| 378 zone(), | 400 zone(), | 
| 379 parsed_function->function().origin()).library())), | 401 parsed_function->function().origin()).library())), | 
| 380 try_stack_(NULL), | 402 try_stack_(NULL), | 
| 381 last_used_try_index_(0), | 403 last_used_try_index_(0), | 
| 382 unregister_pending_function_(false), | 404 unregister_pending_function_(false), | 
| 383 async_temp_scope_(NULL), | 405 async_temp_scope_(NULL), | 
| 384 trace_indent_(0) { | 406 trace_indent_(0), | 
| 407 recursion_counter_(0) { | |
| 385 ASSERT(tokens_iterator_.IsValid()); | 408 ASSERT(tokens_iterator_.IsValid()); | 
| 386 ASSERT(!current_function().IsNull()); | 409 ASSERT(!current_function().IsNull()); | 
| 387 EnsureExpressionTemp(); | 410 EnsureExpressionTemp(); | 
| 388 } | 411 } | 
| 389 | 412 | 
| 390 | 413 | 
| 391 Parser::~Parser() { | 414 Parser::~Parser() { | 
| 392 if (unregister_pending_function_) { | 415 if (unregister_pending_function_) { | 
| 393 const GrowableObjectArray& pending_functions = | 416 const GrowableObjectArray& pending_functions = | 
| 394 GrowableObjectArray::Handle(T->pending_functions()); | 417 GrowableObjectArray::Handle(T->pending_functions()); | 
| (...skipping 5710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6105 for (intptr_t i = 0; i < top_level.functions().length(); i++) { | 6128 for (intptr_t i = 0; i < top_level.functions().length(); i++) { | 
| 6106 toplevel_class.AddFunction(*top_level.functions()[i]); | 6129 toplevel_class.AddFunction(*top_level.functions()[i]); | 
| 6107 } | 6130 } | 
| 6108 if (toplevel_class.is_finalized()) { | 6131 if (toplevel_class.is_finalized()) { | 
| 6109 toplevel_class.ResetFinalization(); | 6132 toplevel_class.ResetFinalization(); | 
| 6110 } | 6133 } | 
| 6111 pending_classes.Add(toplevel_class, Heap::kOld); | 6134 pending_classes.Add(toplevel_class, Heap::kOld); | 
| 6112 } | 6135 } | 
| 6113 | 6136 | 
| 6114 | 6137 | 
| 6138 void Parser::CheckStack() { | |
| 6139 volatile uword c_stack_pos = Isolate::GetCurrentStackPointer(); | |
| 6140 volatile uword c_stack_base = OSThread::Current()->stack_base(); | |
| 6141 volatile uword c_stack_limit = | |
| 6142 c_stack_base - OSThread::GetSpecifiedStackSize(); | |
| 6143 if ((c_stack_base > 0) && (c_stack_pos < c_stack_limit)) { | |
| 
 
rmacnak
2016/01/22 00:45:28
Add comment that c_stack_base > 0 handles the case
 
hausner
2016/01/22 18:38:14
Done.
 
 | |
| 6144 ReportError("stack overflow while parsing"); | |
| 6145 } | |
| 6146 } | |
| 6147 | |
| 6148 | |
| 6115 void Parser::ChainNewBlock(LocalScope* outer_scope) { | 6149 void Parser::ChainNewBlock(LocalScope* outer_scope) { | 
| 6116 Block* block = new(Z) Block( | 6150 Block* block = new(Z) Block( | 
| 6117 current_block_, | 6151 current_block_, | 
| 6118 outer_scope, | 6152 outer_scope, | 
| 6119 new(Z) SequenceNode(TokenPos(), outer_scope)); | 6153 new(Z) SequenceNode(TokenPos(), outer_scope)); | 
| 6120 current_block_ = block; | 6154 current_block_ = block; | 
| 6121 } | 6155 } | 
| 6122 | 6156 | 
| 6123 | 6157 | 
| 6124 void Parser::OpenBlock() { | 6158 void Parser::OpenBlock() { | 
| (...skipping 1926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8051 } | 8085 } | 
| 8052 } | 8086 } | 
| 8053 return false; | 8087 return false; | 
| 8054 } | 8088 } | 
| 8055 | 8089 | 
| 8056 | 8090 | 
| 8057 void Parser::ParseStatementSequence() { | 8091 void Parser::ParseStatementSequence() { | 
| 8058 TRACE_PARSER("ParseStatementSequence"); | 8092 TRACE_PARSER("ParseStatementSequence"); | 
| 8059 const bool dead_code_allowed = true; | 8093 const bool dead_code_allowed = true; | 
| 8060 bool abrupt_completing_seen = false; | 8094 bool abrupt_completing_seen = false; | 
| 8095 RecursionChecker rc(this); | |
| 8061 while (CurrentToken() != Token::kRBRACE) { | 8096 while (CurrentToken() != Token::kRBRACE) { | 
| 8062 const intptr_t statement_pos = TokenPos(); | 8097 const intptr_t statement_pos = TokenPos(); | 
| 8063 AstNode* statement = ParseStatement(); | 8098 AstNode* statement = ParseStatement(); | 
| 8064 // Do not add statements with no effect (e.g., LoadLocalNode). | 8099 // Do not add statements with no effect (e.g., LoadLocalNode). | 
| 8065 if ((statement != NULL) && statement->IsLoadLocalNode()) { | 8100 if ((statement != NULL) && statement->IsLoadLocalNode()) { | 
| 8066 // Skip load local. | 8101 // Skip load local. | 
| 8067 continue; | 8102 continue; | 
| 8068 } | 8103 } | 
| 8069 if (statement != NULL) { | 8104 if (statement != NULL) { | 
| 8070 if (!dead_code_allowed && abrupt_completing_seen) { | 8105 if (!dead_code_allowed && abrupt_completing_seen) { | 
| (...skipping 19 matching lines...) Expand all Loading... | |
| 8090 OpenBlock(); | 8125 OpenBlock(); | 
| 8091 } | 8126 } | 
| 8092 if (label != NULL) { | 8127 if (label != NULL) { | 
| 8093 current_block_->scope->AddLabel(label); | 8128 current_block_->scope->AddLabel(label); | 
| 8094 } | 8129 } | 
| 8095 if (CurrentToken() == Token::kLBRACE) { | 8130 if (CurrentToken() == Token::kLBRACE) { | 
| 8096 ConsumeToken(); | 8131 ConsumeToken(); | 
| 8097 ParseStatementSequence(); | 8132 ParseStatementSequence(); | 
| 8098 ExpectToken(Token::kRBRACE); | 8133 ExpectToken(Token::kRBRACE); | 
| 8099 } else { | 8134 } else { | 
| 8135 RecursionChecker rc(this); | |
| 8100 AstNode* statement = ParseStatement(); | 8136 AstNode* statement = ParseStatement(); | 
| 8101 if (statement != NULL) { | 8137 if (statement != NULL) { | 
| 8102 current_block_->statements->Add(statement); | 8138 current_block_->statements->Add(statement); | 
| 8103 } | 8139 } | 
| 8104 } | 8140 } | 
| 8105 SequenceNode* sequence = CloseBlock(); | 8141 SequenceNode* sequence = CloseBlock(); | 
| 8106 return sequence; | 8142 return sequence; | 
| 8107 } | 8143 } | 
| 8108 | 8144 | 
| 8109 | 8145 | 
| (...skipping 2718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10828 } | 10864 } | 
| 10829 | 10865 | 
| 10830 | 10866 | 
| 10831 AstNode* Parser::ParseExpr(bool require_compiletime_const, | 10867 AstNode* Parser::ParseExpr(bool require_compiletime_const, | 
| 10832 bool consume_cascades) { | 10868 bool consume_cascades) { | 
| 10833 TRACE_PARSER("ParseExpr"); | 10869 TRACE_PARSER("ParseExpr"); | 
| 10834 String* expr_ident = | 10870 String* expr_ident = | 
| 10835 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 10871 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 
| 10836 const intptr_t expr_pos = TokenPos(); | 10872 const intptr_t expr_pos = TokenPos(); | 
| 10837 | 10873 | 
| 10874 RecursionChecker rc(this); | |
| 10875 | |
| 10838 if (CurrentToken() == Token::kTHROW) { | 10876 if (CurrentToken() == Token::kTHROW) { | 
| 10839 if (require_compiletime_const) { | 10877 if (require_compiletime_const) { | 
| 10840 ReportError("'throw expr' is not a valid compile-time constant"); | 10878 ReportError("'throw expr' is not a valid compile-time constant"); | 
| 10841 } | 10879 } | 
| 10842 ConsumeToken(); | 10880 ConsumeToken(); | 
| 10843 if (CurrentToken() == Token::kSEMICOLON) { | 10881 if (CurrentToken() == Token::kSEMICOLON) { | 
| 10844 ReportError("expression expected after throw"); | 10882 ReportError("expression expected after throw"); | 
| 10845 } | 10883 } | 
| 10846 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); | 10884 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); | 
| 10847 return new(Z) ThrowNode(expr_pos, expr, NULL); | 10885 return new(Z) ThrowNode(expr_pos, expr, NULL); | 
| (...skipping 3569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 14417 const ArgumentListNode& function_args, | 14455 const ArgumentListNode& function_args, | 
| 14418 const LocalVariable* temp_for_last_arg, | 14456 const LocalVariable* temp_for_last_arg, | 
| 14419 bool is_super_invocation) { | 14457 bool is_super_invocation) { | 
| 14420 UNREACHABLE(); | 14458 UNREACHABLE(); | 
| 14421 return NULL; | 14459 return NULL; | 
| 14422 } | 14460 } | 
| 14423 | 14461 | 
| 14424 } // namespace dart | 14462 } // namespace dart | 
| 14425 | 14463 | 
| 14426 #endif // DART_PRECOMPILED | 14464 #endif // DART_PRECOMPILED | 
| OLD | NEW |