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 |