| 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 6785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6796 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); | 6796 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); |
| 6797 // List existingArgumentNames. | 6797 // List existingArgumentNames. |
| 6798 // Check if there exists a function with the same name. | 6798 // Check if there exists a function with the same name. |
| 6799 Function& function = | 6799 Function& function = |
| 6800 Function::Handle(cls.LookupStaticFunction(function_name)); | 6800 Function::Handle(cls.LookupStaticFunction(function_name)); |
| 6801 if (function.IsNull()) { | 6801 if (function.IsNull()) { |
| 6802 // TODO(srdjan): Store argument values into the argument list. | 6802 // TODO(srdjan): Store argument values into the argument list. |
| 6803 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); | 6803 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); |
| 6804 } else { | 6804 } else { |
| 6805 const int total_num_parameters = function.NumParameters(); | 6805 const int total_num_parameters = function.NumParameters(); |
| 6806 Array& array = Array::ZoneHandle(Array::New(total_num_parameters)); | 6806 Array& array = |
| 6807 array ^= array.Canonicalize(); | 6807 Array::ZoneHandle(Array::New(total_num_parameters, Heap::kOld)); |
| 6808 // Skip receiver. | 6808 // Skip receiver. |
| 6809 for (int i = 0; i < total_num_parameters; i++) { | 6809 for (int i = 0; i < total_num_parameters; i++) { |
| 6810 array.SetAt(i, String::Handle(function.ParameterNameAt(i))); | 6810 array.SetAt(i, String::Handle(function.ParameterNameAt(i))); |
| 6811 } | 6811 } |
| 6812 arguments->Add(new LiteralNode(call_pos, array)); | 6812 arguments->Add(new LiteralNode(call_pos, array)); |
| 6813 } | 6813 } |
| 6814 return MakeStaticCall(Symbols::NoSuchMethodError(), | 6814 return MakeStaticCall(Symbols::NoSuchMethodError(), |
| 6815 PrivateCoreLibName(Symbols::ThrowNew()), | 6815 PrivateCoreLibName(Symbols::ThrowNew()), |
| 6816 arguments); | 6816 arguments); |
| 6817 } | 6817 } |
| (...skipping 1234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8052 bool Parser::IsInstantiatorRequired() const { | 8052 bool Parser::IsInstantiatorRequired() const { |
| 8053 ASSERT(!current_function().IsNull()); | 8053 ASSERT(!current_function().IsNull()); |
| 8054 if (current_function().is_static() && | 8054 if (current_function().is_static() && |
| 8055 !current_function().IsInFactoryScope()) { | 8055 !current_function().IsInFactoryScope()) { |
| 8056 return false; | 8056 return false; |
| 8057 } | 8057 } |
| 8058 return current_class().NumTypeParameters() > 0; | 8058 return current_class().NumTypeParameters() > 0; |
| 8059 } | 8059 } |
| 8060 | 8060 |
| 8061 | 8061 |
| 8062 RawInstance* Parser::TryCanonicalize(const Instance& instance, |
| 8063 intptr_t token_pos) { |
| 8064 if (instance.IsNull()) { |
| 8065 return instance.raw(); |
| 8066 } |
| 8067 const char* error_str = NULL; |
| 8068 Instance& result = |
| 8069 Instance::Handle(instance.CheckAndCanonicalize(&error_str)); |
| 8070 if (result.IsNull()) { |
| 8071 ErrorMsg(token_pos, "Invalid const object %s", error_str); |
| 8072 } |
| 8073 return result.raw(); |
| 8074 } |
| 8062 | 8075 |
| 8063 // If the field is constant, initialize the field if necessary and return | 8076 |
| 8064 // no ast (NULL). | 8077 // If the field is already initialized, return no ast (NULL). |
| 8065 // Otherwise return NULL if no implicit getter exists (either never created | 8078 // Otherwise, if the field is constant, initialize the field and return no ast. |
| 8066 // because trivial, or not needed or field not readable). | 8079 // If the field is not initialized and not const, return the ast for the getter. |
| 8067 AstNode* Parser::RunStaticFieldInitializer(const Field& field) { | 8080 AstNode* Parser::RunStaticFieldInitializer(const Field& field) { |
| 8068 ASSERT(field.is_static()); | 8081 ASSERT(field.is_static()); |
| 8069 const Class& field_owner = Class::ZoneHandle(field.owner()); | 8082 const Class& field_owner = Class::ZoneHandle(field.owner()); |
| 8070 const String& field_name = String::ZoneHandle(field.name()); | 8083 const String& field_name = String::ZoneHandle(field.name()); |
| 8071 const String& getter_name = String::Handle(Field::GetterName(field_name)); | 8084 const String& getter_name = String::Handle(Field::GetterName(field_name)); |
| 8072 const Function& getter = | 8085 const Function& getter = |
| 8073 Function::Handle(field_owner.LookupStaticFunction(getter_name)); | 8086 Function::Handle(field_owner.LookupStaticFunction(getter_name)); |
| 8074 const Instance& value = Instance::Handle(field.value()); | 8087 const Instance& value = Instance::Handle(field.value()); |
| 8075 if (value.raw() == Object::transition_sentinel().raw()) { | 8088 if (value.raw() == Object::transition_sentinel().raw()) { |
| 8076 if (field.is_const()) { | 8089 if (field.is_const()) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8114 AppendErrorMsg(error, TokenPos(), | 8127 AppendErrorMsg(error, TokenPos(), |
| 8115 "error initializing const field '%s'", | 8128 "error initializing const field '%s'", |
| 8116 String::Handle(field.name()).ToCString()); | 8129 String::Handle(field.name()).ToCString()); |
| 8117 } else { | 8130 } else { |
| 8118 isolate()->long_jump_base()->Jump(1, error); | 8131 isolate()->long_jump_base()->Jump(1, error); |
| 8119 } | 8132 } |
| 8120 } | 8133 } |
| 8121 ASSERT(const_value.IsNull() || const_value.IsInstance()); | 8134 ASSERT(const_value.IsNull() || const_value.IsInstance()); |
| 8122 Instance& instance = Instance::Handle(); | 8135 Instance& instance = Instance::Handle(); |
| 8123 instance ^= const_value.raw(); | 8136 instance ^= const_value.raw(); |
| 8124 if (!instance.IsNull()) { | 8137 instance = TryCanonicalize(instance, TokenPos()); |
| 8125 instance ^= instance.Canonicalize(); | |
| 8126 } | |
| 8127 field.set_value(instance); | 8138 field.set_value(instance); |
| 8128 return NULL; // Constant | 8139 return NULL; // Constant |
| 8129 } else { | 8140 } else { |
| 8130 return new StaticGetterNode(TokenPos(), | 8141 return new StaticGetterNode(TokenPos(), |
| 8131 NULL, | 8142 NULL, |
| 8132 false, | 8143 false, |
| 8133 field_owner, | 8144 field_owner, |
| 8134 field_name); | 8145 field_name); |
| 8135 } | 8146 } |
| 8136 } | 8147 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8181 // not optimizable. | 8192 // not optimizable. |
| 8182 current_function().set_is_optimizable(false); | 8193 current_function().set_is_optimizable(false); |
| 8183 if (result.IsUnhandledException()) { | 8194 if (result.IsUnhandledException()) { |
| 8184 return result.raw(); | 8195 return result.raw(); |
| 8185 } else { | 8196 } else { |
| 8186 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); | 8197 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); |
| 8187 UNREACHABLE(); | 8198 UNREACHABLE(); |
| 8188 return Object::null(); | 8199 return Object::null(); |
| 8189 } | 8200 } |
| 8190 } else { | 8201 } else { |
| 8191 if (!instance.IsNull()) { | 8202 return TryCanonicalize(instance, TokenPos()); |
| 8192 instance ^= instance.Canonicalize(); | |
| 8193 } | |
| 8194 return instance.raw(); | |
| 8195 } | 8203 } |
| 8196 } | 8204 } |
| 8197 | 8205 |
| 8198 | 8206 |
| 8199 // Do a lookup for the identifier in the block scope and the class scope | 8207 // Do a lookup for the identifier in the block scope and the class scope |
| 8200 // return true if the identifier is found, false otherwise. | 8208 // return true if the identifier is found, false otherwise. |
| 8201 // If node is non NULL return an AST node corresponding to the identifier. | 8209 // If node is non NULL return an AST node corresponding to the identifier. |
| 8202 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, | 8210 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, |
| 8203 const String &ident, | 8211 const String &ident, |
| 8204 AstNode** node) { | 8212 AstNode** node) { |
| (...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8824 } else { | 8832 } else { |
| 8825 ErrorMsg(elem->AsLiteralNode()->token_pos(), | 8833 ErrorMsg(elem->AsLiteralNode()->token_pos(), |
| 8826 "list literal element at index %d must be " | 8834 "list literal element at index %d must be " |
| 8827 "a constant of type '%s'", | 8835 "a constant of type '%s'", |
| 8828 i, | 8836 i, |
| 8829 String::Handle(element_type.UserVisibleName()).ToCString()); | 8837 String::Handle(element_type.UserVisibleName()).ToCString()); |
| 8830 } | 8838 } |
| 8831 } | 8839 } |
| 8832 const_list.SetAt(i, elem->AsLiteralNode()->literal()); | 8840 const_list.SetAt(i, elem->AsLiteralNode()->literal()); |
| 8833 } | 8841 } |
| 8834 const_list ^= const_list.Canonicalize(); | 8842 const_list ^= TryCanonicalize(const_list, literal_pos); |
| 8835 const_list.MakeImmutable(); | 8843 const_list.MakeImmutable(); |
| 8836 return new LiteralNode(literal_pos, const_list); | 8844 return new LiteralNode(literal_pos, const_list); |
| 8837 } else { | 8845 } else { |
| 8838 // Factory call at runtime. | 8846 // Factory call at runtime. |
| 8839 const Class& factory_class = | 8847 const Class& factory_class = |
| 8840 Class::Handle(LookupCoreClass(Symbols::List())); | 8848 Class::Handle(LookupCoreClass(Symbols::List())); |
| 8841 ASSERT(!factory_class.IsNull()); | 8849 ASSERT(!factory_class.IsNull()); |
| 8842 const Function& factory_method = Function::ZoneHandle( | 8850 const Function& factory_method = Function::ZoneHandle( |
| 8843 factory_class.LookupFactory( | 8851 factory_class.LookupFactory( |
| 8844 PrivateCoreLibName(Symbols::ListLiteralFactory()))); | 8852 PrivateCoreLibName(Symbols::ListLiteralFactory()))); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9021 } else { | 9029 } else { |
| 9022 ErrorMsg(arg->AsLiteralNode()->token_pos(), | 9030 ErrorMsg(arg->AsLiteralNode()->token_pos(), |
| 9023 "map literal value at index %d must be " | 9031 "map literal value at index %d must be " |
| 9024 "a constant of type '%s'", | 9032 "a constant of type '%s'", |
| 9025 i >> 1, | 9033 i >> 1, |
| 9026 String::Handle(value_type.UserVisibleName()).ToCString()); | 9034 String::Handle(value_type.UserVisibleName()).ToCString()); |
| 9027 } | 9035 } |
| 9028 } | 9036 } |
| 9029 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); | 9037 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); |
| 9030 } | 9038 } |
| 9031 key_value_array ^= key_value_array.Canonicalize(); | 9039 key_value_array ^= TryCanonicalize(key_value_array, TokenPos()); |
| 9032 key_value_array.MakeImmutable(); | 9040 key_value_array.MakeImmutable(); |
| 9033 | 9041 |
| 9034 // Construct the map object. | 9042 // Construct the map object. |
| 9035 const Class& immutable_map_class = | 9043 const Class& immutable_map_class = |
| 9036 Class::Handle(LookupCoreClass(Symbols::ImmutableMap())); | 9044 Class::Handle(LookupCoreClass(Symbols::ImmutableMap())); |
| 9037 ASSERT(!immutable_map_class.IsNull()); | 9045 ASSERT(!immutable_map_class.IsNull()); |
| 9038 // If the immutable map class extends other parameterized classes, we need | 9046 // If the immutable map class extends other parameterized classes, we need |
| 9039 // to adjust the type argument vector. This is currently not the case. | 9047 // to adjust the type argument vector. This is currently not the case. |
| 9040 ASSERT(immutable_map_class.NumTypeArguments() == 2); | 9048 ASSERT(immutable_map_class.NumTypeArguments() == 2); |
| 9041 ArgumentListNode* constr_args = new ArgumentListNode(TokenPos()); | 9049 ArgumentListNode* constr_args = new ArgumentListNode(TokenPos()); |
| (...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9694 | 9702 |
| 9695 Object& result = Object::Handle(Compiler::ExecuteOnce(seq)); | 9703 Object& result = Object::Handle(Compiler::ExecuteOnce(seq)); |
| 9696 if (result.IsError()) { | 9704 if (result.IsError()) { |
| 9697 // Propagate the compilation error. | 9705 // Propagate the compilation error. |
| 9698 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); | 9706 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); |
| 9699 UNREACHABLE(); | 9707 UNREACHABLE(); |
| 9700 } | 9708 } |
| 9701 ASSERT(result.IsInstance()); | 9709 ASSERT(result.IsInstance()); |
| 9702 Instance& value = Instance::ZoneHandle(); | 9710 Instance& value = Instance::ZoneHandle(); |
| 9703 value ^= result.raw(); | 9711 value ^= result.raw(); |
| 9704 if (!value.IsNull()) { | 9712 value = TryCanonicalize(value, TokenPos()); |
| 9705 value ^= value.Canonicalize(); | |
| 9706 } | |
| 9707 return value; | 9713 return value; |
| 9708 } | 9714 } |
| 9709 } | 9715 } |
| 9710 | 9716 |
| 9711 | 9717 |
| 9712 void Parser::SkipFunctionLiteral() { | 9718 void Parser::SkipFunctionLiteral() { |
| 9713 if (IsIdentifier()) { | 9719 if (IsIdentifier()) { |
| 9714 if (LookaheadToken(1) != Token::kLPAREN) { | 9720 if (LookaheadToken(1) != Token::kLPAREN) { |
| 9715 SkipType(true); | 9721 SkipType(true); |
| 9716 } | 9722 } |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9990 void Parser::SkipQualIdent() { | 9996 void Parser::SkipQualIdent() { |
| 9991 ASSERT(IsIdentifier()); | 9997 ASSERT(IsIdentifier()); |
| 9992 ConsumeToken(); | 9998 ConsumeToken(); |
| 9993 if (CurrentToken() == Token::kPERIOD) { | 9999 if (CurrentToken() == Token::kPERIOD) { |
| 9994 ConsumeToken(); // Consume the kPERIOD token. | 10000 ConsumeToken(); // Consume the kPERIOD token. |
| 9995 ExpectIdentifier("identifier expected after '.'"); | 10001 ExpectIdentifier("identifier expected after '.'"); |
| 9996 } | 10002 } |
| 9997 } | 10003 } |
| 9998 | 10004 |
| 9999 } // namespace dart | 10005 } // namespace dart |
| OLD | NEW |