| 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 "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 8885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8896 return result.raw(); | 8896 return result.raw(); |
| 8897 } | 8897 } |
| 8898 | 8898 |
| 8899 | 8899 |
| 8900 // If the field is already initialized, return no ast (NULL). | 8900 // If the field is already initialized, return no ast (NULL). |
| 8901 // Otherwise, if the field is constant, initialize the field and return no ast. | 8901 // Otherwise, if the field is constant, initialize the field and return no ast. |
| 8902 // If the field is not initialized and not const, return the ast for the getter. | 8902 // If the field is not initialized and not const, return the ast for the getter. |
| 8903 AstNode* Parser::RunStaticFieldInitializer(const Field& field, | 8903 AstNode* Parser::RunStaticFieldInitializer(const Field& field, |
| 8904 intptr_t field_ref_pos) { | 8904 intptr_t field_ref_pos) { |
| 8905 ASSERT(field.is_static()); | 8905 ASSERT(field.is_static()); |
| 8906 const Class& field_owner = Class::ZoneHandle(field.owner()); | 8906 const Class& field_owner = Class::ZoneHandle(isolate(), field.owner()); |
| 8907 const String& field_name = String::ZoneHandle(field.name()); | 8907 const String& field_name = String::ZoneHandle(isolate(), field.name()); |
| 8908 const String& getter_name = String::Handle(Field::GetterName(field_name)); | 8908 const String& getter_name = String::Handle(isolate(), |
| 8909 const Function& getter = | 8909 Field::GetterName(field_name)); |
| 8910 Function::Handle(field_owner.LookupStaticFunction(getter_name)); | 8910 const Function& getter = Function::Handle( |
| 8911 const Instance& value = Instance::Handle(field.value()); | 8911 isolate(), field_owner.LookupStaticFunction(getter_name)); |
| 8912 const Instance& value = Instance::Handle(isolate(), field.value()); |
| 8912 if (value.raw() == Object::transition_sentinel().raw()) { | 8913 if (value.raw() == Object::transition_sentinel().raw()) { |
| 8913 if (field.is_const()) { | 8914 if (field.is_const()) { |
| 8914 ErrorMsg("circular dependency while initializing static field '%s'", | 8915 ErrorMsg("circular dependency while initializing static field '%s'", |
| 8915 field_name.ToCString()); | 8916 field_name.ToCString()); |
| 8916 } else { | 8917 } else { |
| 8917 // The implicit static getter will throw the exception if necessary. | 8918 // The implicit static getter will throw the exception if necessary. |
| 8918 return new StaticGetterNode(field_ref_pos, | 8919 return new StaticGetterNode(field_ref_pos, |
| 8919 NULL, | 8920 NULL, |
| 8920 false, | 8921 false, |
| 8921 field_owner, | 8922 field_owner, |
| 8922 field_name); | 8923 field_name); |
| 8923 } | 8924 } |
| 8924 } else if (value.raw() == Object::sentinel().raw()) { | 8925 } else if (value.raw() == Object::sentinel().raw()) { |
| 8925 // This field has not been referenced yet and thus the value has | 8926 // This field has not been referenced yet and thus the value has |
| 8926 // not been evaluated. If the field is const, call the static getter method | 8927 // not been evaluated. If the field is const, call the static getter method |
| 8927 // to evaluate the expression and canonicalize the value. | 8928 // to evaluate the expression and canonicalize the value. |
| 8928 if (field.is_const()) { | 8929 if (field.is_const()) { |
| 8929 field.set_value(Object::transition_sentinel()); | 8930 field.set_value(Object::transition_sentinel()); |
| 8930 const int kNumArguments = 0; // no arguments. | 8931 const int kNumArguments = 0; // no arguments. |
| 8931 const Function& func = | 8932 const Function& func = Function::Handle( |
| 8932 Function::Handle(Resolver::ResolveStatic(field_owner, | 8933 isolate(), Resolver::ResolveStatic(field_owner, |
| 8933 getter_name, | 8934 getter_name, |
| 8934 kNumArguments, | 8935 kNumArguments, |
| 8935 Object::empty_array())); | 8936 Object::empty_array())); |
| 8936 ASSERT(!func.IsNull()); | 8937 ASSERT(!func.IsNull()); |
| 8937 ASSERT(func.kind() == RawFunction::kImplicitStaticFinalGetter); | 8938 ASSERT(func.kind() == RawFunction::kImplicitStaticFinalGetter); |
| 8938 Object& const_value = Object::Handle( | 8939 Object& const_value = Object::Handle(isolate()); |
| 8939 DartEntry::InvokeFunction(func, Object::empty_array())); | 8940 { |
| 8941 PAUSETIMERSCOPE(isolate(), time_compilation); |
| 8942 const_value = DartEntry::InvokeFunction(func, Object::empty_array()); |
| 8943 } |
| 8940 if (const_value.IsError()) { | 8944 if (const_value.IsError()) { |
| 8941 const Error& error = Error::Cast(const_value); | 8945 const Error& error = Error::Cast(const_value); |
| 8942 if (error.IsUnhandledException()) { | 8946 if (error.IsUnhandledException()) { |
| 8943 // An exception may not occur in every parse attempt, i.e., the | 8947 // An exception may not occur in every parse attempt, i.e., the |
| 8944 // generated AST is not deterministic. Therefore mark the function as | 8948 // generated AST is not deterministic. Therefore mark the function as |
| 8945 // not optimizable. | 8949 // not optimizable. |
| 8946 current_function().SetIsOptimizable(false); | 8950 current_function().SetIsOptimizable(false); |
| 8947 field.set_value(Object::null_instance()); | 8951 field.set_value(Object::null_instance()); |
| 8948 // It is a compile-time error if evaluation of a compile-time constant | 8952 // It is a compile-time error if evaluation of a compile-time constant |
| 8949 // would raise an exception. | 8953 // would raise an exception. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8983 | 8987 |
| 8984 RawObject* Parser::EvaluateConstConstructorCall( | 8988 RawObject* Parser::EvaluateConstConstructorCall( |
| 8985 const Class& type_class, | 8989 const Class& type_class, |
| 8986 const TypeArguments& type_arguments, | 8990 const TypeArguments& type_arguments, |
| 8987 const Function& constructor, | 8991 const Function& constructor, |
| 8988 ArgumentListNode* arguments) { | 8992 ArgumentListNode* arguments) { |
| 8989 // Factories have one extra argument: the type arguments. | 8993 // Factories have one extra argument: the type arguments. |
| 8990 // Constructors have 2 extra arguments: rcvr and construction phase. | 8994 // Constructors have 2 extra arguments: rcvr and construction phase. |
| 8991 const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2; | 8995 const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2; |
| 8992 const int num_arguments = arguments->length() + kNumExtraArgs; | 8996 const int num_arguments = arguments->length() + kNumExtraArgs; |
| 8993 const Array& arg_values = Array::Handle(Array::New(num_arguments)); | 8997 const Array& arg_values = Array::Handle(isolate(), |
| 8994 Instance& instance = Instance::Handle(); | 8998 Array::New(num_arguments)); |
| 8999 Instance& instance = Instance::Handle(isolate()); |
| 8995 if (!constructor.IsFactory()) { | 9000 if (!constructor.IsFactory()) { |
| 8996 instance = Instance::New(type_class, Heap::kOld); | 9001 instance = Instance::New(type_class, Heap::kOld); |
| 8997 if (!type_arguments.IsNull()) { | 9002 if (!type_arguments.IsNull()) { |
| 8998 if (!type_arguments.IsInstantiated()) { | 9003 if (!type_arguments.IsInstantiated()) { |
| 8999 ErrorMsg("type must be constant in const constructor"); | 9004 ErrorMsg("type must be constant in const constructor"); |
| 9000 } | 9005 } |
| 9001 instance.SetTypeArguments( | 9006 instance.SetTypeArguments( |
| 9002 TypeArguments::Handle(type_arguments.Canonicalize())); | 9007 TypeArguments::Handle(type_arguments.Canonicalize())); |
| 9003 } | 9008 } |
| 9004 arg_values.SetAt(0, instance); | 9009 arg_values.SetAt(0, instance); |
| 9005 arg_values.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll))); | 9010 arg_values.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll))); |
| 9006 } else { | 9011 } else { |
| 9007 // Prepend type_arguments to list of arguments to factory. | 9012 // Prepend type_arguments to list of arguments to factory. |
| 9008 ASSERT(type_arguments.IsZoneHandle()); | 9013 ASSERT(type_arguments.IsZoneHandle()); |
| 9009 arg_values.SetAt(0, type_arguments); | 9014 arg_values.SetAt(0, type_arguments); |
| 9010 } | 9015 } |
| 9011 for (int i = 0; i < arguments->length(); i++) { | 9016 for (int i = 0; i < arguments->length(); i++) { |
| 9012 AstNode* arg = arguments->NodeAt(i); | 9017 AstNode* arg = arguments->NodeAt(i); |
| 9013 // Arguments have been evaluated to a literal value already. | 9018 // Arguments have been evaluated to a literal value already. |
| 9014 ASSERT(arg->IsLiteralNode()); | 9019 ASSERT(arg->IsLiteralNode()); |
| 9015 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); | 9020 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); |
| 9016 } | 9021 } |
| 9017 const Array& args_descriptor = | 9022 const Array& args_descriptor = Array::Handle( |
| 9018 Array::Handle(ArgumentsDescriptor::New(num_arguments, | 9023 isolate(), ArgumentsDescriptor::New(num_arguments, arguments->names())); |
| 9019 arguments->names())); | 9024 Object& result = Object::Handle(isolate()); |
| 9020 const Object& result = | 9025 { |
| 9021 Object::Handle(DartEntry::InvokeFunction(constructor, | 9026 PAUSETIMERSCOPE(isolate(), time_compilation); |
| 9022 arg_values, | 9027 result = DartEntry::InvokeFunction( |
| 9023 args_descriptor)); | 9028 constructor, arg_values, args_descriptor); |
| 9029 } |
| 9024 if (result.IsError()) { | 9030 if (result.IsError()) { |
| 9025 // An exception may not occur in every parse attempt, i.e., the | 9031 // An exception may not occur in every parse attempt, i.e., the |
| 9026 // generated AST is not deterministic. Therefore mark the function as | 9032 // generated AST is not deterministic. Therefore mark the function as |
| 9027 // not optimizable. Unless we are evaluating metadata, in which case there | 9033 // not optimizable. Unless we are evaluating metadata, in which case there |
| 9028 // is no current function. | 9034 // is no current function. |
| 9029 if (!parsing_metadata_) { | 9035 if (!parsing_metadata_) { |
| 9030 current_function().SetIsOptimizable(false); | 9036 current_function().SetIsOptimizable(false); |
| 9031 } | 9037 } |
| 9032 if (result.IsUnhandledException()) { | 9038 if (result.IsUnhandledException()) { |
| 9033 return result.raw(); | 9039 return result.raw(); |
| (...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10177 new_object = new AssignableNode(new_pos, | 10183 new_object = new AssignableNode(new_pos, |
| 10178 new_object, | 10184 new_object, |
| 10179 type_bound, | 10185 type_bound, |
| 10180 Symbols::FactoryResult()); | 10186 Symbols::FactoryResult()); |
| 10181 } | 10187 } |
| 10182 return new_object; | 10188 return new_object; |
| 10183 } | 10189 } |
| 10184 | 10190 |
| 10185 | 10191 |
| 10186 String& Parser::Interpolate(const GrowableArray<AstNode*>& values) { | 10192 String& Parser::Interpolate(const GrowableArray<AstNode*>& values) { |
| 10187 const Class& cls = | 10193 const Class& cls = Class::Handle( |
| 10188 Class::Handle(Library::LookupCoreClass(Symbols::StringBase())); | 10194 isolate(), Library::LookupCoreClass(Symbols::StringBase())); |
| 10189 ASSERT(!cls.IsNull()); | 10195 ASSERT(!cls.IsNull()); |
| 10190 const Function& func = | 10196 const Function& func = Function::Handle(isolate(), cls.LookupStaticFunction( |
| 10191 Function::Handle(cls.LookupStaticFunction( | 10197 Library::PrivateCoreLibName(Symbols::Interpolate()))); |
| 10192 Library::PrivateCoreLibName(Symbols::Interpolate()))); | |
| 10193 ASSERT(!func.IsNull()); | 10198 ASSERT(!func.IsNull()); |
| 10194 | 10199 |
| 10195 // Build the array of literal values to interpolate. | 10200 // Build the array of literal values to interpolate. |
| 10196 const Array& value_arr = Array::Handle(Array::New(values.length())); | 10201 const Array& value_arr = Array::Handle(isolate(), |
| 10202 Array::New(values.length())); |
| 10197 for (int i = 0; i < values.length(); i++) { | 10203 for (int i = 0; i < values.length(); i++) { |
| 10198 ASSERT(values[i]->IsLiteralNode()); | 10204 ASSERT(values[i]->IsLiteralNode()); |
| 10199 value_arr.SetAt(i, values[i]->AsLiteralNode()->literal()); | 10205 value_arr.SetAt(i, values[i]->AsLiteralNode()->literal()); |
| 10200 } | 10206 } |
| 10201 | 10207 |
| 10202 // Build argument array to pass to the interpolation function. | 10208 // Build argument array to pass to the interpolation function. |
| 10203 const Array& interpolate_arg = Array::Handle(Array::New(1)); | 10209 const Array& interpolate_arg = Array::Handle(isolate(), Array::New(1)); |
| 10204 interpolate_arg.SetAt(0, value_arr); | 10210 interpolate_arg.SetAt(0, value_arr); |
| 10205 | 10211 |
| 10206 // Call interpolation function. | 10212 // Call interpolation function. |
| 10207 String& concatenated = String::ZoneHandle(); | 10213 String& concatenated = String::ZoneHandle(isolate()); |
| 10208 concatenated ^= DartEntry::InvokeFunction(func, interpolate_arg); | 10214 { |
| 10215 PAUSETIMERSCOPE(isolate(), time_compilation); |
| 10216 concatenated ^= DartEntry::InvokeFunction(func, interpolate_arg); |
| 10217 } |
| 10209 if (concatenated.IsUnhandledException()) { | 10218 if (concatenated.IsUnhandledException()) { |
| 10210 ErrorMsg("Exception thrown in Parser::Interpolate"); | 10219 ErrorMsg("Exception thrown in Parser::Interpolate"); |
| 10211 } | 10220 } |
| 10212 concatenated = Symbols::New(concatenated); | 10221 concatenated = Symbols::New(concatenated); |
| 10213 return concatenated; | 10222 return concatenated; |
| 10214 } | 10223 } |
| 10215 | 10224 |
| 10216 | 10225 |
| 10217 // A string literal consists of the concatenation of the next n tokens | 10226 // A string literal consists of the concatenation of the next n tokens |
| 10218 // that satisfy the EBNF grammar: | 10227 // that satisfy the EBNF grammar: |
| (...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10830 void Parser::SkipQualIdent() { | 10839 void Parser::SkipQualIdent() { |
| 10831 ASSERT(IsIdentifier()); | 10840 ASSERT(IsIdentifier()); |
| 10832 ConsumeToken(); | 10841 ConsumeToken(); |
| 10833 if (CurrentToken() == Token::kPERIOD) { | 10842 if (CurrentToken() == Token::kPERIOD) { |
| 10834 ConsumeToken(); // Consume the kPERIOD token. | 10843 ConsumeToken(); // Consume the kPERIOD token. |
| 10835 ExpectIdentifier("identifier expected after '.'"); | 10844 ExpectIdentifier("identifier expected after '.'"); |
| 10836 } | 10845 } |
| 10837 } | 10846 } |
| 10838 | 10847 |
| 10839 } // namespace dart | 10848 } // namespace dart |
| OLD | NEW |