| 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 6873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |