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 |