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 |