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 |