Chromium Code Reviews| 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 6783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6794 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); | 6794 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); |
| 6795 // List existingArgumentNames. | 6795 // List existingArgumentNames. |
| 6796 // Check if there exists a function with the same name. | 6796 // Check if there exists a function with the same name. |
| 6797 Function& function = | 6797 Function& function = |
| 6798 Function::Handle(cls.LookupStaticFunction(function_name)); | 6798 Function::Handle(cls.LookupStaticFunction(function_name)); |
| 6799 if (function.IsNull()) { | 6799 if (function.IsNull()) { |
| 6800 // TODO(srdjan): Store argument values into the argument list. | 6800 // TODO(srdjan): Store argument values into the argument list. |
| 6801 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); | 6801 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); |
| 6802 } else { | 6802 } else { |
| 6803 const int total_num_parameters = function.NumParameters(); | 6803 const int total_num_parameters = function.NumParameters(); |
| 6804 Array& array = Array::ZoneHandle(Array::New(total_num_parameters)); | 6804 Array& array = |
| 6805 array ^= array.Canonicalize(); | 6805 Array::ZoneHandle(Array::New(total_num_parameters, Heap::kOld)); |
| 6806 // Skip receiver. | 6806 // Skip receiver. |
| 6807 for (int i = 0; i < total_num_parameters; i++) { | 6807 for (int i = 0; i < total_num_parameters; i++) { |
| 6808 array.SetAt(i, String::Handle(function.ParameterNameAt(i))); | 6808 array.SetAt(i, String::Handle(function.ParameterNameAt(i))); |
| 6809 } | 6809 } |
| 6810 arguments->Add(new LiteralNode(call_pos, array)); | 6810 arguments->Add(new LiteralNode(call_pos, array)); |
| 6811 } | 6811 } |
| 6812 return MakeStaticCall(Symbols::NoSuchMethodError(), | 6812 return MakeStaticCall(Symbols::NoSuchMethodError(), |
| 6813 PrivateCoreLibName(Symbols::ThrowNew()), | 6813 PrivateCoreLibName(Symbols::ThrowNew()), |
| 6814 arguments); | 6814 arguments); |
| 6815 } | 6815 } |
| (...skipping 1234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8050 bool Parser::IsInstantiatorRequired() const { | 8050 bool Parser::IsInstantiatorRequired() const { |
| 8051 ASSERT(!current_function().IsNull()); | 8051 ASSERT(!current_function().IsNull()); |
| 8052 if (current_function().is_static() && | 8052 if (current_function().is_static() && |
| 8053 !current_function().IsInFactoryScope()) { | 8053 !current_function().IsInFactoryScope()) { |
| 8054 return false; | 8054 return false; |
| 8055 } | 8055 } |
| 8056 return current_class().NumTypeParameters() > 0; | 8056 return current_class().NumTypeParameters() > 0; |
| 8057 } | 8057 } |
| 8058 | 8058 |
| 8059 | 8059 |
| 8060 RawInstance* Parser::TryCanonicalize(const Instance& instance) { | |
| 8061 if (instance.IsNull()) { | |
| 8062 return instance.raw(); | |
| 8063 } | |
| 8064 const char* error_str = NULL; | |
| 8065 Instance& result = | |
| 8066 Instance::Handle(instance.CheckAndCanonicalize(&error_str)); | |
| 8067 if (result.IsNull()) { | |
| 8068 ErrorMsg("Invalid const object %s", error_str); | |
|
hausner
2013/06/11 23:29:24
The error position is not necessarily the current
srdjan
2013/06/12 00:22:22
Done.
| |
| 8069 } | |
| 8070 return result.raw(); | |
| 8071 } | |
| 8072 | |
| 8073 | |
| 8060 // If the field is already initialized, return no ast (NULL). | 8074 // If the field is already initialized, return no ast (NULL). |
| 8061 // Otherwise, if the field is constant, initialize the field and return no ast. | 8075 // Otherwise, if the field is constant, initialize the field and return no ast. |
| 8062 // If the field is not initialized and not const, return the ast for the getter. | 8076 // If the field is not initialized and not const, return the ast for the getter. |
| 8063 AstNode* Parser::RunStaticFieldInitializer(const Field& field) { | 8077 AstNode* Parser::RunStaticFieldInitializer(const Field& field) { |
| 8064 ASSERT(field.is_static()); | 8078 ASSERT(field.is_static()); |
| 8065 const Instance& value = Instance::Handle(field.value()); | 8079 const Instance& value = Instance::Handle(field.value()); |
| 8066 if (value.raw() == Object::transition_sentinel().raw()) { | 8080 if (value.raw() == Object::transition_sentinel().raw()) { |
| 8067 if (field.is_const()) { | 8081 if (field.is_const()) { |
| 8068 ErrorMsg("circular dependency while initializing static field '%s'", | 8082 ErrorMsg("circular dependency while initializing static field '%s'", |
| 8069 String::Handle(field.name()).ToCString()); | 8083 String::Handle(field.name()).ToCString()); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8109 AppendErrorMsg(error, TokenPos(), | 8123 AppendErrorMsg(error, TokenPos(), |
| 8110 "error initializing const field '%s'", | 8124 "error initializing const field '%s'", |
| 8111 String::Handle(field.name()).ToCString()); | 8125 String::Handle(field.name()).ToCString()); |
| 8112 } else { | 8126 } else { |
| 8113 isolate()->long_jump_base()->Jump(1, error); | 8127 isolate()->long_jump_base()->Jump(1, error); |
| 8114 } | 8128 } |
| 8115 } | 8129 } |
| 8116 ASSERT(const_value.IsNull() || const_value.IsInstance()); | 8130 ASSERT(const_value.IsNull() || const_value.IsInstance()); |
| 8117 Instance& instance = Instance::Handle(); | 8131 Instance& instance = Instance::Handle(); |
| 8118 instance ^= const_value.raw(); | 8132 instance ^= const_value.raw(); |
| 8119 if (!instance.IsNull()) { | 8133 instance = TryCanonicalize(instance); |
| 8120 instance ^= instance.Canonicalize(); | |
| 8121 } | |
| 8122 field.set_value(instance); | 8134 field.set_value(instance); |
| 8123 } else { | 8135 } else { |
| 8124 return new StaticGetterNode(TokenPos(), | 8136 return new StaticGetterNode(TokenPos(), |
| 8125 NULL, | 8137 NULL, |
| 8126 false, | 8138 false, |
| 8127 Class::ZoneHandle(field.owner()), | 8139 Class::ZoneHandle(field.owner()), |
| 8128 String::ZoneHandle(field.name())); | 8140 String::ZoneHandle(field.name())); |
| 8129 } | 8141 } |
| 8130 } | 8142 } |
| 8131 return NULL; | 8143 return NULL; |
| 8132 } | 8144 } |
| 8133 | 8145 |
| 8134 | 8146 |
| 8135 RawObject* Parser::EvaluateConstConstructorCall( | 8147 RawObject* Parser::EvaluateConstConstructorCall( |
| 8136 const Class& type_class, | 8148 const Class& type_class, |
| 8137 const AbstractTypeArguments& type_arguments, | 8149 const AbstractTypeArguments& type_arguments, |
| 8138 const Function& constructor, | 8150 const Function& constructor, |
| 8139 ArgumentListNode* arguments) { | 8151 ArgumentListNode* arguments) { |
| 8140 const int kNumExtraArgs = 2; // implicit rcvr and construction phase args. | 8152 const int kNumExtraArgs = 2; // implicit rcvr and construction phase args. |
| 8141 const int num_arguments = arguments->length() + kNumExtraArgs; | 8153 const int num_arguments = arguments->length() + kNumExtraArgs; |
| 8142 const Array& arg_values = Array::Handle(Array::New(num_arguments)); | 8154 const Array& arg_values = Array::Handle(Array::New(num_arguments)); |
| 8143 Instance& instance = Instance::Handle(); | 8155 Instance& instance = Instance::Handle(); |
| 8144 ASSERT(!constructor.IsFactory()); | 8156 ASSERT(!constructor.IsFactory()); |
| 8145 instance = Instance::New(type_class, Heap::kOld); | 8157 instance ^= Instance::New(type_class, Heap::kOld); |
|
hausner
2013/06/11 23:29:24
Why ^= ?
srdjan
2013/06/12 00:22:22
Weird ... removed.
| |
| 8146 if (!type_arguments.IsNull()) { | 8158 if (!type_arguments.IsNull()) { |
| 8147 if (!type_arguments.IsInstantiated()) { | 8159 if (!type_arguments.IsInstantiated()) { |
| 8148 ErrorMsg("type must be constant in const constructor"); | 8160 ErrorMsg("type must be constant in const constructor"); |
| 8149 } | 8161 } |
| 8150 instance.SetTypeArguments( | 8162 instance.SetTypeArguments( |
| 8151 AbstractTypeArguments::Handle(type_arguments.Canonicalize())); | 8163 AbstractTypeArguments::Handle(type_arguments.Canonicalize())); |
| 8152 } | 8164 } |
| 8153 arg_values.SetAt(0, instance); | 8165 arg_values.SetAt(0, instance); |
| 8154 arg_values.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll))); | 8166 arg_values.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll))); |
| 8155 for (int i = 0; i < arguments->length(); i++) { | 8167 for (int i = 0; i < arguments->length(); i++) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 8171 // not optimizable. | 8183 // not optimizable. |
| 8172 current_function().set_is_optimizable(false); | 8184 current_function().set_is_optimizable(false); |
| 8173 if (result.IsUnhandledException()) { | 8185 if (result.IsUnhandledException()) { |
| 8174 return result.raw(); | 8186 return result.raw(); |
| 8175 } else { | 8187 } else { |
| 8176 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); | 8188 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); |
| 8177 UNREACHABLE(); | 8189 UNREACHABLE(); |
| 8178 return Object::null(); | 8190 return Object::null(); |
| 8179 } | 8191 } |
| 8180 } else { | 8192 } else { |
| 8181 if (!instance.IsNull()) { | 8193 return TryCanonicalize(instance); |
| 8182 instance ^= instance.Canonicalize(); | |
| 8183 } | |
| 8184 return instance.raw(); | |
| 8185 } | 8194 } |
| 8186 } | 8195 } |
| 8187 | 8196 |
| 8188 | 8197 |
| 8189 // Do a lookup for the identifier in the block scope and the class scope | 8198 // Do a lookup for the identifier in the block scope and the class scope |
| 8190 // return true if the identifier is found, false otherwise. | 8199 // return true if the identifier is found, false otherwise. |
| 8191 // If node is non NULL return an AST node corresponding to the identifier. | 8200 // If node is non NULL return an AST node corresponding to the identifier. |
| 8192 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, | 8201 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, |
| 8193 const String &ident, | 8202 const String &ident, |
| 8194 AstNode** node) { | 8203 AstNode** node) { |
| (...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8814 } else { | 8823 } else { |
| 8815 ErrorMsg(elem->AsLiteralNode()->token_pos(), | 8824 ErrorMsg(elem->AsLiteralNode()->token_pos(), |
| 8816 "list literal element at index %d must be " | 8825 "list literal element at index %d must be " |
| 8817 "a constant of type '%s'", | 8826 "a constant of type '%s'", |
| 8818 i, | 8827 i, |
| 8819 String::Handle(element_type.UserVisibleName()).ToCString()); | 8828 String::Handle(element_type.UserVisibleName()).ToCString()); |
| 8820 } | 8829 } |
| 8821 } | 8830 } |
| 8822 const_list.SetAt(i, elem->AsLiteralNode()->literal()); | 8831 const_list.SetAt(i, elem->AsLiteralNode()->literal()); |
| 8823 } | 8832 } |
| 8824 const_list ^= const_list.Canonicalize(); | 8833 const_list ^= TryCanonicalize(const_list); |
| 8825 const_list.MakeImmutable(); | 8834 const_list.MakeImmutable(); |
| 8826 return new LiteralNode(literal_pos, const_list); | 8835 return new LiteralNode(literal_pos, const_list); |
| 8827 } else { | 8836 } else { |
| 8828 // Factory call at runtime. | 8837 // Factory call at runtime. |
| 8829 const Class& factory_class = | 8838 const Class& factory_class = |
| 8830 Class::Handle(LookupCoreClass(Symbols::List())); | 8839 Class::Handle(LookupCoreClass(Symbols::List())); |
| 8831 ASSERT(!factory_class.IsNull()); | 8840 ASSERT(!factory_class.IsNull()); |
| 8832 const Function& factory_method = Function::ZoneHandle( | 8841 const Function& factory_method = Function::ZoneHandle( |
| 8833 factory_class.LookupFactory( | 8842 factory_class.LookupFactory( |
| 8834 PrivateCoreLibName(Symbols::ListLiteralFactory()))); | 8843 PrivateCoreLibName(Symbols::ListLiteralFactory()))); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9011 } else { | 9020 } else { |
| 9012 ErrorMsg(arg->AsLiteralNode()->token_pos(), | 9021 ErrorMsg(arg->AsLiteralNode()->token_pos(), |
| 9013 "map literal value at index %d must be " | 9022 "map literal value at index %d must be " |
| 9014 "a constant of type '%s'", | 9023 "a constant of type '%s'", |
| 9015 i >> 1, | 9024 i >> 1, |
| 9016 String::Handle(value_type.UserVisibleName()).ToCString()); | 9025 String::Handle(value_type.UserVisibleName()).ToCString()); |
| 9017 } | 9026 } |
| 9018 } | 9027 } |
| 9019 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); | 9028 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); |
| 9020 } | 9029 } |
| 9021 key_value_array ^= key_value_array.Canonicalize(); | 9030 key_value_array ^= TryCanonicalize(key_value_array); |
| 9022 key_value_array.MakeImmutable(); | 9031 key_value_array.MakeImmutable(); |
| 9023 | 9032 |
| 9024 // Construct the map object. | 9033 // Construct the map object. |
| 9025 const Class& immutable_map_class = | 9034 const Class& immutable_map_class = |
| 9026 Class::Handle(LookupCoreClass(Symbols::ImmutableMap())); | 9035 Class::Handle(LookupCoreClass(Symbols::ImmutableMap())); |
| 9027 ASSERT(!immutable_map_class.IsNull()); | 9036 ASSERT(!immutable_map_class.IsNull()); |
| 9028 // If the immutable map class extends other parameterized classes, we need | 9037 // If the immutable map class extends other parameterized classes, we need |
| 9029 // to adjust the type argument vector. This is currently not the case. | 9038 // to adjust the type argument vector. This is currently not the case. |
| 9030 ASSERT(immutable_map_class.NumTypeArguments() == 2); | 9039 ASSERT(immutable_map_class.NumTypeArguments() == 2); |
| 9031 ArgumentListNode* constr_args = new ArgumentListNode(TokenPos()); | 9040 ArgumentListNode* constr_args = new ArgumentListNode(TokenPos()); |
| (...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9684 | 9693 |
| 9685 Object& result = Object::Handle(Compiler::ExecuteOnce(seq)); | 9694 Object& result = Object::Handle(Compiler::ExecuteOnce(seq)); |
| 9686 if (result.IsError()) { | 9695 if (result.IsError()) { |
| 9687 // Propagate the compilation error. | 9696 // Propagate the compilation error. |
| 9688 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); | 9697 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); |
| 9689 UNREACHABLE(); | 9698 UNREACHABLE(); |
| 9690 } | 9699 } |
| 9691 ASSERT(result.IsInstance()); | 9700 ASSERT(result.IsInstance()); |
| 9692 Instance& value = Instance::ZoneHandle(); | 9701 Instance& value = Instance::ZoneHandle(); |
| 9693 value ^= result.raw(); | 9702 value ^= result.raw(); |
| 9694 if (!value.IsNull()) { | 9703 value = TryCanonicalize(value); |
| 9695 value ^= value.Canonicalize(); | |
| 9696 } | |
| 9697 return value; | 9704 return value; |
| 9698 } | 9705 } |
| 9699 } | 9706 } |
| 9700 | 9707 |
| 9701 | 9708 |
| 9702 void Parser::SkipFunctionLiteral() { | 9709 void Parser::SkipFunctionLiteral() { |
| 9703 if (IsIdentifier()) { | 9710 if (IsIdentifier()) { |
| 9704 if (LookaheadToken(1) != Token::kLPAREN) { | 9711 if (LookaheadToken(1) != Token::kLPAREN) { |
| 9705 SkipType(true); | 9712 SkipType(true); |
| 9706 } | 9713 } |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9980 void Parser::SkipQualIdent() { | 9987 void Parser::SkipQualIdent() { |
| 9981 ASSERT(IsIdentifier()); | 9988 ASSERT(IsIdentifier()); |
| 9982 ConsumeToken(); | 9989 ConsumeToken(); |
| 9983 if (CurrentToken() == Token::kPERIOD) { | 9990 if (CurrentToken() == Token::kPERIOD) { |
| 9984 ConsumeToken(); // Consume the kPERIOD token. | 9991 ConsumeToken(); // Consume the kPERIOD token. |
| 9985 ExpectIdentifier("identifier expected after '.'"); | 9992 ExpectIdentifier("identifier expected after '.'"); |
| 9986 } | 9993 } |
| 9987 } | 9994 } |
| 9988 | 9995 |
| 9989 } // namespace dart | 9996 } // namespace dart |
| OLD | NEW |