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 7625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7636 } | 7636 } |
7637 } | 7637 } |
7638 CheckToken(Token::kLPAREN); | 7638 CheckToken(Token::kLPAREN); |
7639 | 7639 |
7640 // Check whether we have parsed this closure function before, in a previous | 7640 // Check whether we have parsed this closure function before, in a previous |
7641 // compilation. If so, reuse the function object, else create a new one | 7641 // compilation. If so, reuse the function object, else create a new one |
7642 // and register it in the current class. | 7642 // and register it in the current class. |
7643 // Note that we cannot share the same closure function between the closurized | 7643 // Note that we cannot share the same closure function between the closurized |
7644 // and non-closurized versions of the same parent function. | 7644 // and non-closurized versions of the same parent function. |
7645 Function& function = Function::ZoneHandle(Z); | 7645 Function& function = Function::ZoneHandle(Z); |
7646 bool found_func = true; | |
7647 // TODO(hausner): There could be two different closures at the given | 7646 // TODO(hausner): There could be two different closures at the given |
7648 // function_pos, one enclosed in a closurized function and one enclosed in the | 7647 // function_pos, one enclosed in a closurized function and one enclosed in the |
7649 // non-closurized version of this same function. | 7648 // non-closurized version of this same function. |
7650 function = I->LookupClosureFunction(innermost_function(), function_pos); | 7649 function = I->LookupClosureFunction(innermost_function(), function_pos); |
7651 if (function.IsNull()) { | 7650 if (function.IsNull()) { |
7652 // The function will be registered in the lookup table by the | 7651 // The function will be registered in the lookup table by the |
7653 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure | 7652 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure |
7654 // function has been properly setup. | 7653 // function has been properly setup. |
7655 found_func = false; | |
7656 function = Function::NewClosureFunction(*function_name, | 7654 function = Function::NewClosureFunction(*function_name, |
7657 innermost_function(), | 7655 innermost_function(), |
7658 function_pos); | 7656 function_pos); |
7659 function.set_result_type(result_type); | 7657 function.set_result_type(result_type); |
7660 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 7658 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
7661 library_.AddFunctionMetadata(function, metadata_pos); | 7659 library_.AddFunctionMetadata(function, metadata_pos); |
7662 } | 7660 } |
7663 } | 7661 } |
7664 | 7662 |
7665 // The function type needs to be finalized at compile time, since the closure | 7663 // The function type needs to be finalized at compile time, since the closure |
(...skipping 29 matching lines...) Expand all Loading... |
7695 current_block_->scope->LookupVariable(function_variable->name(), | 7693 current_block_->scope->LookupVariable(function_variable->name(), |
7696 true); | 7694 true); |
7697 ASSERT(existing_var != NULL); | 7695 ASSERT(existing_var != NULL); |
7698 // Use before define cases have already been detected and reported above. | 7696 // Use before define cases have already been detected and reported above. |
7699 ASSERT(existing_var->owner() == current_block_->scope); | 7697 ASSERT(existing_var->owner() == current_block_->scope); |
7700 ReportError(function_pos, "identifier '%s' already defined", | 7698 ReportError(function_pos, "identifier '%s' already defined", |
7701 function_variable->name().ToCString()); | 7699 function_variable->name().ToCString()); |
7702 } | 7700 } |
7703 } | 7701 } |
7704 | 7702 |
7705 Type& signature_type = Type::ZoneHandle(Z); | 7703 // Parse the local function. |
7706 SequenceNode* statements = NULL; | 7704 SequenceNode* statements = Parser::ParseFunc(function, !is_literal); |
7707 if (!found_func) { | 7705 INC_STAT(thread(), num_functions_parsed, 1); |
7708 // Parse the local function. As a side effect of the parsing, the | |
7709 // variables of this function's scope that are referenced by the local | |
7710 // function (and its inner nested functions) will be marked as captured. | |
7711 | 7706 |
7712 statements = Parser::ParseFunc(function, !is_literal); | 7707 // Now that the local function has formal parameters, lookup the signature |
7713 INC_STAT(thread(), num_functions_parsed, 1); | 7708 Type& signature_type = Type::ZoneHandle(Z, function.SignatureType()); |
7714 | 7709 signature_type ^= ClassFinalizer::FinalizeType( |
7715 // Now that the local function has formal parameters, lookup the signature | 7710 current_class(), signature_type, ClassFinalizer::kCanonicalize); |
7716 signature_type = function.SignatureType(); | 7711 function.SetSignatureType(signature_type); |
7717 signature_type ^= ClassFinalizer::FinalizeType( | |
7718 current_class(), signature_type, ClassFinalizer::kCanonicalize); | |
7719 function.SetSignatureType(signature_type); | |
7720 } else { | |
7721 // The local function was parsed before. The captured variables are | |
7722 // saved in the function's context scope. Iterate over the context scope | |
7723 // and mark its variables as captured. | |
7724 const ContextScope& context_scope = | |
7725 ContextScope::Handle(Z, function.context_scope()); | |
7726 ASSERT(!context_scope.IsNull()); | |
7727 String& var_name = String::Handle(Z); | |
7728 for (int i = 0; i < context_scope.num_variables(); i++) { | |
7729 var_name = context_scope.NameAt(i); | |
7730 // We need to look up the name in a way that returns even hidden | |
7731 // variables, e.g. 'this' in an initializer list. | |
7732 LocalVariable* v = current_block_->scope->LookupVariable(var_name, true); | |
7733 ASSERT(v != NULL); | |
7734 current_block_->scope->CaptureVariable(v); | |
7735 } | |
7736 SkipFunctionLiteral(); | |
7737 signature_type = function.SignatureType(); | |
7738 } | |
7739 | 7712 |
7740 // Local functions are registered in the enclosing class, but | 7713 // Local functions are registered in the enclosing class, but |
7741 // ignored during class finalization. The enclosing class has | 7714 // ignored during class finalization. The enclosing class has |
7742 // already been finalized. | 7715 // already been finalized. |
7743 ASSERT(current_class().is_finalized()); | 7716 ASSERT(current_class().is_finalized()); |
7744 ASSERT(signature_type.IsFinalized()); | 7717 ASSERT(signature_type.IsFinalized()); |
7745 | 7718 |
7746 // Make sure that the instantiator is captured. | 7719 // Make sure that the instantiator is captured. |
7747 if ((current_block_->scope->function_level() > 0) && | 7720 if ((current_block_->scope->function_level() > 0) && |
7748 Class::Handle(signature_type.type_class()).IsGeneric()) { | 7721 Class::Handle(signature_type.type_class()).IsGeneric()) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7783 // captured. The captured variables will be recorded along with their | 7756 // captured. The captured variables will be recorded along with their |
7784 // allocation information in a Scope object stored in the function object. | 7757 // allocation information in a Scope object stored in the function object. |
7785 // This Scope object is then provided to the compiler when compiling the local | 7758 // This Scope object is then provided to the compiler when compiling the local |
7786 // function. It would be too early to record the captured variables here, | 7759 // function. It would be too early to record the captured variables here, |
7787 // since further closure functions may capture more variables. | 7760 // since further closure functions may capture more variables. |
7788 // This Scope object is constructed after all variables have been allocated. | 7761 // This Scope object is constructed after all variables have been allocated. |
7789 // The local scope of the parsed function can be pruned, since contained | 7762 // The local scope of the parsed function can be pruned, since contained |
7790 // variables are not relevant for the compilation of the enclosing function. | 7763 // variables are not relevant for the compilation of the enclosing function. |
7791 // This pruning is done by omitting to hook the local scope in its parent | 7764 // This pruning is done by omitting to hook the local scope in its parent |
7792 // scope in the constructor of LocalScope. | 7765 // scope in the constructor of LocalScope. |
7793 AstNode* closure = | 7766 AstNode* closure = new(Z) ClosureNode( |
7794 new(Z) ClosureNode(function_pos, function, NULL, | 7767 function_pos, function, NULL, statements->scope()); |
7795 statements != NULL ? statements->scope() : NULL); | |
7796 | 7768 |
7797 if (function_variable == NULL) { | 7769 if (function_variable == NULL) { |
7798 ASSERT(is_literal); | 7770 ASSERT(is_literal); |
7799 return closure; | 7771 return closure; |
7800 } else { | 7772 } else { |
7801 AstNode* initialization = new(Z) StoreLocalNode( | 7773 AstNode* initialization = new(Z) StoreLocalNode( |
7802 function_pos, function_variable, closure); | 7774 function_pos, function_variable, closure); |
7803 return initialization; | 7775 return initialization; |
7804 } | 7776 } |
7805 } | 7777 } |
(...skipping 6754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14560 const ArgumentListNode& function_args, | 14532 const ArgumentListNode& function_args, |
14561 const LocalVariable* temp_for_last_arg, | 14533 const LocalVariable* temp_for_last_arg, |
14562 bool is_super_invocation) { | 14534 bool is_super_invocation) { |
14563 UNREACHABLE(); | 14535 UNREACHABLE(); |
14564 return NULL; | 14536 return NULL; |
14565 } | 14537 } |
14566 | 14538 |
14567 } // namespace dart | 14539 } // namespace dart |
14568 | 14540 |
14569 #endif // DART_PRECOMPILED_RUNTIME | 14541 #endif // DART_PRECOMPILED_RUNTIME |
OLD | NEW |