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

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

Issue 16780009: When canonicalize instances check if all fields are canonical. If a field is a non-canonical number… (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
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 6783 matching lines...) Expand 10 before | Expand all | Expand 10 after
6794 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); 6794 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle()));
6795 // List existingArgumentNames. 6795 // List existingArgumentNames.
6796 // Check if there exists a function with the same name. 6796 // Check if there exists a function with the same name.
6797 Function& function = 6797 Function& function =
6798 Function::Handle(cls.LookupStaticFunction(function_name)); 6798 Function::Handle(cls.LookupStaticFunction(function_name));
6799 if (function.IsNull()) { 6799 if (function.IsNull()) {
6800 // TODO(srdjan): Store argument values into the argument list. 6800 // TODO(srdjan): Store argument values into the argument list.
6801 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); 6801 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle()));
6802 } else { 6802 } else {
6803 const int total_num_parameters = function.NumParameters(); 6803 const int total_num_parameters = function.NumParameters();
6804 Array& array = Array::ZoneHandle(Array::New(total_num_parameters)); 6804 Array& array =
6805 array ^= array.Canonicalize(); 6805 Array::ZoneHandle(Array::New(total_num_parameters, Heap::kOld));
6806 // Skip receiver. 6806 // Skip receiver.
6807 for (int i = 0; i < total_num_parameters; i++) { 6807 for (int i = 0; i < total_num_parameters; i++) {
6808 array.SetAt(i, String::Handle(function.ParameterNameAt(i))); 6808 array.SetAt(i, String::Handle(function.ParameterNameAt(i)));
6809 } 6809 }
6810 arguments->Add(new LiteralNode(call_pos, array)); 6810 arguments->Add(new LiteralNode(call_pos, array));
6811 } 6811 }
6812 return MakeStaticCall(Symbols::NoSuchMethodError(), 6812 return MakeStaticCall(Symbols::NoSuchMethodError(),
6813 PrivateCoreLibName(Symbols::ThrowNew()), 6813 PrivateCoreLibName(Symbols::ThrowNew()),
6814 arguments); 6814 arguments);
6815 } 6815 }
(...skipping 1234 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 RawInstance* Parser::TryCanonicalize(const Instance& instance) {
8061 if (instance.IsNull()) {
8062 return instance.raw();
8063 }
8064 const char* error_str = NULL;
8065 Instance& result =
8066 Instance::Handle(instance.CheckAndCanonicalize(&error_str));
8067 if (result.IsNull()) {
8068 ErrorMsg("Invalid const object %s", error_str);
hausner 2013/06/11 23:29:24 The error position is not necessarily the current
srdjan 2013/06/12 00:22:22 Done.
8069 }
8070 return result.raw();
8071 }
8072
8073
8060 // If the field is already initialized, return no ast (NULL). 8074 // If the field is already initialized, return no ast (NULL).
8061 // Otherwise, if the field is constant, initialize the field and return no ast. 8075 // Otherwise, if the field is constant, initialize the field and return no ast.
8062 // If the field is not initialized and not const, return the ast for the getter. 8076 // If the field is not initialized and not const, return the ast for the getter.
8063 AstNode* Parser::RunStaticFieldInitializer(const Field& field) { 8077 AstNode* Parser::RunStaticFieldInitializer(const Field& field) {
8064 ASSERT(field.is_static()); 8078 ASSERT(field.is_static());
8065 const Instance& value = Instance::Handle(field.value()); 8079 const Instance& value = Instance::Handle(field.value());
8066 if (value.raw() == Object::transition_sentinel().raw()) { 8080 if (value.raw() == Object::transition_sentinel().raw()) {
8067 if (field.is_const()) { 8081 if (field.is_const()) {
8068 ErrorMsg("circular dependency while initializing static field '%s'", 8082 ErrorMsg("circular dependency while initializing static field '%s'",
8069 String::Handle(field.name()).ToCString()); 8083 String::Handle(field.name()).ToCString());
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
8109 AppendErrorMsg(error, TokenPos(), 8123 AppendErrorMsg(error, TokenPos(),
8110 "error initializing const field '%s'", 8124 "error initializing const field '%s'",
8111 String::Handle(field.name()).ToCString()); 8125 String::Handle(field.name()).ToCString());
8112 } else { 8126 } else {
8113 isolate()->long_jump_base()->Jump(1, error); 8127 isolate()->long_jump_base()->Jump(1, error);
8114 } 8128 }
8115 } 8129 }
8116 ASSERT(const_value.IsNull() || const_value.IsInstance()); 8130 ASSERT(const_value.IsNull() || const_value.IsInstance());
8117 Instance& instance = Instance::Handle(); 8131 Instance& instance = Instance::Handle();
8118 instance ^= const_value.raw(); 8132 instance ^= const_value.raw();
8119 if (!instance.IsNull()) { 8133 instance = TryCanonicalize(instance);
8120 instance ^= instance.Canonicalize();
8121 }
8122 field.set_value(instance); 8134 field.set_value(instance);
8123 } else { 8135 } else {
8124 return new StaticGetterNode(TokenPos(), 8136 return new StaticGetterNode(TokenPos(),
8125 NULL, 8137 NULL,
8126 false, 8138 false,
8127 Class::ZoneHandle(field.owner()), 8139 Class::ZoneHandle(field.owner()),
8128 String::ZoneHandle(field.name())); 8140 String::ZoneHandle(field.name()));
8129 } 8141 }
8130 } 8142 }
8131 return NULL; 8143 return NULL;
8132 } 8144 }
8133 8145
8134 8146
8135 RawObject* Parser::EvaluateConstConstructorCall( 8147 RawObject* Parser::EvaluateConstConstructorCall(
8136 const Class& type_class, 8148 const Class& type_class,
8137 const AbstractTypeArguments& type_arguments, 8149 const AbstractTypeArguments& type_arguments,
8138 const Function& constructor, 8150 const Function& constructor,
8139 ArgumentListNode* arguments) { 8151 ArgumentListNode* arguments) {
8140 const int kNumExtraArgs = 2; // implicit rcvr and construction phase args. 8152 const int kNumExtraArgs = 2; // implicit rcvr and construction phase args.
8141 const int num_arguments = arguments->length() + kNumExtraArgs; 8153 const int num_arguments = arguments->length() + kNumExtraArgs;
8142 const Array& arg_values = Array::Handle(Array::New(num_arguments)); 8154 const Array& arg_values = Array::Handle(Array::New(num_arguments));
8143 Instance& instance = Instance::Handle(); 8155 Instance& instance = Instance::Handle();
8144 ASSERT(!constructor.IsFactory()); 8156 ASSERT(!constructor.IsFactory());
8145 instance = Instance::New(type_class, Heap::kOld); 8157 instance ^= Instance::New(type_class, Heap::kOld);
hausner 2013/06/11 23:29:24 Why ^= ?
srdjan 2013/06/12 00:22:22 Weird ... removed.
8146 if (!type_arguments.IsNull()) { 8158 if (!type_arguments.IsNull()) {
8147 if (!type_arguments.IsInstantiated()) { 8159 if (!type_arguments.IsInstantiated()) {
8148 ErrorMsg("type must be constant in const constructor"); 8160 ErrorMsg("type must be constant in const constructor");
8149 } 8161 }
8150 instance.SetTypeArguments( 8162 instance.SetTypeArguments(
8151 AbstractTypeArguments::Handle(type_arguments.Canonicalize())); 8163 AbstractTypeArguments::Handle(type_arguments.Canonicalize()));
8152 } 8164 }
8153 arg_values.SetAt(0, instance); 8165 arg_values.SetAt(0, instance);
8154 arg_values.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll))); 8166 arg_values.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
8155 for (int i = 0; i < arguments->length(); i++) { 8167 for (int i = 0; i < arguments->length(); i++) {
(...skipping 15 matching lines...) Expand all
8171 // not optimizable. 8183 // not optimizable.
8172 current_function().set_is_optimizable(false); 8184 current_function().set_is_optimizable(false);
8173 if (result.IsUnhandledException()) { 8185 if (result.IsUnhandledException()) {
8174 return result.raw(); 8186 return result.raw();
8175 } else { 8187 } else {
8176 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); 8188 isolate()->long_jump_base()->Jump(1, Error::Cast(result));
8177 UNREACHABLE(); 8189 UNREACHABLE();
8178 return Object::null(); 8190 return Object::null();
8179 } 8191 }
8180 } else { 8192 } else {
8181 if (!instance.IsNull()) { 8193 return TryCanonicalize(instance);
8182 instance ^= instance.Canonicalize();
8183 }
8184 return instance.raw();
8185 } 8194 }
8186 } 8195 }
8187 8196
8188 8197
8189 // Do a lookup for the identifier in the block scope and the class scope 8198 // Do a lookup for the identifier in the block scope and the class scope
8190 // return true if the identifier is found, false otherwise. 8199 // return true if the identifier is found, false otherwise.
8191 // If node is non NULL return an AST node corresponding to the identifier. 8200 // If node is non NULL return an AST node corresponding to the identifier.
8192 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, 8201 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos,
8193 const String &ident, 8202 const String &ident,
8194 AstNode** node) { 8203 AstNode** node) {
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after
8814 } else { 8823 } else {
8815 ErrorMsg(elem->AsLiteralNode()->token_pos(), 8824 ErrorMsg(elem->AsLiteralNode()->token_pos(),
8816 "list literal element at index %d must be " 8825 "list literal element at index %d must be "
8817 "a constant of type '%s'", 8826 "a constant of type '%s'",
8818 i, 8827 i,
8819 String::Handle(element_type.UserVisibleName()).ToCString()); 8828 String::Handle(element_type.UserVisibleName()).ToCString());
8820 } 8829 }
8821 } 8830 }
8822 const_list.SetAt(i, elem->AsLiteralNode()->literal()); 8831 const_list.SetAt(i, elem->AsLiteralNode()->literal());
8823 } 8832 }
8824 const_list ^= const_list.Canonicalize(); 8833 const_list ^= TryCanonicalize(const_list);
8825 const_list.MakeImmutable(); 8834 const_list.MakeImmutable();
8826 return new LiteralNode(literal_pos, const_list); 8835 return new LiteralNode(literal_pos, const_list);
8827 } else { 8836 } else {
8828 // Factory call at runtime. 8837 // Factory call at runtime.
8829 const Class& factory_class = 8838 const Class& factory_class =
8830 Class::Handle(LookupCoreClass(Symbols::List())); 8839 Class::Handle(LookupCoreClass(Symbols::List()));
8831 ASSERT(!factory_class.IsNull()); 8840 ASSERT(!factory_class.IsNull());
8832 const Function& factory_method = Function::ZoneHandle( 8841 const Function& factory_method = Function::ZoneHandle(
8833 factory_class.LookupFactory( 8842 factory_class.LookupFactory(
8834 PrivateCoreLibName(Symbols::ListLiteralFactory()))); 8843 PrivateCoreLibName(Symbols::ListLiteralFactory())));
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
9011 } else { 9020 } else {
9012 ErrorMsg(arg->AsLiteralNode()->token_pos(), 9021 ErrorMsg(arg->AsLiteralNode()->token_pos(),
9013 "map literal value at index %d must be " 9022 "map literal value at index %d must be "
9014 "a constant of type '%s'", 9023 "a constant of type '%s'",
9015 i >> 1, 9024 i >> 1,
9016 String::Handle(value_type.UserVisibleName()).ToCString()); 9025 String::Handle(value_type.UserVisibleName()).ToCString());
9017 } 9026 }
9018 } 9027 }
9019 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); 9028 key_value_array.SetAt(i, arg->AsLiteralNode()->literal());
9020 } 9029 }
9021 key_value_array ^= key_value_array.Canonicalize(); 9030 key_value_array ^= TryCanonicalize(key_value_array);
9022 key_value_array.MakeImmutable(); 9031 key_value_array.MakeImmutable();
9023 9032
9024 // Construct the map object. 9033 // Construct the map object.
9025 const Class& immutable_map_class = 9034 const Class& immutable_map_class =
9026 Class::Handle(LookupCoreClass(Symbols::ImmutableMap())); 9035 Class::Handle(LookupCoreClass(Symbols::ImmutableMap()));
9027 ASSERT(!immutable_map_class.IsNull()); 9036 ASSERT(!immutable_map_class.IsNull());
9028 // If the immutable map class extends other parameterized classes, we need 9037 // If the immutable map class extends other parameterized classes, we need
9029 // to adjust the type argument vector. This is currently not the case. 9038 // to adjust the type argument vector. This is currently not the case.
9030 ASSERT(immutable_map_class.NumTypeArguments() == 2); 9039 ASSERT(immutable_map_class.NumTypeArguments() == 2);
9031 ArgumentListNode* constr_args = new ArgumentListNode(TokenPos()); 9040 ArgumentListNode* constr_args = new ArgumentListNode(TokenPos());
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
9684 9693
9685 Object& result = Object::Handle(Compiler::ExecuteOnce(seq)); 9694 Object& result = Object::Handle(Compiler::ExecuteOnce(seq));
9686 if (result.IsError()) { 9695 if (result.IsError()) {
9687 // Propagate the compilation error. 9696 // Propagate the compilation error.
9688 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); 9697 isolate()->long_jump_base()->Jump(1, Error::Cast(result));
9689 UNREACHABLE(); 9698 UNREACHABLE();
9690 } 9699 }
9691 ASSERT(result.IsInstance()); 9700 ASSERT(result.IsInstance());
9692 Instance& value = Instance::ZoneHandle(); 9701 Instance& value = Instance::ZoneHandle();
9693 value ^= result.raw(); 9702 value ^= result.raw();
9694 if (!value.IsNull()) { 9703 value = TryCanonicalize(value);
9695 value ^= value.Canonicalize();
9696 }
9697 return value; 9704 return value;
9698 } 9705 }
9699 } 9706 }
9700 9707
9701 9708
9702 void Parser::SkipFunctionLiteral() { 9709 void Parser::SkipFunctionLiteral() {
9703 if (IsIdentifier()) { 9710 if (IsIdentifier()) {
9704 if (LookaheadToken(1) != Token::kLPAREN) { 9711 if (LookaheadToken(1) != Token::kLPAREN) {
9705 SkipType(true); 9712 SkipType(true);
9706 } 9713 }
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
9980 void Parser::SkipQualIdent() { 9987 void Parser::SkipQualIdent() {
9981 ASSERT(IsIdentifier()); 9988 ASSERT(IsIdentifier());
9982 ConsumeToken(); 9989 ConsumeToken();
9983 if (CurrentToken() == Token::kPERIOD) { 9990 if (CurrentToken() == Token::kPERIOD) {
9984 ConsumeToken(); // Consume the kPERIOD token. 9991 ConsumeToken(); // Consume the kPERIOD token.
9985 ExpectIdentifier("identifier expected after '.'"); 9992 ExpectIdentifier("identifier expected after '.'");
9986 } 9993 }
9987 } 9994 }
9988 9995
9989 } // namespace dart 9996 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698