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

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
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/raw_object_snapshot.cc » ('j') | 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 6873 matching lines...) Expand 10 before | Expand all | Expand 10 after
6884 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); 6884 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle()));
6885 // List existingArgumentNames. 6885 // List existingArgumentNames.
6886 // Check if there exists a function with the same name. 6886 // Check if there exists a function with the same name.
6887 Function& function = 6887 Function& function =
6888 Function::Handle(cls.LookupStaticFunction(function_name)); 6888 Function::Handle(cls.LookupStaticFunction(function_name));
6889 if (function.IsNull()) { 6889 if (function.IsNull()) {
6890 // TODO(srdjan): Store argument values into the argument list. 6890 // TODO(srdjan): Store argument values into the argument list.
6891 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); 6891 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle()));
6892 } else { 6892 } else {
6893 const int total_num_parameters = function.NumParameters(); 6893 const int total_num_parameters = function.NumParameters();
6894 Array& array = Array::ZoneHandle(Array::New(total_num_parameters)); 6894 Array& array =
6895 array ^= array.Canonicalize(); 6895 Array::ZoneHandle(Array::New(total_num_parameters, Heap::kOld));
6896 // Skip receiver. 6896 // Skip receiver.
6897 for (int i = 0; i < total_num_parameters; i++) { 6897 for (int i = 0; i < total_num_parameters; i++) {
6898 array.SetAt(i, String::Handle(function.ParameterNameAt(i))); 6898 array.SetAt(i, String::Handle(function.ParameterNameAt(i)));
6899 } 6899 }
6900 arguments->Add(new LiteralNode(call_pos, array)); 6900 arguments->Add(new LiteralNode(call_pos, array));
6901 } 6901 }
6902 return MakeStaticCall(Symbols::NoSuchMethodError(), 6902 return MakeStaticCall(Symbols::NoSuchMethodError(),
6903 PrivateCoreLibName(Symbols::ThrowNew()), 6903 PrivateCoreLibName(Symbols::ThrowNew()),
6904 arguments); 6904 arguments);
6905 } 6905 }
(...skipping 1234 matching lines...) Expand 10 before | Expand all | Expand 10 after
8140 bool Parser::IsInstantiatorRequired() const { 8140 bool Parser::IsInstantiatorRequired() const {
8141 ASSERT(!current_function().IsNull()); 8141 ASSERT(!current_function().IsNull());
8142 if (current_function().is_static() && 8142 if (current_function().is_static() &&
8143 !current_function().IsInFactoryScope()) { 8143 !current_function().IsInFactoryScope()) {
8144 return false; 8144 return false;
8145 } 8145 }
8146 return current_class().NumTypeParameters() > 0; 8146 return current_class().NumTypeParameters() > 0;
8147 } 8147 }
8148 8148
8149 8149
8150 RawInstance* Parser::TryCanonicalize(const Instance& instance,
8151 intptr_t token_pos) {
8152 if (instance.IsNull()) {
8153 return instance.raw();
8154 }
8155 const char* error_str = NULL;
8156 Instance& result =
8157 Instance::Handle(instance.CheckAndCanonicalize(&error_str));
8158 if (result.IsNull()) {
8159 ErrorMsg(token_pos, "Invalid const object %s", error_str);
8160 }
8161 return result.raw();
8162 }
8150 8163
8151 // If the field is constant, initialize the field if necessary and return 8164
8152 // no ast (NULL). 8165 // If the field is already initialized, return no ast (NULL).
8153 // Otherwise return NULL if no implicit getter exists (either never created 8166 // Otherwise, if the field is constant, initialize the field and return no ast.
8154 // because trivial, or not needed or field not readable). 8167 // If the field is not initialized and not const, return the ast for the getter.
8155 AstNode* Parser::RunStaticFieldInitializer(const Field& field) { 8168 AstNode* Parser::RunStaticFieldInitializer(const Field& field) {
8156 ASSERT(field.is_static()); 8169 ASSERT(field.is_static());
8157 const Class& field_owner = Class::ZoneHandle(field.owner()); 8170 const Class& field_owner = Class::ZoneHandle(field.owner());
8158 const String& field_name = String::ZoneHandle(field.name()); 8171 const String& field_name = String::ZoneHandle(field.name());
8159 const String& getter_name = String::Handle(Field::GetterName(field_name)); 8172 const String& getter_name = String::Handle(Field::GetterName(field_name));
8160 const Function& getter = 8173 const Function& getter =
8161 Function::Handle(field_owner.LookupStaticFunction(getter_name)); 8174 Function::Handle(field_owner.LookupStaticFunction(getter_name));
8162 const Instance& value = Instance::Handle(field.value()); 8175 const Instance& value = Instance::Handle(field.value());
8163 if (value.raw() == Object::transition_sentinel().raw()) { 8176 if (value.raw() == Object::transition_sentinel().raw()) {
8164 if (field.is_const()) { 8177 if (field.is_const()) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
8202 AppendErrorMsg(error, TokenPos(), 8215 AppendErrorMsg(error, TokenPos(),
8203 "error initializing const field '%s'", 8216 "error initializing const field '%s'",
8204 String::Handle(field.name()).ToCString()); 8217 String::Handle(field.name()).ToCString());
8205 } else { 8218 } else {
8206 isolate()->long_jump_base()->Jump(1, error); 8219 isolate()->long_jump_base()->Jump(1, error);
8207 } 8220 }
8208 } 8221 }
8209 ASSERT(const_value.IsNull() || const_value.IsInstance()); 8222 ASSERT(const_value.IsNull() || const_value.IsInstance());
8210 Instance& instance = Instance::Handle(); 8223 Instance& instance = Instance::Handle();
8211 instance ^= const_value.raw(); 8224 instance ^= const_value.raw();
8212 if (!instance.IsNull()) { 8225 instance = TryCanonicalize(instance, TokenPos());
8213 instance ^= instance.Canonicalize();
8214 }
8215 field.set_value(instance); 8226 field.set_value(instance);
8216 return NULL; // Constant 8227 return NULL; // Constant
8217 } else { 8228 } else {
8218 return new StaticGetterNode(TokenPos(), 8229 return new StaticGetterNode(TokenPos(),
8219 NULL, 8230 NULL,
8220 false, 8231 false,
8221 field_owner, 8232 field_owner,
8222 field_name); 8233 field_name);
8223 } 8234 }
8224 } 8235 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
8269 // not optimizable. 8280 // not optimizable.
8270 current_function().set_is_optimizable(false); 8281 current_function().set_is_optimizable(false);
8271 if (result.IsUnhandledException()) { 8282 if (result.IsUnhandledException()) {
8272 return result.raw(); 8283 return result.raw();
8273 } else { 8284 } else {
8274 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); 8285 isolate()->long_jump_base()->Jump(1, Error::Cast(result));
8275 UNREACHABLE(); 8286 UNREACHABLE();
8276 return Object::null(); 8287 return Object::null();
8277 } 8288 }
8278 } else { 8289 } else {
8279 if (!instance.IsNull()) { 8290 return TryCanonicalize(instance, TokenPos());
8280 instance ^= instance.Canonicalize();
8281 }
8282 return instance.raw();
8283 } 8291 }
8284 } 8292 }
8285 8293
8286 8294
8287 // Do a lookup for the identifier in the block scope and the class scope 8295 // Do a lookup for the identifier in the block scope and the class scope
8288 // return true if the identifier is found, false otherwise. 8296 // return true if the identifier is found, false otherwise.
8289 // If node is non NULL return an AST node corresponding to the identifier. 8297 // If node is non NULL return an AST node corresponding to the identifier.
8290 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, 8298 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos,
8291 const String &ident, 8299 const String &ident,
8292 AstNode** node) { 8300 AstNode** node) {
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after
8912 } else { 8920 } else {
8913 ErrorMsg(elem->AsLiteralNode()->token_pos(), 8921 ErrorMsg(elem->AsLiteralNode()->token_pos(),
8914 "list literal element at index %d must be " 8922 "list literal element at index %d must be "
8915 "a constant of type '%s'", 8923 "a constant of type '%s'",
8916 i, 8924 i,
8917 String::Handle(element_type.UserVisibleName()).ToCString()); 8925 String::Handle(element_type.UserVisibleName()).ToCString());
8918 } 8926 }
8919 } 8927 }
8920 const_list.SetAt(i, elem->AsLiteralNode()->literal()); 8928 const_list.SetAt(i, elem->AsLiteralNode()->literal());
8921 } 8929 }
8922 const_list ^= const_list.Canonicalize(); 8930 const_list ^= TryCanonicalize(const_list, literal_pos);
8923 const_list.MakeImmutable(); 8931 const_list.MakeImmutable();
8924 return new LiteralNode(literal_pos, const_list); 8932 return new LiteralNode(literal_pos, const_list);
8925 } else { 8933 } else {
8926 // Factory call at runtime. 8934 // Factory call at runtime.
8927 const Class& factory_class = 8935 const Class& factory_class =
8928 Class::Handle(LookupCoreClass(Symbols::List())); 8936 Class::Handle(LookupCoreClass(Symbols::List()));
8929 ASSERT(!factory_class.IsNull()); 8937 ASSERT(!factory_class.IsNull());
8930 const Function& factory_method = Function::ZoneHandle( 8938 const Function& factory_method = Function::ZoneHandle(
8931 factory_class.LookupFactory( 8939 factory_class.LookupFactory(
8932 PrivateCoreLibName(Symbols::ListLiteralFactory()))); 8940 PrivateCoreLibName(Symbols::ListLiteralFactory())));
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
9109 } else { 9117 } else {
9110 ErrorMsg(arg->AsLiteralNode()->token_pos(), 9118 ErrorMsg(arg->AsLiteralNode()->token_pos(),
9111 "map literal value at index %d must be " 9119 "map literal value at index %d must be "
9112 "a constant of type '%s'", 9120 "a constant of type '%s'",
9113 i >> 1, 9121 i >> 1,
9114 String::Handle(value_type.UserVisibleName()).ToCString()); 9122 String::Handle(value_type.UserVisibleName()).ToCString());
9115 } 9123 }
9116 } 9124 }
9117 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); 9125 key_value_array.SetAt(i, arg->AsLiteralNode()->literal());
9118 } 9126 }
9119 key_value_array ^= key_value_array.Canonicalize(); 9127 key_value_array ^= TryCanonicalize(key_value_array, TokenPos());
9120 key_value_array.MakeImmutable(); 9128 key_value_array.MakeImmutable();
9121 9129
9122 // Construct the map object. 9130 // Construct the map object.
9123 const Class& immutable_map_class = 9131 const Class& immutable_map_class =
9124 Class::Handle(LookupCoreClass(Symbols::ImmutableMap())); 9132 Class::Handle(LookupCoreClass(Symbols::ImmutableMap()));
9125 ASSERT(!immutable_map_class.IsNull()); 9133 ASSERT(!immutable_map_class.IsNull());
9126 // If the immutable map class extends other parameterized classes, we need 9134 // If the immutable map class extends other parameterized classes, we need
9127 // to adjust the type argument vector. This is currently not the case. 9135 // to adjust the type argument vector. This is currently not the case.
9128 ASSERT(immutable_map_class.NumTypeArguments() == 2); 9136 ASSERT(immutable_map_class.NumTypeArguments() == 2);
9129 ArgumentListNode* constr_args = new ArgumentListNode(TokenPos()); 9137 ArgumentListNode* constr_args = new ArgumentListNode(TokenPos());
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after
9783 9791
9784 Object& result = Object::Handle(Compiler::ExecuteOnce(seq)); 9792 Object& result = Object::Handle(Compiler::ExecuteOnce(seq));
9785 if (result.IsError()) { 9793 if (result.IsError()) {
9786 // Propagate the compilation error. 9794 // Propagate the compilation error.
9787 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); 9795 isolate()->long_jump_base()->Jump(1, Error::Cast(result));
9788 UNREACHABLE(); 9796 UNREACHABLE();
9789 } 9797 }
9790 ASSERT(result.IsInstance()); 9798 ASSERT(result.IsInstance());
9791 Instance& value = Instance::ZoneHandle(); 9799 Instance& value = Instance::ZoneHandle();
9792 value ^= result.raw(); 9800 value ^= result.raw();
9793 if (!value.IsNull()) { 9801 value = TryCanonicalize(value, TokenPos());
9794 value ^= value.Canonicalize();
9795 }
9796 return value; 9802 return value;
9797 } 9803 }
9798 } 9804 }
9799 9805
9800 9806
9801 void Parser::SkipFunctionLiteral() { 9807 void Parser::SkipFunctionLiteral() {
9802 if (IsIdentifier()) { 9808 if (IsIdentifier()) {
9803 if (LookaheadToken(1) != Token::kLPAREN) { 9809 if (LookaheadToken(1) != Token::kLPAREN) {
9804 SkipType(true); 9810 SkipType(true);
9805 } 9811 }
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
10079 void Parser::SkipQualIdent() { 10085 void Parser::SkipQualIdent() {
10080 ASSERT(IsIdentifier()); 10086 ASSERT(IsIdentifier());
10081 ConsumeToken(); 10087 ConsumeToken();
10082 if (CurrentToken() == Token::kPERIOD) { 10088 if (CurrentToken() == Token::kPERIOD) {
10083 ConsumeToken(); // Consume the kPERIOD token. 10089 ConsumeToken(); // Consume the kPERIOD token.
10084 ExpectIdentifier("identifier expected after '.'"); 10090 ExpectIdentifier("identifier expected after '.'");
10085 } 10091 }
10086 } 10092 }
10087 10093
10088 } // namespace dart 10094 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/raw_object_snapshot.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698