Chromium Code Reviews| Index: runtime/vm/parser.cc |
| =================================================================== |
| --- runtime/vm/parser.cc (revision 26468) |
| +++ runtime/vm/parser.cc (working copy) |
| @@ -255,7 +255,8 @@ |
| current_class_(Class::Handle(isolate_)), |
| library_(Library::Handle(isolate_, library.raw())), |
| try_blocks_list_(NULL), |
| - last_used_try_index_(CatchClauseNode::kInvalidTryIndex) { |
| + last_used_try_index_(CatchClauseNode::kInvalidTryIndex), |
| + unregister_pending_function_(false) { |
| ASSERT(tokens_iterator_.IsValid()); |
| ASSERT(!library.IsNull()); |
| } |
| @@ -284,7 +285,8 @@ |
| isolate_, |
| parsed_function->function().origin()).library())), |
| try_blocks_list_(NULL), |
| - last_used_try_index_(CatchClauseNode::kInvalidTryIndex) { |
| + last_used_try_index_(CatchClauseNode::kInvalidTryIndex), |
| + unregister_pending_function_(false) { |
| ASSERT(tokens_iterator_.IsValid()); |
| ASSERT(!current_function().IsNull()); |
| if (FLAG_enable_type_checks) { |
| @@ -293,6 +295,19 @@ |
| } |
| +Parser::~Parser() { |
| + if (unregister_pending_function_) { |
| + const GrowableObjectArray& pending_functions = |
| + GrowableObjectArray::Handle( |
| + isolate()->object_store()->pending_functions()); |
| + ASSERT(pending_functions.Length() > 0); |
| + ASSERT(pending_functions.At(pending_functions.Length()-1) == |
| + current_function().raw()); |
| + pending_functions.RemoveLast(); |
| + } |
| +} |
| + |
| + |
| void Parser::SetScript(const Script & script, intptr_t token_pos) { |
| script_ = script.raw(); |
| tokens_iterator_.SetStream(TokenStream::Handle(script.tokens()), token_pos); |
| @@ -2360,6 +2375,22 @@ |
| } |
| +void Parser::CheckRecursiveInvocation() { |
| + const GrowableObjectArray& pending_functions = |
| + GrowableObjectArray::Handle( |
| + isolate()->object_store()->pending_functions()); |
| + for (int i = 0; i < pending_functions.Length(); i++) { |
| + if (pending_functions.At(i) == current_function().raw()) { |
| + const String& fname = |
| + String::Handle(current_function().UserVisibleName()); |
| + ErrorMsg("circular dependency for function %s", fname.ToCString()); |
| + } |
| + } |
|
srdjan
2013/08/21 23:39:09
ASSERT(!unregister_pending_function_) so that you
hausner
2013/08/21 23:57:13
Done.
|
| + pending_functions.Add(current_function()); |
| + unregister_pending_function_ = true; |
| +} |
| + |
| + |
| // Parser is at the opening parenthesis of the formal parameter declaration |
| // of function. Parse the formal parameters, initializers and code. |
| SequenceNode* Parser::ParseConstructor(const Function& func, |
| @@ -2372,6 +2403,8 @@ |
| const Class& cls = Class::Handle(func.Owner()); |
| ASSERT(!cls.IsNull()); |
| + CheckRecursiveInvocation(); |
| + |
| if (func.IsImplicitConstructor()) { |
| // Special case: implicit constructor. |
| // The parser adds an implicit default constructor when a class |