| 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 7595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7606 } | 7606 } |
| 7607 } | 7607 } |
| 7608 CheckToken(Token::kLPAREN); | 7608 CheckToken(Token::kLPAREN); |
| 7609 | 7609 |
| 7610 // Check whether we have parsed this closure function before, in a previous | 7610 // Check whether we have parsed this closure function before, in a previous |
| 7611 // compilation. If so, reuse the function object, else create a new one | 7611 // compilation. If so, reuse the function object, else create a new one |
| 7612 // and register it in the current class. | 7612 // and register it in the current class. |
| 7613 // Note that we cannot share the same closure function between the closurized | 7613 // Note that we cannot share the same closure function between the closurized |
| 7614 // and non-closurized versions of the same parent function. | 7614 // and non-closurized versions of the same parent function. |
| 7615 Function& function = Function::ZoneHandle(Z); | 7615 Function& function = Function::ZoneHandle(Z); |
| 7616 bool found_func = true; | |
| 7617 // TODO(hausner): There could be two different closures at the given | 7616 // TODO(hausner): There could be two different closures at the given |
| 7618 // function_pos, one enclosed in a closurized function and one enclosed in the | 7617 // function_pos, one enclosed in a closurized function and one enclosed in the |
| 7619 // non-closurized version of this same function. | 7618 // non-closurized version of this same function. |
| 7620 function = I->LookupClosureFunction(innermost_function(), function_pos); | 7619 function = I->LookupClosureFunction(innermost_function(), function_pos); |
| 7621 if (function.IsNull()) { | 7620 if (function.IsNull()) { |
| 7622 // The function will be registered in the lookup table by the | 7621 // The function will be registered in the lookup table by the |
| 7623 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure | 7622 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure |
| 7624 // function has been properly setup. | 7623 // function has been properly setup. |
| 7625 found_func = false; | |
| 7626 function = Function::NewClosureFunction(*function_name, | 7624 function = Function::NewClosureFunction(*function_name, |
| 7627 innermost_function(), | 7625 innermost_function(), |
| 7628 function_pos); | 7626 function_pos); |
| 7629 function.set_result_type(result_type); | 7627 function.set_result_type(result_type); |
| 7630 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 7628 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
| 7631 library_.AddFunctionMetadata(function, metadata_pos); | 7629 library_.AddFunctionMetadata(function, metadata_pos); |
| 7632 } | 7630 } |
| 7633 } | 7631 } |
| 7634 | 7632 |
| 7635 // The function type needs to be finalized at compile time, since the closure | 7633 // The function type needs to be finalized at compile time, since the closure |
| (...skipping 29 matching lines...) Expand all Loading... |
| 7665 current_block_->scope->LookupVariable(function_variable->name(), | 7663 current_block_->scope->LookupVariable(function_variable->name(), |
| 7666 true); | 7664 true); |
| 7667 ASSERT(existing_var != NULL); | 7665 ASSERT(existing_var != NULL); |
| 7668 // Use before define cases have already been detected and reported above. | 7666 // Use before define cases have already been detected and reported above. |
| 7669 ASSERT(existing_var->owner() == current_block_->scope); | 7667 ASSERT(existing_var->owner() == current_block_->scope); |
| 7670 ReportError(function_pos, "identifier '%s' already defined", | 7668 ReportError(function_pos, "identifier '%s' already defined", |
| 7671 function_variable->name().ToCString()); | 7669 function_variable->name().ToCString()); |
| 7672 } | 7670 } |
| 7673 } | 7671 } |
| 7674 | 7672 |
| 7673 // Parse the local function. |
| 7674 SequenceNode* statements = Parser::ParseFunc(function, !is_literal); |
| 7675 INC_STAT(thread(), num_functions_parsed, 1); |
| 7675 | 7676 |
| 7676 Type& signature_type = Type::ZoneHandle(Z); | 7677 // Now that the local function has formal parameters, lookup the signature |
| 7677 SequenceNode* statements = NULL; | 7678 Type& signature_type = Type::ZoneHandle(Z, function.SignatureType()); |
| 7678 if (!found_func) { | 7679 signature_type ^= ClassFinalizer::FinalizeType( |
| 7679 // Parse the local function. As a side effect of the parsing, the | 7680 current_class(), signature_type, ClassFinalizer::kCanonicalize); |
| 7680 // variables of this function's scope that are referenced by the local | 7681 function.SetSignatureType(signature_type); |
| 7681 // function (and its inner nested functions) will be marked as captured. | |
| 7682 statements = Parser::ParseFunc(function, !is_literal); | |
| 7683 INC_STAT(thread(), num_functions_parsed, 1); | |
| 7684 | |
| 7685 // Now that the local function has formal parameters, lookup the signature | |
| 7686 signature_type = function.SignatureType(); | |
| 7687 signature_type ^= ClassFinalizer::FinalizeType( | |
| 7688 current_class(), signature_type, ClassFinalizer::kCanonicalize); | |
| 7689 function.SetSignatureType(signature_type); | |
| 7690 } else { | |
| 7691 // The local function was parsed before. The captured variables are | |
| 7692 // saved in the function's context scope. Iterate over the context scope | |
| 7693 // and mark its variables as captured. | |
| 7694 const ContextScope& context_scope = | |
| 7695 ContextScope::Handle(Z, function.context_scope()); | |
| 7696 ASSERT(!context_scope.IsNull()); | |
| 7697 String& var_name = String::Handle(Z); | |
| 7698 for (int i = 0; i < context_scope.num_variables(); i++) { | |
| 7699 var_name = context_scope.NameAt(i); | |
| 7700 // We need to look up the name in a way that returns even hidden | |
| 7701 // variables, e.g. 'this' in an initializer list. | |
| 7702 LocalVariable* v = current_block_->scope->LookupVariable(var_name, true); | |
| 7703 ASSERT(v != NULL); | |
| 7704 current_block_->scope->CaptureVariable(v); | |
| 7705 } | |
| 7706 SkipFunctionLiteral(); | |
| 7707 signature_type = function.SignatureType(); | |
| 7708 } | |
| 7709 | 7682 |
| 7710 // Local functions are registered in the enclosing class, but | 7683 // Local functions are registered in the enclosing class, but |
| 7711 // ignored during class finalization. The enclosing class has | 7684 // ignored during class finalization. The enclosing class has |
| 7712 // already been finalized. | 7685 // already been finalized. |
| 7713 ASSERT(current_class().is_finalized()); | 7686 ASSERT(current_class().is_finalized()); |
| 7714 ASSERT(signature_type.IsFinalized()); | 7687 ASSERT(signature_type.IsFinalized()); |
| 7715 | 7688 |
| 7716 // Make sure that the instantiator is captured. | 7689 // Make sure that the instantiator is captured. |
| 7717 if ((current_block_->scope->function_level() > 0) && | 7690 if ((current_block_->scope->function_level() > 0) && |
| 7718 Class::Handle(signature_type.type_class()).IsGeneric()) { | 7691 Class::Handle(signature_type.type_class()).IsGeneric()) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7753 // captured. The captured variables will be recorded along with their | 7726 // captured. The captured variables will be recorded along with their |
| 7754 // allocation information in a Scope object stored in the function object. | 7727 // allocation information in a Scope object stored in the function object. |
| 7755 // This Scope object is then provided to the compiler when compiling the local | 7728 // This Scope object is then provided to the compiler when compiling the local |
| 7756 // function. It would be too early to record the captured variables here, | 7729 // function. It would be too early to record the captured variables here, |
| 7757 // since further closure functions may capture more variables. | 7730 // since further closure functions may capture more variables. |
| 7758 // This Scope object is constructed after all variables have been allocated. | 7731 // This Scope object is constructed after all variables have been allocated. |
| 7759 // The local scope of the parsed function can be pruned, since contained | 7732 // The local scope of the parsed function can be pruned, since contained |
| 7760 // variables are not relevant for the compilation of the enclosing function. | 7733 // variables are not relevant for the compilation of the enclosing function. |
| 7761 // This pruning is done by omitting to hook the local scope in its parent | 7734 // This pruning is done by omitting to hook the local scope in its parent |
| 7762 // scope in the constructor of LocalScope. | 7735 // scope in the constructor of LocalScope. |
| 7763 AstNode* closure = | 7736 AstNode* closure = new(Z) ClosureNode( |
| 7764 new(Z) ClosureNode(function_pos, function, NULL, | 7737 function_pos, function, NULL, statements->scope()); |
| 7765 statements != NULL ? statements->scope() : NULL); | |
| 7766 | 7738 |
| 7767 if (function_variable == NULL) { | 7739 if (function_variable == NULL) { |
| 7768 ASSERT(is_literal); | 7740 ASSERT(is_literal); |
| 7769 return closure; | 7741 return closure; |
| 7770 } else { | 7742 } else { |
| 7771 AstNode* initialization = new(Z) StoreLocalNode( | 7743 AstNode* initialization = new(Z) StoreLocalNode( |
| 7772 function_pos, function_variable, closure); | 7744 function_pos, function_variable, closure); |
| 7773 return initialization; | 7745 return initialization; |
| 7774 } | 7746 } |
| 7775 } | 7747 } |
| (...skipping 6752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14528 const ArgumentListNode& function_args, | 14500 const ArgumentListNode& function_args, |
| 14529 const LocalVariable* temp_for_last_arg, | 14501 const LocalVariable* temp_for_last_arg, |
| 14530 bool is_super_invocation) { | 14502 bool is_super_invocation) { |
| 14531 UNREACHABLE(); | 14503 UNREACHABLE(); |
| 14532 return NULL; | 14504 return NULL; |
| 14533 } | 14505 } |
| 14534 | 14506 |
| 14535 } // namespace dart | 14507 } // namespace dart |
| 14536 | 14508 |
| 14537 #endif // DART_PRECOMPILED_RUNTIME | 14509 #endif // DART_PRECOMPILED_RUNTIME |
| OLD | NEW |