Chromium Code Reviews| 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 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 3894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3905 } | 3905 } |
| 3906 const String& anonymous_function_name = | 3906 const String& anonymous_function_name = |
| 3907 String::ZoneHandle(String::NewSymbol("function")); | 3907 String::ZoneHandle(String::NewSymbol("function")); |
| 3908 function_name = &anonymous_function_name; | 3908 function_name = &anonymous_function_name; |
| 3909 } | 3909 } |
| 3910 ASSERT(ident_pos >= 0); | 3910 ASSERT(ident_pos >= 0); |
| 3911 | 3911 |
| 3912 if (CurrentToken() != Token::kLPAREN) { | 3912 if (CurrentToken() != Token::kLPAREN) { |
| 3913 ErrorMsg("'(' expected"); | 3913 ErrorMsg("'(' expected"); |
| 3914 } | 3914 } |
| 3915 Function& function = Function::ZoneHandle( | 3915 intptr_t function_pos = token_index_; |
| 3916 Function::NewClosureFunction(*function_name, | 3916 |
| 3917 current_function(), | 3917 // Check whether we have parsed this closure before, in a previous |
| 3918 token_index_)); | 3918 // compilation. If so, reuse the function object, else create a new one |
| 3919 function.set_result_type(result_type); | 3919 // and register it in the current class. |
| 3920 Function& function = Function::ZoneHandle(); | |
| 3921 bool is_new_closure = false; | |
| 3922 function = current_class().LookupClosureFunction(function_pos); | |
| 3923 if (function.IsNull() || (function.token_index() != function_pos)) { | |
| 3924 is_new_closure = true; | |
| 3925 function = Function::NewClosureFunction(*function_name, | |
| 3926 current_function(), | |
| 3927 function_pos); | |
| 3928 function.set_result_type(result_type); | |
| 3929 current_class().AddClosureFunction(function); | |
| 3930 } | |
| 3920 | 3931 |
| 3921 // The function type does not need to be determined at compile time, unless | 3932 // The function type does not need to be determined at compile time, unless |
| 3922 // the closure is assigned to a function variable and type checks are enabled. | 3933 // the closure is assigned to a function variable and type checks are enabled. |
| 3923 // At run time, the function type is derived from the signature class of the | 3934 // At run time, the function type is derived from the signature class of the |
| 3924 // closure function and from the type arguments of the instantiator. | 3935 // closure function and from the type arguments of the instantiator. |
| 3925 | 3936 |
| 3926 LocalVariable* function_variable = NULL; | 3937 LocalVariable* function_variable = NULL; |
| 3927 Type& function_type = Type::ZoneHandle(); | 3938 Type& function_type = Type::ZoneHandle(); |
| 3928 if (variable_name != NULL) { | 3939 if (variable_name != NULL) { |
| 3929 // Since the function type depends on the signature of the closure function, | 3940 // Since the function type depends on the signature of the closure function, |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 3948 if (!current_block_->scope->AddVariable(function_variable)) { | 3959 if (!current_block_->scope->AddVariable(function_variable)) { |
| 3949 ErrorMsg(ident_pos, "identifier '%s' already defined", | 3960 ErrorMsg(ident_pos, "identifier '%s' already defined", |
| 3950 function_variable->name().ToCString()); | 3961 function_variable->name().ToCString()); |
| 3951 } | 3962 } |
| 3952 } | 3963 } |
| 3953 | 3964 |
| 3954 // Parse the local function. | 3965 // Parse the local function. |
| 3955 Array& default_parameter_values = Array::Handle(); | 3966 Array& default_parameter_values = Array::Handle(); |
| 3956 SequenceNode* statements = Parser::ParseFunc(function, | 3967 SequenceNode* statements = Parser::ParseFunc(function, |
| 3957 default_parameter_values); | 3968 default_parameter_values); |
| 3969 ASSERT(is_new_closure || (function.end_token_index() == token_index_)); | |
| 3970 function.set_end_token_index(token_index_); | |
| 3958 | 3971 |
| 3959 // Now that the local function has formal parameters, lookup the signature | 3972 // Now that the local function has formal parameters, lookup the signature |
| 3960 // class in the current library (but not in its imports) and only create a new | 3973 // class in the current library (but not in its imports) and only create a new |
| 3961 // canonical signature class if it does not exist yet. | 3974 // canonical signature class if it does not exist yet. |
| 3962 const String& signature = String::Handle(function.Signature()); | 3975 const String& signature = String::Handle(function.Signature()); |
| 3963 Class& signature_class = Class::ZoneHandle( | 3976 Class& signature_class = Class::ZoneHandle( |
| 3964 library_.LookupLocalClass(signature)); | 3977 library_.LookupLocalClass(signature)); |
| 3978 | |
| 3965 if (signature_class.IsNull()) { | 3979 if (signature_class.IsNull()) { |
| 3980 // If we don't have a signature class yet, this must be a closure we | |
| 3981 // have not parsed before. | |
| 3982 ASSERT(is_new_closure); | |
| 3966 signature_class = Class::NewSignatureClass(signature, | 3983 signature_class = Class::NewSignatureClass(signature, |
| 3967 function, | 3984 function, |
| 3968 script_); | 3985 script_); |
| 3969 // Record the function signature class in the current library. | 3986 // Record the function signature class in the current library. |
| 3970 library_.AddClass(signature_class); | 3987 library_.AddClass(signature_class); |
| 3971 } else { | 3988 } else if (is_new_closure) { |
| 3972 function.set_signature_class(signature_class); | 3989 function.set_signature_class(signature_class); |
| 3973 } | 3990 } |
| 3974 ASSERT(function.signature_class() == signature_class.raw()); | 3991 ASSERT(function.signature_class() == signature_class.raw()); |
| 3975 // Local functions are not registered in the enclosing class, which is already | |
| 3976 // finalized. | |
| 3977 ASSERT(current_class().is_finalized()); | |
|
regis
2012/03/16 22:04:01
I would not remove this assert, but just change th
hausner
2012/03/16 22:20:58
Done.
| |
| 3978 | 3992 |
| 3979 // Make sure that the instantiator is captured. | 3993 // Make sure that the instantiator is captured. |
| 3980 if ((signature_class.NumTypeParameters() > 0) && | 3994 if ((signature_class.NumTypeParameters() > 0) && |
| 3981 (current_block_->scope->function_level() > 0)) { | 3995 (current_block_->scope->function_level() > 0)) { |
| 3982 CaptureReceiver(); | 3996 CaptureReceiver(); |
| 3983 } | 3997 } |
| 3984 | 3998 |
| 3985 if (variable_name != NULL) { | 3999 if (variable_name != NULL) { |
| 3986 // Patch the function type now that the signature is known. | 4000 // Patch the function type now that the signature is known. |
| 3987 // We need to create a new type for proper finalization, since the existing | 4001 // We need to create a new type for proper finalization, since the existing |
| (...skipping 4223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8211 void Parser::SkipQualIdent() { | 8225 void Parser::SkipQualIdent() { |
| 8212 ASSERT(IsIdentifier()); | 8226 ASSERT(IsIdentifier()); |
| 8213 ConsumeToken(); | 8227 ConsumeToken(); |
| 8214 if (CurrentToken() == Token::kPERIOD) { | 8228 if (CurrentToken() == Token::kPERIOD) { |
| 8215 ConsumeToken(); // Consume the kPERIOD token. | 8229 ConsumeToken(); // Consume the kPERIOD token. |
| 8216 ExpectIdentifier("identifier expected after '.'"); | 8230 ExpectIdentifier("identifier expected after '.'"); |
| 8217 } | 8231 } |
| 8218 } | 8232 } |
| 8219 | 8233 |
| 8220 } // namespace dart | 8234 } // namespace dart |
| OLD | NEW |