| 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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 8039 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8050 bool Parser::IsInstantiatorRequired() const { | 8050 bool Parser::IsInstantiatorRequired() const { |
| 8051 ASSERT(!current_function().IsNull()); | 8051 ASSERT(!current_function().IsNull()); |
| 8052 if (current_function().is_static() && | 8052 if (current_function().is_static() && |
| 8053 !current_function().IsInFactoryScope()) { | 8053 !current_function().IsInFactoryScope()) { |
| 8054 return false; | 8054 return false; |
| 8055 } | 8055 } |
| 8056 return current_class().NumTypeParameters() > 0; | 8056 return current_class().NumTypeParameters() > 0; |
| 8057 } | 8057 } |
| 8058 | 8058 |
| 8059 | 8059 |
| 8060 // If the field is already initialized, return no ast (NULL). | 8060 |
| 8061 // Otherwise, if the field is constant, initialize the field and return no ast. | 8061 // If the field is constant, initialize the field if necessary and return |
| 8062 // If the field is not initialized and not const, return the ast for the getter. | 8062 // no ast (NULL). |
| 8063 // Otherwise return NULL if no implicit getter exists (either never created |
| 8064 // because trivial, or not needed or field not readable). |
| 8063 AstNode* Parser::RunStaticFieldInitializer(const Field& field) { | 8065 AstNode* Parser::RunStaticFieldInitializer(const Field& field) { |
| 8064 ASSERT(field.is_static()); | 8066 ASSERT(field.is_static()); |
| 8067 const Class& field_owner = Class::ZoneHandle(field.owner()); |
| 8068 const String& field_name = String::ZoneHandle(field.name()); |
| 8069 const String& getter_name = String::Handle(Field::GetterName(field_name)); |
| 8070 const Function& getter = |
| 8071 Function::Handle(field_owner.LookupStaticFunction(getter_name)); |
| 8065 const Instance& value = Instance::Handle(field.value()); | 8072 const Instance& value = Instance::Handle(field.value()); |
| 8066 if (value.raw() == Object::transition_sentinel().raw()) { | 8073 if (value.raw() == Object::transition_sentinel().raw()) { |
| 8067 if (field.is_const()) { | 8074 if (field.is_const()) { |
| 8068 ErrorMsg("circular dependency while initializing static field '%s'", | 8075 ErrorMsg("circular dependency while initializing static field '%s'", |
| 8069 String::Handle(field.name()).ToCString()); | 8076 field_name.ToCString()); |
| 8070 } else { | 8077 } else { |
| 8071 // The implicit static getter will throw the exception if necessary. | 8078 // The implicit static getter will throw the exception if necessary. |
| 8072 return new StaticGetterNode(TokenPos(), | 8079 return new StaticGetterNode(TokenPos(), |
| 8073 NULL, | 8080 NULL, |
| 8074 false, | 8081 false, |
| 8075 Class::ZoneHandle(field.owner()), | 8082 field_owner, |
| 8076 String::ZoneHandle(field.name())); | 8083 field_name); |
| 8077 } | 8084 } |
| 8078 } else if (value.raw() == Object::sentinel().raw()) { | 8085 } else if (value.raw() == Object::sentinel().raw()) { |
| 8079 // This field has not been referenced yet and thus the value has | 8086 // This field has not been referenced yet and thus the value has |
| 8080 // not been evaluated. If the field is const, call the static getter method | 8087 // not been evaluated. If the field is const, call the static getter method |
| 8081 // to evaluate the expression and canonicalize the value. | 8088 // to evaluate the expression and canonicalize the value. |
| 8082 if (field.is_const()) { | 8089 if (field.is_const()) { |
| 8083 field.set_value(Object::transition_sentinel()); | 8090 field.set_value(Object::transition_sentinel()); |
| 8084 const String& field_name = String::Handle(field.name()); | |
| 8085 const String& getter_name = | |
| 8086 String::Handle(Field::GetterName(field_name)); | |
| 8087 const Class& cls = Class::Handle(field.owner()); | |
| 8088 const int kNumArguments = 0; // no arguments. | 8091 const int kNumArguments = 0; // no arguments. |
| 8089 const Function& func = | 8092 const Function& func = |
| 8090 Function::Handle(Resolver::ResolveStatic(cls, | 8093 Function::Handle(Resolver::ResolveStatic(field_owner, |
| 8091 getter_name, | 8094 getter_name, |
| 8092 kNumArguments, | 8095 kNumArguments, |
| 8093 Object::empty_array(), | 8096 Object::empty_array(), |
| 8094 Resolver::kIsQualified)); | 8097 Resolver::kIsQualified)); |
| 8095 ASSERT(!func.IsNull()); | 8098 ASSERT(!func.IsNull()); |
| 8096 ASSERT(func.kind() == RawFunction::kConstImplicitGetter); | 8099 ASSERT(func.kind() == RawFunction::kConstImplicitGetter); |
| 8097 Object& const_value = Object::Handle( | 8100 Object& const_value = Object::Handle( |
| 8098 DartEntry::InvokeFunction(func, Object::empty_array())); | 8101 DartEntry::InvokeFunction(func, Object::empty_array())); |
| 8099 if (const_value.IsError()) { | 8102 if (const_value.IsError()) { |
| 8100 const Error& error = Error::Cast(const_value); | 8103 const Error& error = Error::Cast(const_value); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 8113 isolate()->long_jump_base()->Jump(1, error); | 8116 isolate()->long_jump_base()->Jump(1, error); |
| 8114 } | 8117 } |
| 8115 } | 8118 } |
| 8116 ASSERT(const_value.IsNull() || const_value.IsInstance()); | 8119 ASSERT(const_value.IsNull() || const_value.IsInstance()); |
| 8117 Instance& instance = Instance::Handle(); | 8120 Instance& instance = Instance::Handle(); |
| 8118 instance ^= const_value.raw(); | 8121 instance ^= const_value.raw(); |
| 8119 if (!instance.IsNull()) { | 8122 if (!instance.IsNull()) { |
| 8120 instance ^= instance.Canonicalize(); | 8123 instance ^= instance.Canonicalize(); |
| 8121 } | 8124 } |
| 8122 field.set_value(instance); | 8125 field.set_value(instance); |
| 8126 return NULL; // Constant |
| 8123 } else { | 8127 } else { |
| 8124 return new StaticGetterNode(TokenPos(), | 8128 return new StaticGetterNode(TokenPos(), |
| 8125 NULL, | 8129 NULL, |
| 8126 false, | 8130 false, |
| 8127 Class::ZoneHandle(field.owner()), | 8131 field_owner, |
| 8128 String::ZoneHandle(field.name())); | 8132 field_name); |
| 8129 } | 8133 } |
| 8130 } | 8134 } |
| 8131 return NULL; | 8135 if (getter.IsNull() || (getter.kind() == RawFunction::kConstImplicitGetter)) { |
| 8136 return NULL; |
| 8137 } |
| 8138 ASSERT(getter.kind() == RawFunction::kImplicitGetter); |
| 8139 return new StaticGetterNode(TokenPos(), NULL, false, field_owner, field_name); |
| 8132 } | 8140 } |
| 8133 | 8141 |
| 8134 | 8142 |
| 8135 RawObject* Parser::EvaluateConstConstructorCall( | 8143 RawObject* Parser::EvaluateConstConstructorCall( |
| 8136 const Class& type_class, | 8144 const Class& type_class, |
| 8137 const AbstractTypeArguments& type_arguments, | 8145 const AbstractTypeArguments& type_arguments, |
| 8138 const Function& constructor, | 8146 const Function& constructor, |
| 8139 ArgumentListNode* arguments) { | 8147 ArgumentListNode* arguments) { |
| 8140 const int kNumExtraArgs = 2; // implicit rcvr and construction phase args. | 8148 const int kNumExtraArgs = 2; // implicit rcvr and construction phase args. |
| 8141 const int num_arguments = arguments->length() + kNumExtraArgs; | 8149 const int num_arguments = arguments->length() + kNumExtraArgs; |
| (...skipping 1838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9980 void Parser::SkipQualIdent() { | 9988 void Parser::SkipQualIdent() { |
| 9981 ASSERT(IsIdentifier()); | 9989 ASSERT(IsIdentifier()); |
| 9982 ConsumeToken(); | 9990 ConsumeToken(); |
| 9983 if (CurrentToken() == Token::kPERIOD) { | 9991 if (CurrentToken() == Token::kPERIOD) { |
| 9984 ConsumeToken(); // Consume the kPERIOD token. | 9992 ConsumeToken(); // Consume the kPERIOD token. |
| 9985 ExpectIdentifier("identifier expected after '.'"); | 9993 ExpectIdentifier("identifier expected after '.'"); |
| 9986 } | 9994 } |
| 9987 } | 9995 } |
| 9988 | 9996 |
| 9989 } // namespace dart | 9997 } // namespace dart |
| OLD | NEW |