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_RUNTIME | 8 #ifndef DART_PRECOMPILED_RUNTIME |
9 | 9 |
10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 ~BoolScope() { | 120 ~BoolScope() { |
121 *_addr = _saved_value; | 121 *_addr = _saved_value; |
122 } | 122 } |
123 | 123 |
124 private: | 124 private: |
125 bool* _addr; | 125 bool* _addr; |
126 bool _saved_value; | 126 bool _saved_value; |
127 }; | 127 }; |
128 | 128 |
129 | 129 |
| 130 class RecursionChecker : public ValueObject { |
| 131 public: |
| 132 explicit RecursionChecker(Parser* p) : parser_(p) { |
| 133 parser_->recursion_counter_++; |
| 134 // No need to check the stack unless the parser is in an unusually deep |
| 135 // recurive state. Thus, we omit the more expensive stack checks in |
| 136 // the common case. |
| 137 const int kMaxUncheckedDepth = 100; // Somewhat arbitrary. |
| 138 if (parser_->recursion_counter_ > kMaxUncheckedDepth) { |
| 139 parser_->CheckStack(); |
| 140 } |
| 141 } |
| 142 ~RecursionChecker() { |
| 143 parser_->recursion_counter_--; |
| 144 } |
| 145 |
| 146 private: |
| 147 Parser* parser_; |
| 148 }; |
| 149 |
| 150 |
130 static RawTypeArguments* NewTypeArguments( | 151 static RawTypeArguments* NewTypeArguments( |
131 const GrowableArray<AbstractType*>& objs) { | 152 const GrowableArray<AbstractType*>& objs) { |
132 const TypeArguments& a = | 153 const TypeArguments& a = |
133 TypeArguments::Handle(TypeArguments::New(objs.length())); | 154 TypeArguments::Handle(TypeArguments::New(objs.length())); |
134 for (int i = 0; i < objs.length(); i++) { | 155 for (int i = 0; i < objs.length(); i++) { |
135 a.SetTypeAt(i, *objs.At(i)); | 156 a.SetTypeAt(i, *objs.At(i)); |
136 } | 157 } |
137 // Cannot canonicalize TypeArgument yet as its types may not have been | 158 // Cannot canonicalize TypeArgument yet as its types may not have been |
138 // finalized yet. | 159 // finalized yet. |
139 return a.raw(); | 160 return a.raw(); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 allow_function_literals_(true), | 363 allow_function_literals_(true), |
343 parsed_function_(NULL), | 364 parsed_function_(NULL), |
344 innermost_function_(Function::Handle(zone())), | 365 innermost_function_(Function::Handle(zone())), |
345 literal_token_(LiteralToken::Handle(zone())), | 366 literal_token_(LiteralToken::Handle(zone())), |
346 current_class_(Class::Handle(zone())), | 367 current_class_(Class::Handle(zone())), |
347 library_(Library::Handle(zone(), library.raw())), | 368 library_(Library::Handle(zone(), library.raw())), |
348 try_stack_(NULL), | 369 try_stack_(NULL), |
349 last_used_try_index_(0), | 370 last_used_try_index_(0), |
350 unregister_pending_function_(false), | 371 unregister_pending_function_(false), |
351 async_temp_scope_(NULL), | 372 async_temp_scope_(NULL), |
352 trace_indent_(0) { | 373 trace_indent_(0), |
| 374 recursion_counter_(0) { |
353 ASSERT(tokens_iterator_.IsValid()); | 375 ASSERT(tokens_iterator_.IsValid()); |
354 ASSERT(!library.IsNull()); | 376 ASSERT(!library.IsNull()); |
355 } | 377 } |
356 | 378 |
357 | 379 |
358 // For parsing a function. | 380 // For parsing a function. |
359 Parser::Parser(const Script& script, | 381 Parser::Parser(const Script& script, |
360 ParsedFunction* parsed_function, | 382 ParsedFunction* parsed_function, |
361 intptr_t token_position) | 383 intptr_t token_position) |
362 : isolate_(Thread::Current()->isolate()), | 384 : isolate_(Thread::Current()->isolate()), |
(...skipping 13 matching lines...) Expand all Loading... |
376 literal_token_(LiteralToken::Handle(zone())), | 398 literal_token_(LiteralToken::Handle(zone())), |
377 current_class_(Class::Handle(zone(), | 399 current_class_(Class::Handle(zone(), |
378 parsed_function->function().Owner())), | 400 parsed_function->function().Owner())), |
379 library_(Library::Handle(zone(), Class::Handle( | 401 library_(Library::Handle(zone(), Class::Handle( |
380 zone(), | 402 zone(), |
381 parsed_function->function().origin()).library())), | 403 parsed_function->function().origin()).library())), |
382 try_stack_(NULL), | 404 try_stack_(NULL), |
383 last_used_try_index_(0), | 405 last_used_try_index_(0), |
384 unregister_pending_function_(false), | 406 unregister_pending_function_(false), |
385 async_temp_scope_(NULL), | 407 async_temp_scope_(NULL), |
386 trace_indent_(0) { | 408 trace_indent_(0), |
| 409 recursion_counter_(0) { |
387 ASSERT(tokens_iterator_.IsValid()); | 410 ASSERT(tokens_iterator_.IsValid()); |
388 ASSERT(!current_function().IsNull()); | 411 ASSERT(!current_function().IsNull()); |
389 EnsureExpressionTemp(); | 412 EnsureExpressionTemp(); |
390 } | 413 } |
391 | 414 |
392 | 415 |
393 Parser::~Parser() { | 416 Parser::~Parser() { |
394 if (unregister_pending_function_) { | 417 if (unregister_pending_function_) { |
395 const GrowableObjectArray& pending_functions = | 418 const GrowableObjectArray& pending_functions = |
396 GrowableObjectArray::Handle(T->pending_functions()); | 419 GrowableObjectArray::Handle(T->pending_functions()); |
(...skipping 5643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6040 for (intptr_t i = 0; i < top_level.functions().length(); i++) { | 6063 for (intptr_t i = 0; i < top_level.functions().length(); i++) { |
6041 toplevel_class.AddFunction(*top_level.functions()[i]); | 6064 toplevel_class.AddFunction(*top_level.functions()[i]); |
6042 } | 6065 } |
6043 if (toplevel_class.is_finalized()) { | 6066 if (toplevel_class.is_finalized()) { |
6044 toplevel_class.ResetFinalization(); | 6067 toplevel_class.ResetFinalization(); |
6045 } | 6068 } |
6046 pending_classes.Add(toplevel_class, Heap::kOld); | 6069 pending_classes.Add(toplevel_class, Heap::kOld); |
6047 } | 6070 } |
6048 | 6071 |
6049 | 6072 |
| 6073 void Parser::CheckStack() { |
| 6074 volatile uword c_stack_pos = Isolate::GetCurrentStackPointer(); |
| 6075 volatile uword c_stack_base = OSThread::Current()->stack_base(); |
| 6076 volatile uword c_stack_limit = |
| 6077 c_stack_base - OSThread::GetSpecifiedStackSize(); |
| 6078 // Note: during early initialization the stack_base() can return 0. |
| 6079 if ((c_stack_base > 0) && (c_stack_pos < c_stack_limit)) { |
| 6080 ReportError("stack overflow while parsing"); |
| 6081 } |
| 6082 } |
| 6083 |
| 6084 |
6050 void Parser::ChainNewBlock(LocalScope* outer_scope) { | 6085 void Parser::ChainNewBlock(LocalScope* outer_scope) { |
6051 Block* block = new(Z) Block( | 6086 Block* block = new(Z) Block( |
6052 current_block_, | 6087 current_block_, |
6053 outer_scope, | 6088 outer_scope, |
6054 new(Z) SequenceNode(TokenPos(), outer_scope)); | 6089 new(Z) SequenceNode(TokenPos(), outer_scope)); |
6055 current_block_ = block; | 6090 current_block_ = block; |
6056 } | 6091 } |
6057 | 6092 |
6058 | 6093 |
6059 void Parser::OpenBlock() { | 6094 void Parser::OpenBlock() { |
(...skipping 1883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7943 } | 7978 } |
7944 } | 7979 } |
7945 return false; | 7980 return false; |
7946 } | 7981 } |
7947 | 7982 |
7948 | 7983 |
7949 void Parser::ParseStatementSequence() { | 7984 void Parser::ParseStatementSequence() { |
7950 TRACE_PARSER("ParseStatementSequence"); | 7985 TRACE_PARSER("ParseStatementSequence"); |
7951 const bool dead_code_allowed = true; | 7986 const bool dead_code_allowed = true; |
7952 bool abrupt_completing_seen = false; | 7987 bool abrupt_completing_seen = false; |
| 7988 RecursionChecker rc(this); |
7953 while (CurrentToken() != Token::kRBRACE) { | 7989 while (CurrentToken() != Token::kRBRACE) { |
7954 const intptr_t statement_pos = TokenPos(); | 7990 const intptr_t statement_pos = TokenPos(); |
7955 AstNode* statement = ParseStatement(); | 7991 AstNode* statement = ParseStatement(); |
7956 // Do not add statements with no effect (e.g., LoadLocalNode). | 7992 // Do not add statements with no effect (e.g., LoadLocalNode). |
7957 if ((statement != NULL) && statement->IsLoadLocalNode()) { | 7993 if ((statement != NULL) && statement->IsLoadLocalNode()) { |
7958 // Skip load local. | 7994 // Skip load local. |
7959 continue; | 7995 continue; |
7960 } | 7996 } |
7961 if (statement != NULL) { | 7997 if (statement != NULL) { |
7962 if (!dead_code_allowed && abrupt_completing_seen) { | 7998 if (!dead_code_allowed && abrupt_completing_seen) { |
(...skipping 19 matching lines...) Expand all Loading... |
7982 OpenBlock(); | 8018 OpenBlock(); |
7983 } | 8019 } |
7984 if (label != NULL) { | 8020 if (label != NULL) { |
7985 current_block_->scope->AddLabel(label); | 8021 current_block_->scope->AddLabel(label); |
7986 } | 8022 } |
7987 if (CurrentToken() == Token::kLBRACE) { | 8023 if (CurrentToken() == Token::kLBRACE) { |
7988 ConsumeToken(); | 8024 ConsumeToken(); |
7989 ParseStatementSequence(); | 8025 ParseStatementSequence(); |
7990 ExpectToken(Token::kRBRACE); | 8026 ExpectToken(Token::kRBRACE); |
7991 } else { | 8027 } else { |
| 8028 RecursionChecker rc(this); |
7992 AstNode* statement = ParseStatement(); | 8029 AstNode* statement = ParseStatement(); |
7993 if (statement != NULL) { | 8030 if (statement != NULL) { |
7994 current_block_->statements->Add(statement); | 8031 current_block_->statements->Add(statement); |
7995 } | 8032 } |
7996 } | 8033 } |
7997 SequenceNode* sequence = CloseBlock(); | 8034 SequenceNode* sequence = CloseBlock(); |
7998 return sequence; | 8035 return sequence; |
7999 } | 8036 } |
8000 | 8037 |
8001 | 8038 |
(...skipping 2731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10733 } | 10770 } |
10734 | 10771 |
10735 | 10772 |
10736 AstNode* Parser::ParseExpr(bool require_compiletime_const, | 10773 AstNode* Parser::ParseExpr(bool require_compiletime_const, |
10737 bool consume_cascades) { | 10774 bool consume_cascades) { |
10738 TRACE_PARSER("ParseExpr"); | 10775 TRACE_PARSER("ParseExpr"); |
10739 String* expr_ident = | 10776 String* expr_ident = |
10740 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 10777 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
10741 const intptr_t expr_pos = TokenPos(); | 10778 const intptr_t expr_pos = TokenPos(); |
10742 | 10779 |
| 10780 RecursionChecker rc(this); |
| 10781 |
10743 if (CurrentToken() == Token::kTHROW) { | 10782 if (CurrentToken() == Token::kTHROW) { |
10744 if (require_compiletime_const) { | 10783 if (require_compiletime_const) { |
10745 ReportError("'throw expr' is not a valid compile-time constant"); | 10784 ReportError("'throw expr' is not a valid compile-time constant"); |
10746 } | 10785 } |
10747 ConsumeToken(); | 10786 ConsumeToken(); |
10748 if (CurrentToken() == Token::kSEMICOLON) { | 10787 if (CurrentToken() == Token::kSEMICOLON) { |
10749 ReportError("expression expected after throw"); | 10788 ReportError("expression expected after throw"); |
10750 } | 10789 } |
10751 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); | 10790 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); |
10752 return new(Z) ThrowNode(expr_pos, expr, NULL); | 10791 return new(Z) ThrowNode(expr_pos, expr, NULL); |
(...skipping 3561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14314 const ArgumentListNode& function_args, | 14353 const ArgumentListNode& function_args, |
14315 const LocalVariable* temp_for_last_arg, | 14354 const LocalVariable* temp_for_last_arg, |
14316 bool is_super_invocation) { | 14355 bool is_super_invocation) { |
14317 UNREACHABLE(); | 14356 UNREACHABLE(); |
14318 return NULL; | 14357 return NULL; |
14319 } | 14358 } |
14320 | 14359 |
14321 } // namespace dart | 14360 } // namespace dart |
14322 | 14361 |
14323 #endif // DART_PRECOMPILED_RUNTIME | 14362 #endif // DART_PRECOMPILED_RUNTIME |
OLD | NEW |