| 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 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 743 } | 743 } |
| 744 parsed_function->SetNodeSequence(node_sequence); | 744 parsed_function->SetNodeSequence(node_sequence); |
| 745 | 745 |
| 746 // The instantiator may be required at run time for generic type checks or | 746 // The instantiator may be required at run time for generic type checks or |
| 747 // allocation of generic types. | 747 // allocation of generic types. |
| 748 if (parser.IsInstantiatorRequired()) { | 748 if (parser.IsInstantiatorRequired()) { |
| 749 // In the case of a local function, only set the instantiator if the | 749 // In the case of a local function, only set the instantiator if the |
| 750 // receiver was captured. | 750 // receiver was captured. |
| 751 const bool kTestOnly = true; | 751 const bool kTestOnly = true; |
| 752 LocalVariable* receiver = | 752 LocalVariable* receiver = |
| 753 parser.LookupReceiver(node_sequence->scope(), | 753 parser.LookupReceiver(node_sequence->scope(), kTestOnly); |
| 754 kTestOnly); | |
| 755 if (!parser.current_function().IsLocalFunction() || | 754 if (!parser.current_function().IsLocalFunction() || |
| 756 ((receiver != NULL) && receiver->is_captured())) { | 755 ((receiver != NULL) && receiver->is_captured())) { |
| 757 parsed_function->set_instantiator( | 756 parsed_function->set_instantiator( |
| 758 new LoadLocalNode(node_sequence->token_pos(), *receiver)); | 757 new LoadLocalNode(node_sequence->token_pos(), *receiver)); |
| 759 } | 758 } |
| 760 } | 759 } |
| 761 | 760 |
| 762 parsed_function->set_default_parameter_values(default_parameter_values); | 761 parsed_function->set_default_parameter_values(default_parameter_values); |
| 763 isolate->set_ast_node_id(prev_ast_node_id); | 762 isolate->set_ast_node_id(prev_ast_node_id); |
| 764 } | 763 } |
| (...skipping 3255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4020 if (native_function == NULL) { | 4019 if (native_function == NULL) { |
| 4021 ErrorMsg(native_pos, "native function '%s' cannot be found", | 4020 ErrorMsg(native_pos, "native function '%s' cannot be found", |
| 4022 native_name.ToCString()); | 4021 native_name.ToCString()); |
| 4023 } | 4022 } |
| 4024 | 4023 |
| 4025 const bool has_opt_params = (params->num_optional_parameters > 0); | 4024 const bool has_opt_params = (params->num_optional_parameters > 0); |
| 4026 | 4025 |
| 4027 // Now add the NativeBodyNode and return statement. | 4026 // Now add the NativeBodyNode and return statement. |
| 4028 current_block_->statements->Add( | 4027 current_block_->statements->Add( |
| 4029 new ReturnNode(TokenPos(), new NativeBodyNode(TokenPos(), | 4028 new ReturnNode(TokenPos(), new NativeBodyNode(TokenPos(), |
| 4030 native_name, | 4029 native_name, |
| 4031 native_function, | 4030 native_function, |
| 4032 num_parameters, | 4031 num_parameters, |
| 4033 has_opt_params, | 4032 has_opt_params, |
| 4034 is_instance_closure))); | 4033 is_instance_closure))); |
| 4035 } | 4034 } |
| 4036 | 4035 |
| 4037 | 4036 |
| 4038 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, | 4037 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { |
| 4039 bool test_only) { | |
| 4040 const String& this_name = String::Handle(String::NewSymbol(kThisName)); | 4038 const String& this_name = String::Handle(String::NewSymbol(kThisName)); |
| 4041 return from_scope->LookupVariable(this_name, test_only); | 4039 return from_scope->LookupVariable(this_name, test_only); |
| 4042 } | 4040 } |
| 4043 | 4041 |
| 4044 | 4042 |
| 4045 LocalVariable* Parser::LookupPhaseParameter() { | 4043 LocalVariable* Parser::LookupPhaseParameter() { |
| 4046 const String& phase_name = | 4044 const String& phase_name = |
| 4047 String::Handle(String::NewSymbol(kPhaseParameterName)); | 4045 String::Handle(String::NewSymbol(kPhaseParameterName)); |
| 4048 const bool kTestOnly = false; | 4046 const bool kTestOnly = false; |
| 4049 return current_block_->scope->LookupVariable(phase_name, kTestOnly); | 4047 return current_block_->scope->LookupVariable(phase_name, kTestOnly); |
| (...skipping 2353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6403 const Array& kNoArgumentNames = Array::Handle(); | 6401 const Array& kNoArgumentNames = Array::Handle(); |
| 6404 func = Resolver::ResolveStatic(cls, | 6402 func = Resolver::ResolveStatic(cls, |
| 6405 getter_name, | 6403 getter_name, |
| 6406 kNumArguments, | 6404 kNumArguments, |
| 6407 kNoArgumentNames, | 6405 kNoArgumentNames, |
| 6408 Resolver::kIsQualified); | 6406 Resolver::kIsQualified); |
| 6409 if (!func.IsNull()) { | 6407 if (!func.IsNull()) { |
| 6410 ASSERT(func.kind() != RawFunction::kConstImplicitGetter); | 6408 ASSERT(func.kind() != RawFunction::kConstImplicitGetter); |
| 6411 EnsureExpressionTemp(); | 6409 EnsureExpressionTemp(); |
| 6412 closure = new StaticGetterNode(call_pos, | 6410 closure = new StaticGetterNode(call_pos, |
| 6411 NULL, |
| 6413 Class::ZoneHandle(cls.raw()), | 6412 Class::ZoneHandle(cls.raw()), |
| 6414 func_name); | 6413 func_name); |
| 6415 return new ClosureCallNode(call_pos, closure, arguments); | 6414 return new ClosureCallNode(call_pos, closure, arguments); |
| 6416 } | 6415 } |
| 6417 } else { | 6416 } else { |
| 6418 EnsureExpressionTemp(); | 6417 EnsureExpressionTemp(); |
| 6419 closure = GenerateStaticFieldLookup(field, call_pos); | 6418 closure = GenerateStaticFieldLookup(field, call_pos); |
| 6420 return new ClosureCallNode(call_pos, closure, arguments); | 6419 return new ClosureCallNode(call_pos, closure, arguments); |
| 6421 } | 6420 } |
| 6422 // Could not resolve static method: throw an exception if the arguments | 6421 // Could not resolve static method: throw an exception if the arguments |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6539 AstNode* value = ParseExpr(kAllowConst); | 6538 AstNode* value = ParseExpr(kAllowConst); |
| 6540 AstNode* load_access = NULL; | 6539 AstNode* load_access = NULL; |
| 6541 if (field.IsNull()) { | 6540 if (field.IsNull()) { |
| 6542 // No field found, we must have at least a setter function defined. | 6541 // No field found, we must have at least a setter function defined. |
| 6543 ASSERT(!func.IsNull()); | 6542 ASSERT(!func.IsNull()); |
| 6544 // Explicit setter function for the field found, field does not exist. | 6543 // Explicit setter function for the field found, field does not exist. |
| 6545 // Create a getter node first in case it is needed. If getter node | 6544 // Create a getter node first in case it is needed. If getter node |
| 6546 // is used as part of, e.g., "+=", and the explicit getter does not | 6545 // is used as part of, e.g., "+=", and the explicit getter does not |
| 6547 // exist, and error will be reported by the code generator. | 6546 // exist, and error will be reported by the code generator. |
| 6548 load_access = new StaticGetterNode(call_pos, | 6547 load_access = new StaticGetterNode(call_pos, |
| 6548 NULL, |
| 6549 Class::ZoneHandle(cls.raw()), | 6549 Class::ZoneHandle(cls.raw()), |
| 6550 String::ZoneHandle(field_name.raw())); | 6550 String::ZoneHandle(field_name.raw())); |
| 6551 } else { | 6551 } else { |
| 6552 // Field exists. | 6552 // Field exists. |
| 6553 if (field.is_final()) { | 6553 if (field.is_final()) { |
| 6554 // Field has been marked as final, report an error as the field | 6554 // Field has been marked as final, report an error as the field |
| 6555 // is not settable. | 6555 // is not settable. |
| 6556 ErrorMsg(ident_pos, | 6556 ErrorMsg(ident_pos, |
| 6557 "field '%s' is const static, cannot assign to it", | 6557 "field '%s' is const static, cannot assign to it", |
| 6558 field_name.ToCString()); | 6558 field_name.ToCString()); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 6581 if (func.IsNull()) { | 6581 if (func.IsNull()) { |
| 6582 // No field or explicit getter function, this is an error. | 6582 // No field or explicit getter function, this is an error. |
| 6583 ErrorMsg(ident_pos, | 6583 ErrorMsg(ident_pos, |
| 6584 "unknown static field '%s'", field_name.ToCString()); | 6584 "unknown static field '%s'", field_name.ToCString()); |
| 6585 return access; | 6585 return access; |
| 6586 } | 6586 } |
| 6587 access = CreateImplicitClosureNode(func, call_pos, NULL); | 6587 access = CreateImplicitClosureNode(func, call_pos, NULL); |
| 6588 } else { | 6588 } else { |
| 6589 ASSERT(func.kind() != RawFunction::kConstImplicitGetter); | 6589 ASSERT(func.kind() != RawFunction::kConstImplicitGetter); |
| 6590 access = new StaticGetterNode(call_pos, | 6590 access = new StaticGetterNode(call_pos, |
| 6591 NULL, |
| 6591 Class::ZoneHandle(cls.raw()), | 6592 Class::ZoneHandle(cls.raw()), |
| 6592 field_name); | 6593 field_name); |
| 6593 } | 6594 } |
| 6594 } else { | 6595 } else { |
| 6595 return GenerateStaticFieldLookup(field, TokenPos()); | 6596 return GenerateStaticFieldLookup(field, TokenPos()); |
| 6596 } | 6597 } |
| 6597 } | 6598 } |
| 6598 return access; | 6599 return access; |
| 6599 } | 6600 } |
| 6600 | 6601 |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6957 AstNode* Parser::RunStaticFieldInitializer(const Field& field) { | 6958 AstNode* Parser::RunStaticFieldInitializer(const Field& field) { |
| 6958 ASSERT(field.is_static()); | 6959 ASSERT(field.is_static()); |
| 6959 const Instance& value = Instance::Handle(field.value()); | 6960 const Instance& value = Instance::Handle(field.value()); |
| 6960 if (value.raw() == Object::transition_sentinel()) { | 6961 if (value.raw() == Object::transition_sentinel()) { |
| 6961 if (field.is_const()) { | 6962 if (field.is_const()) { |
| 6962 ErrorMsg("circular dependency while initializing static field '%s'", | 6963 ErrorMsg("circular dependency while initializing static field '%s'", |
| 6963 String::Handle(field.name()).ToCString()); | 6964 String::Handle(field.name()).ToCString()); |
| 6964 } else { | 6965 } else { |
| 6965 // The implicit static getter will throw the exception if necessary. | 6966 // The implicit static getter will throw the exception if necessary. |
| 6966 return new StaticGetterNode(TokenPos(), | 6967 return new StaticGetterNode(TokenPos(), |
| 6968 NULL, |
| 6967 Class::ZoneHandle(field.owner()), | 6969 Class::ZoneHandle(field.owner()), |
| 6968 String::ZoneHandle(field.name())); | 6970 String::ZoneHandle(field.name())); |
| 6969 } | 6971 } |
| 6970 } else if (value.raw() == Object::sentinel()) { | 6972 } else if (value.raw() == Object::sentinel()) { |
| 6971 // This field has not been referenced yet and thus the value has | 6973 // This field has not been referenced yet and thus the value has |
| 6972 // not been evaluated. If the field is const, call the static getter method | 6974 // not been evaluated. If the field is const, call the static getter method |
| 6973 // to evaluate the expression and canonicalize the value. | 6975 // to evaluate the expression and canonicalize the value. |
| 6974 if (field.is_const()) { | 6976 if (field.is_const()) { |
| 6975 field.set_value(Instance::Handle(Object::transition_sentinel())); | 6977 field.set_value(Instance::Handle(Object::transition_sentinel())); |
| 6976 const String& field_name = String::Handle(field.name()); | 6978 const String& field_name = String::Handle(field.name()); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 7005 } | 7007 } |
| 7006 ASSERT(const_value.IsNull() || const_value.IsInstance()); | 7008 ASSERT(const_value.IsNull() || const_value.IsInstance()); |
| 7007 Instance& instance = Instance::Handle(); | 7009 Instance& instance = Instance::Handle(); |
| 7008 instance ^= const_value.raw(); | 7010 instance ^= const_value.raw(); |
| 7009 if (!instance.IsNull()) { | 7011 if (!instance.IsNull()) { |
| 7010 instance ^= instance.Canonicalize(); | 7012 instance ^= instance.Canonicalize(); |
| 7011 } | 7013 } |
| 7012 field.set_value(instance); | 7014 field.set_value(instance); |
| 7013 } else { | 7015 } else { |
| 7014 return new StaticGetterNode(TokenPos(), | 7016 return new StaticGetterNode(TokenPos(), |
| 7017 NULL, |
| 7015 Class::ZoneHandle(field.owner()), | 7018 Class::ZoneHandle(field.owner()), |
| 7016 String::ZoneHandle(field.name())); | 7019 String::ZoneHandle(field.name())); |
| 7017 } | 7020 } |
| 7018 } | 7021 } |
| 7019 return NULL; | 7022 return NULL; |
| 7020 } | 7023 } |
| 7021 | 7024 |
| 7022 | 7025 |
| 7023 RawObject* Parser::EvaluateConstConstructorCall( | 7026 RawObject* Parser::EvaluateConstConstructorCall( |
| 7024 const Class& type_class, | 7027 const Class& type_class, |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7128 if (func.IsDynamicFunction()) { | 7131 if (func.IsDynamicFunction()) { |
| 7129 if (node != NULL) { | 7132 if (node != NULL) { |
| 7130 CheckInstanceFieldAccess(ident_pos, ident); | 7133 CheckInstanceFieldAccess(ident_pos, ident); |
| 7131 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 7134 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 7132 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 7135 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
| 7133 } | 7136 } |
| 7134 return true; | 7137 return true; |
| 7135 } else if (func.IsStaticFunction()) { | 7138 } else if (func.IsStaticFunction()) { |
| 7136 if (node != NULL) { | 7139 if (node != NULL) { |
| 7137 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 7140 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 7141 // The static getter may be changed later into an instance setter. |
| 7142 AstNode* receiver = NULL; |
| 7143 const bool kTestOnly = true; |
| 7144 if ((!current_function().is_static() || |
| 7145 current_function().IsInFactoryScope()) && |
| 7146 (LookupReceiver(current_block_->scope, kTestOnly) != NULL)) { |
| 7147 receiver = LoadReceiver(ident_pos); |
| 7148 } |
| 7138 *node = new StaticGetterNode(ident_pos, | 7149 *node = new StaticGetterNode(ident_pos, |
| 7150 receiver, |
| 7139 Class::ZoneHandle(isolate, cls.raw()), | 7151 Class::ZoneHandle(isolate, cls.raw()), |
| 7140 ident); | 7152 ident); |
| 7141 } | 7153 } |
| 7142 return true; | 7154 return true; |
| 7143 } | 7155 } |
| 7144 } | 7156 } |
| 7145 func = cls.LookupSetterFunction(ident); | 7157 func = cls.LookupSetterFunction(ident); |
| 7146 if (!func.IsNull()) { | 7158 if (!func.IsNull()) { |
| 7147 if (func.IsDynamicFunction()) { | 7159 if (func.IsDynamicFunction()) { |
| 7148 if (node != NULL) { | 7160 if (node != NULL) { |
| 7149 // We create a getter node even though a getter doesn't exist as | 7161 // We create a getter node even though a getter doesn't exist as |
| 7150 // it could be followed by an assignment which will convert it to | 7162 // it could be followed by an assignment which will convert it to |
| 7151 // a setter node. If there is no assignment we will get an error | 7163 // a setter node. If there is no assignment we will get an error |
| 7152 // when we try to invoke the getter. | 7164 // when we try to invoke the getter. |
| 7153 CheckInstanceFieldAccess(ident_pos, ident); | 7165 CheckInstanceFieldAccess(ident_pos, ident); |
| 7154 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 7166 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 7155 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 7167 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
| 7156 } | 7168 } |
| 7157 return true; | 7169 return true; |
| 7158 } else if (func.IsStaticFunction()) { | 7170 } else if (func.IsStaticFunction()) { |
| 7159 if (node != NULL) { | 7171 if (node != NULL) { |
| 7160 // We create a getter node even though a getter doesn't exist as | 7172 // We create a getter node even though a getter doesn't exist as |
| 7161 // it could be followed by an assignment which will convert it to | 7173 // it could be followed by an assignment which will convert it to |
| 7162 // a setter node. If there is no assignment we will get an error | 7174 // a setter node. If there is no assignment we will get an error |
| 7163 // when we try to invoke the getter. | 7175 // when we try to invoke the getter. |
| 7164 *node = new StaticGetterNode(ident_pos, | 7176 *node = new StaticGetterNode(ident_pos, |
| 7177 NULL, |
| 7165 Class::ZoneHandle(isolate, cls.raw()), | 7178 Class::ZoneHandle(isolate, cls.raw()), |
| 7166 ident); | 7179 ident); |
| 7167 } | 7180 } |
| 7168 return true; | 7181 return true; |
| 7169 } | 7182 } |
| 7170 } | 7183 } |
| 7171 | 7184 |
| 7172 // Nothing found in scope of current class. | 7185 // Nothing found in scope of current class. |
| 7173 if (node != NULL) { | 7186 if (node != NULL) { |
| 7174 *node = NULL; | 7187 *node = NULL; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7226 } else { | 7239 } else { |
| 7227 obj = lib.LookupObject(accessor_name); | 7240 obj = lib.LookupObject(accessor_name); |
| 7228 } | 7241 } |
| 7229 } | 7242 } |
| 7230 if (!obj.IsNull()) { | 7243 if (!obj.IsNull()) { |
| 7231 ASSERT(obj.IsFunction()); | 7244 ASSERT(obj.IsFunction()); |
| 7232 const Function& func = Function::Cast(obj); | 7245 const Function& func = Function::Cast(obj); |
| 7233 ASSERT(func.is_static()); | 7246 ASSERT(func.is_static()); |
| 7234 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 7247 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 7235 return new StaticGetterNode(qual_ident.ident_pos, | 7248 return new StaticGetterNode(qual_ident.ident_pos, |
| 7249 NULL, |
| 7236 Class::ZoneHandle(func.owner()), | 7250 Class::ZoneHandle(func.owner()), |
| 7237 *qual_ident.ident); | 7251 *qual_ident.ident); |
| 7238 } | 7252 } |
| 7239 if (qual_ident.lib_prefix != NULL) { | 7253 if (qual_ident.lib_prefix != NULL) { |
| 7240 return NULL; | 7254 return NULL; |
| 7241 } | 7255 } |
| 7242 // Lexically unresolved primary identifiers are referenced by their name. | 7256 // Lexically unresolved primary identifiers are referenced by their name. |
| 7243 return new PrimaryNode(qual_ident.ident_pos, *qual_ident.ident); | 7257 return new PrimaryNode(qual_ident.ident_pos, *qual_ident.ident); |
| 7244 } | 7258 } |
| 7245 | 7259 |
| (...skipping 1374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8620 void Parser::SkipQualIdent() { | 8634 void Parser::SkipQualIdent() { |
| 8621 ASSERT(IsIdentifier()); | 8635 ASSERT(IsIdentifier()); |
| 8622 ConsumeToken(); | 8636 ConsumeToken(); |
| 8623 if (CurrentToken() == Token::kPERIOD) { | 8637 if (CurrentToken() == Token::kPERIOD) { |
| 8624 ConsumeToken(); // Consume the kPERIOD token. | 8638 ConsumeToken(); // Consume the kPERIOD token. |
| 8625 ExpectIdentifier("identifier expected after '.'"); | 8639 ExpectIdentifier("identifier expected after '.'"); |
| 8626 } | 8640 } |
| 8627 } | 8641 } |
| 8628 | 8642 |
| 8629 } // namespace dart | 8643 } // namespace dart |
| OLD | NEW |