Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(234)

Side by Side Diff: runtime/vm/parser.cc

Issue 16136014: Make AST generation deterministic: always call a static getter if it exists, regardless if the stat… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698