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/ast_transformer.h" | 9 #include "vm/ast_transformer.h" |
10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
(...skipping 4043 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4054 if (!field->has_static && has_initializer && has_simple_literal) { | 4054 if (!field->has_static && has_initializer && has_simple_literal) { |
4055 class_field.RecordStore(init_value); | 4055 class_field.RecordStore(init_value); |
4056 if (!init_value.IsNull() && init_value.IsDouble()) { | 4056 if (!init_value.IsNull() && init_value.IsDouble()) { |
4057 class_field.set_is_double_initialized(true); | 4057 class_field.set_is_double_initialized(true); |
4058 } | 4058 } |
4059 } | 4059 } |
4060 | 4060 |
4061 // For static final fields (this includes static const fields), set value to | 4061 // For static final fields (this includes static const fields), set value to |
4062 // "uninitialized" and create a kImplicitStaticFinalGetter getter method. | 4062 // "uninitialized" and create a kImplicitStaticFinalGetter getter method. |
4063 if (field->has_static && has_initializer) { | 4063 if (field->has_static && has_initializer) { |
4064 class_field.set_value(init_value); | 4064 class_field.SetStaticValue(init_value, true); |
4065 if (!has_simple_literal) { | 4065 if (!has_simple_literal) { |
4066 String& getter_name = | 4066 String& getter_name = |
4067 String::Handle(Z, Field::GetterSymbol(*field->name)); | 4067 String::Handle(Z, Field::GetterSymbol(*field->name)); |
4068 getter = Function::New(getter_name, | 4068 getter = Function::New(getter_name, |
4069 RawFunction::kImplicitStaticFinalGetter, | 4069 RawFunction::kImplicitStaticFinalGetter, |
4070 field->has_static, | 4070 field->has_static, |
4071 field->has_const, | 4071 field->has_const, |
4072 /* is_abstract = */ false, | 4072 /* is_abstract = */ false, |
4073 /* is_external = */ false, | 4073 /* is_external = */ false, |
4074 /* is_native = */ false, | 4074 /* is_native = */ false, |
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4793 /* is_const = */ true, | 4793 /* is_const = */ true, |
4794 /* is_reflectable = */ true, | 4794 /* is_reflectable = */ true, |
4795 cls, | 4795 cls, |
4796 cls.token_pos()); | 4796 cls.token_pos()); |
4797 enum_value.set_type(dynamic_type); | 4797 enum_value.set_type(dynamic_type); |
4798 enum_value.set_has_initializer(false); | 4798 enum_value.set_has_initializer(false); |
4799 enum_members.AddField(enum_value); | 4799 enum_members.AddField(enum_value); |
4800 // Initialize the field with the ordinal value. It will be patched | 4800 // Initialize the field with the ordinal value. It will be patched |
4801 // later with the enum constant instance. | 4801 // later with the enum constant instance. |
4802 const Smi& ordinal_value = Smi::Handle(Z, Smi::New(i)); | 4802 const Smi& ordinal_value = Smi::Handle(Z, Smi::New(i)); |
4803 enum_value.set_value(ordinal_value); | 4803 enum_value.SetStaticValue(ordinal_value, true); |
4804 enum_value.RecordStore(ordinal_value); | 4804 enum_value.RecordStore(ordinal_value); |
4805 i++; | 4805 i++; |
4806 | 4806 |
4807 // For the user-visible name of the enumeration value, we need to | 4807 // For the user-visible name of the enumeration value, we need to |
4808 // unmangle private names. | 4808 // unmangle private names. |
4809 if (enum_ident->CharAt(0) == '_') { | 4809 if (enum_ident->CharAt(0) == '_') { |
4810 *enum_ident = String::IdentifierPrettyName(*enum_ident); | 4810 *enum_ident = String::IdentifierPrettyName(*enum_ident); |
4811 } | 4811 } |
4812 enum_value_name = Symbols::FromConcat(name_prefix, *enum_ident); | 4812 enum_value_name = Symbols::FromConcat(name_prefix, *enum_ident); |
4813 enum_names.Add(enum_value_name, Heap::kOld); | 4813 enum_names.Add(enum_value_name, Heap::kOld); |
(...skipping 17 matching lines...) Expand all Loading... |
4831 /* is_const = */ true, | 4831 /* is_const = */ true, |
4832 /* is_reflectable = */ true, | 4832 /* is_reflectable = */ true, |
4833 cls, | 4833 cls, |
4834 cls.token_pos()); | 4834 cls.token_pos()); |
4835 values_field.set_type(Type::Handle(Z, Type::ArrayType())); | 4835 values_field.set_type(Type::Handle(Z, Type::ArrayType())); |
4836 enum_members.AddField(values_field); | 4836 enum_members.AddField(values_field); |
4837 | 4837 |
4838 // Allocate the immutable array containing the enumeration values. | 4838 // Allocate the immutable array containing the enumeration values. |
4839 // The actual enum instance values will be patched in later. | 4839 // The actual enum instance values will be patched in later. |
4840 const Array& values_array = Array::Handle(Z, Array::New(i, Heap::kOld)); | 4840 const Array& values_array = Array::Handle(Z, Array::New(i, Heap::kOld)); |
4841 values_field.set_value(values_array); | 4841 values_field.SetStaticValue(values_array, true); |
4842 values_field.RecordStore(values_array); | 4842 values_field.RecordStore(values_array); |
4843 | 4843 |
4844 // Create a static field that contains the list of enumeration names. | 4844 // Create a static field that contains the list of enumeration names. |
4845 // Clone the _enum_names field from the helper class. | 4845 // Clone the _enum_names field from the helper class. |
4846 Field& names_field = Field::Handle(Z, | 4846 Field& names_field = Field::Handle(Z, |
4847 helper_class.LookupStaticField(Symbols::_EnumNames())); | 4847 helper_class.LookupStaticField(Symbols::_EnumNames())); |
4848 ASSERT(!names_field.IsNull()); | 4848 ASSERT(!names_field.IsNull()); |
4849 names_field = names_field.Clone(cls); | 4849 names_field = names_field.Clone(cls); |
4850 enum_members.AddField(names_field); | 4850 enum_members.AddField(names_field); |
4851 const Array& names_array = Array::Handle(Array::MakeArray(enum_names)); | 4851 const Array& names_array = Array::Handle(Array::MakeArray(enum_names)); |
4852 names_field.set_value(names_array); | 4852 names_field.SetStaticValue(names_array, true); |
4853 names_field.RecordStore(names_array); | 4853 names_field.RecordStore(names_array); |
4854 | 4854 |
4855 // Clone the toString() function from the helper class. | 4855 // Clone the toString() function from the helper class. |
4856 Function& to_string_func = Function::Handle(Z, | 4856 Function& to_string_func = Function::Handle(Z, |
4857 helper_class.LookupDynamicFunctionAllowPrivate(Symbols::toString())); | 4857 helper_class.LookupDynamicFunctionAllowPrivate(Symbols::toString())); |
4858 ASSERT(!to_string_func.IsNull()); | 4858 ASSERT(!to_string_func.IsNull()); |
4859 to_string_func = to_string_func.Clone(cls); | 4859 to_string_func = to_string_func.Clone(cls); |
4860 enum_members.AddFunction(to_string_func); | 4860 enum_members.AddFunction(to_string_func); |
4861 | 4861 |
4862 // Clone the hashCode getter function from the helper class. | 4862 // Clone the hashCode getter function from the helper class. |
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5435 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 5435 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
5436 ReportError(name_pos, "setter for '%s' is already defined", | 5436 ReportError(name_pos, "setter for '%s' is already defined", |
5437 var_name.ToCString()); | 5437 var_name.ToCString()); |
5438 } | 5438 } |
5439 | 5439 |
5440 const bool is_reflectable = | 5440 const bool is_reflectable = |
5441 !(library_.is_dart_scheme() && library_.IsPrivate(var_name)); | 5441 !(library_.is_dart_scheme() && library_.IsPrivate(var_name)); |
5442 field = Field::New(var_name, is_static, is_final, is_const, is_reflectable, | 5442 field = Field::New(var_name, is_static, is_final, is_const, is_reflectable, |
5443 current_class(), name_pos); | 5443 current_class(), name_pos); |
5444 field.set_type(type); | 5444 field.set_type(type); |
5445 field.set_value(Object::null_instance()); | 5445 field.SetStaticValue(Object::null_instance(), true); |
5446 top_level->AddField(field); | 5446 top_level->AddField(field); |
5447 library_.AddObject(field, var_name); | 5447 library_.AddObject(field, var_name); |
5448 if (metadata_pos >= 0) { | 5448 if (metadata_pos >= 0) { |
5449 library_.AddFieldMetadata(field, metadata_pos); | 5449 library_.AddFieldMetadata(field, metadata_pos); |
5450 } | 5450 } |
5451 if (CurrentToken() == Token::kASSIGN) { | 5451 if (CurrentToken() == Token::kASSIGN) { |
5452 ConsumeToken(); | 5452 ConsumeToken(); |
5453 Instance& field_value = Instance::Handle(Z, Object::sentinel().raw()); | 5453 Instance& field_value = Instance::Handle(Z, Object::sentinel().raw()); |
5454 bool has_simple_literal = false; | 5454 bool has_simple_literal = false; |
5455 if (LookaheadToken(1) == Token::kSEMICOLON) { | 5455 if (LookaheadToken(1) == Token::kSEMICOLON) { |
5456 has_simple_literal = IsSimpleLiteral(type, &field_value); | 5456 has_simple_literal = IsSimpleLiteral(type, &field_value); |
5457 } | 5457 } |
5458 SkipExpr(); | 5458 SkipExpr(); |
5459 field.set_value(field_value); | 5459 field.SetStaticValue(field_value, true); |
5460 field.set_has_initializer(true); | 5460 field.set_has_initializer(true); |
5461 | 5461 |
5462 if (!has_simple_literal) { | 5462 if (!has_simple_literal) { |
5463 // Create a static final getter. | 5463 // Create a static final getter. |
5464 String& getter_name = String::Handle(Z, Field::GetterSymbol(var_name)); | 5464 String& getter_name = String::Handle(Z, Field::GetterSymbol(var_name)); |
5465 getter = Function::New(getter_name, | 5465 getter = Function::New(getter_name, |
5466 RawFunction::kImplicitStaticFinalGetter, | 5466 RawFunction::kImplicitStaticFinalGetter, |
5467 is_static, | 5467 is_static, |
5468 is_const, | 5468 is_const, |
5469 /* is_abstract = */ false, | 5469 /* is_abstract = */ false, |
(...skipping 5323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10793 return cascade; | 10793 return cascade; |
10794 } | 10794 } |
10795 | 10795 |
10796 | 10796 |
10797 // Convert loading of a static const field into a literal node. | 10797 // Convert loading of a static const field into a literal node. |
10798 static AstNode* LiteralIfStaticConst(Zone* zone, AstNode* expr) { | 10798 static AstNode* LiteralIfStaticConst(Zone* zone, AstNode* expr) { |
10799 if (expr->IsLoadStaticFieldNode()) { | 10799 if (expr->IsLoadStaticFieldNode()) { |
10800 const Field& field = expr->AsLoadStaticFieldNode()->field(); | 10800 const Field& field = expr->AsLoadStaticFieldNode()->field(); |
10801 if (field.is_const() && | 10801 if (field.is_const() && |
10802 !expr->AsLoadStaticFieldNode()->is_deferred_reference()) { | 10802 !expr->AsLoadStaticFieldNode()->is_deferred_reference()) { |
10803 ASSERT(field.value() != Object::sentinel().raw()); | 10803 ASSERT(field.StaticValue() != Object::sentinel().raw()); |
10804 ASSERT(field.value() != Object::transition_sentinel().raw()); | 10804 ASSERT(field.StaticValue() != Object::transition_sentinel().raw()); |
10805 return new(zone) LiteralNode(expr->token_pos(), | 10805 return new(zone) LiteralNode( |
10806 Instance::ZoneHandle(zone, field.value())); | 10806 expr->token_pos(), |
| 10807 Instance::ZoneHandle(zone, field.StaticValue())); |
10807 } | 10808 } |
10808 } | 10809 } |
10809 return expr; | 10810 return expr; |
10810 } | 10811 } |
10811 | 10812 |
10812 | 10813 |
10813 AstNode* Parser::ParseAwaitableExpr(bool require_compiletime_const, | 10814 AstNode* Parser::ParseAwaitableExpr(bool require_compiletime_const, |
10814 bool consume_cascades, | 10815 bool consume_cascades, |
10815 SequenceNode** await_preamble) { | 10816 SequenceNode** await_preamble) { |
10816 TRACE_PARSER("ParseAwaitableExpr"); | 10817 TRACE_PARSER("ParseAwaitableExpr"); |
(...skipping 1158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11975 // If the field is not initialized and not const, return the ast for the getter. | 11976 // If the field is not initialized and not const, return the ast for the getter. |
11976 StaticGetterNode* Parser::RunStaticFieldInitializer(const Field& field, | 11977 StaticGetterNode* Parser::RunStaticFieldInitializer(const Field& field, |
11977 intptr_t field_ref_pos) { | 11978 intptr_t field_ref_pos) { |
11978 ASSERT(field.is_static()); | 11979 ASSERT(field.is_static()); |
11979 const Class& field_owner = Class::ZoneHandle(Z, field.owner()); | 11980 const Class& field_owner = Class::ZoneHandle(Z, field.owner()); |
11980 const String& field_name = String::ZoneHandle(Z, field.name()); | 11981 const String& field_name = String::ZoneHandle(Z, field.name()); |
11981 const String& getter_name = | 11982 const String& getter_name = |
11982 String::Handle(Z, Field::GetterSymbol(field_name)); | 11983 String::Handle(Z, Field::GetterSymbol(field_name)); |
11983 const Function& getter = Function::Handle(Z, | 11984 const Function& getter = Function::Handle(Z, |
11984 field_owner.LookupStaticFunction(getter_name)); | 11985 field_owner.LookupStaticFunction(getter_name)); |
11985 const Instance& value = Instance::Handle(Z, field.value()); | 11986 const Instance& value = Instance::Handle(Z, field.StaticValue()); |
11986 if (value.raw() == Object::transition_sentinel().raw()) { | 11987 if (value.raw() == Object::transition_sentinel().raw()) { |
11987 if (field.is_const()) { | 11988 if (field.is_const()) { |
11988 ReportError("circular dependency while initializing static field '%s'", | 11989 ReportError("circular dependency while initializing static field '%s'", |
11989 field_name.ToCString()); | 11990 field_name.ToCString()); |
11990 } else { | 11991 } else { |
11991 // The implicit static getter will throw the exception if necessary. | 11992 // The implicit static getter will throw the exception if necessary. |
11992 return new(Z) StaticGetterNode( | 11993 return new(Z) StaticGetterNode( |
11993 field_ref_pos, NULL, field_owner, field_name); | 11994 field_ref_pos, NULL, field_owner, field_name); |
11994 } | 11995 } |
11995 } else if (value.raw() == Object::sentinel().raw()) { | 11996 } else if (value.raw() == Object::sentinel().raw()) { |
11996 // This field has not been referenced yet and thus the value has | 11997 // This field has not been referenced yet and thus the value has |
11997 // not been evaluated. If the field is const, call the static getter method | 11998 // not been evaluated. If the field is const, call the static getter method |
11998 // to evaluate the expression and canonicalize the value. | 11999 // to evaluate the expression and canonicalize the value. |
11999 if (field.is_const()) { | 12000 if (field.is_const()) { |
12000 field.set_value(Object::transition_sentinel()); | 12001 field.SetStaticValue(Object::transition_sentinel()); |
12001 const int kNumArguments = 0; // no arguments. | 12002 const int kNumArguments = 0; // no arguments. |
12002 const Function& func = Function::Handle(Z, | 12003 const Function& func = Function::Handle(Z, |
12003 Resolver::ResolveStatic(field_owner, | 12004 Resolver::ResolveStatic(field_owner, |
12004 getter_name, | 12005 getter_name, |
12005 kNumArguments, | 12006 kNumArguments, |
12006 Object::empty_array())); | 12007 Object::empty_array())); |
12007 ASSERT(!func.IsNull()); | 12008 ASSERT(!func.IsNull()); |
12008 ASSERT(func.kind() == RawFunction::kImplicitStaticFinalGetter); | 12009 ASSERT(func.kind() == RawFunction::kImplicitStaticFinalGetter); |
12009 Object& const_value = Object::Handle(Z); | 12010 Object& const_value = Object::Handle(Z); |
12010 { | 12011 { |
12011 PAUSETIMERSCOPE(T, time_compilation); | 12012 PAUSETIMERSCOPE(T, time_compilation); |
12012 const_value = DartEntry::InvokeFunction(func, Object::empty_array()); | 12013 const_value = DartEntry::InvokeFunction(func, Object::empty_array()); |
12013 } | 12014 } |
12014 if (const_value.IsError()) { | 12015 if (const_value.IsError()) { |
12015 const Error& error = Error::Cast(const_value); | 12016 const Error& error = Error::Cast(const_value); |
12016 if (error.IsUnhandledException()) { | 12017 if (error.IsUnhandledException()) { |
12017 // An exception may not occur in every parse attempt, i.e., the | 12018 // An exception may not occur in every parse attempt, i.e., the |
12018 // generated AST is not deterministic. Therefore mark the function as | 12019 // generated AST is not deterministic. Therefore mark the function as |
12019 // not optimizable. | 12020 // not optimizable. |
12020 current_function().SetIsOptimizable(false); | 12021 current_function().SetIsOptimizable(false); |
12021 field.set_value(Object::null_instance()); | 12022 field.SetStaticValue(Object::null_instance()); |
12022 // It is a compile-time error if evaluation of a compile-time constant | 12023 // It is a compile-time error if evaluation of a compile-time constant |
12023 // would raise an exception. | 12024 // would raise an exception. |
12024 const String& field_name = String::Handle(Z, field.name()); | 12025 const String& field_name = String::Handle(Z, field.name()); |
12025 ReportErrors(error, | 12026 ReportErrors(error, |
12026 script_, field_ref_pos, | 12027 script_, field_ref_pos, |
12027 "error initializing const field '%s'", | 12028 "error initializing const field '%s'", |
12028 field_name.ToCString()); | 12029 field_name.ToCString()); |
12029 } else { | 12030 } else { |
12030 ReportError(error); | 12031 ReportError(error); |
12031 } | 12032 } |
12032 UNREACHABLE(); | 12033 UNREACHABLE(); |
12033 } | 12034 } |
12034 ASSERT(const_value.IsNull() || const_value.IsInstance()); | 12035 ASSERT(const_value.IsNull() || const_value.IsInstance()); |
12035 Instance& instance = Instance::Handle(Z); | 12036 Instance& instance = Instance::Handle(Z); |
12036 instance ^= const_value.raw(); | 12037 instance ^= const_value.raw(); |
12037 instance = TryCanonicalize(instance, field_ref_pos); | 12038 instance = TryCanonicalize(instance, field_ref_pos); |
12038 field.set_value(instance); | 12039 field.SetStaticValue(instance); |
12039 return NULL; // Constant | 12040 return NULL; // Constant |
12040 } else { | 12041 } else { |
12041 return new(Z) StaticGetterNode( | 12042 return new(Z) StaticGetterNode( |
12042 field_ref_pos, NULL, field_owner, field_name); | 12043 field_ref_pos, NULL, field_owner, field_name); |
12043 } | 12044 } |
12044 } | 12045 } |
12045 if (getter.IsNull() || | 12046 if (getter.IsNull() || |
12046 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)) { | 12047 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)) { |
12047 return NULL; | 12048 return NULL; |
12048 } | 12049 } |
(...skipping 1841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13890 if (expr->IsLiteralNode()) { | 13891 if (expr->IsLiteralNode()) { |
13891 return expr->AsLiteralNode()->literal(); | 13892 return expr->AsLiteralNode()->literal(); |
13892 } else if (expr->IsLoadLocalNode() && | 13893 } else if (expr->IsLoadLocalNode() && |
13893 expr->AsLoadLocalNode()->local().IsConst()) { | 13894 expr->AsLoadLocalNode()->local().IsConst()) { |
13894 return *expr->AsLoadLocalNode()->local().ConstValue(); | 13895 return *expr->AsLoadLocalNode()->local().ConstValue(); |
13895 } else if (expr->IsLoadStaticFieldNode()) { | 13896 } else if (expr->IsLoadStaticFieldNode()) { |
13896 const Field& field = expr->AsLoadStaticFieldNode()->field(); | 13897 const Field& field = expr->AsLoadStaticFieldNode()->field(); |
13897 // We already checked that this field is const and has been | 13898 // We already checked that this field is const and has been |
13898 // initialized. | 13899 // initialized. |
13899 ASSERT(field.is_const()); | 13900 ASSERT(field.is_const()); |
13900 ASSERT(field.value() != Object::sentinel().raw()); | 13901 ASSERT(field.StaticValue() != Object::sentinel().raw()); |
13901 ASSERT(field.value() != Object::transition_sentinel().raw()); | 13902 ASSERT(field.StaticValue() != Object::transition_sentinel().raw()); |
13902 return Instance::ZoneHandle(Z, field.value()); | 13903 return Instance::ZoneHandle(Z, field.StaticValue()); |
13903 } else { | 13904 } else { |
13904 ASSERT(expr->EvalConstExpr() != NULL); | 13905 ASSERT(expr->EvalConstExpr() != NULL); |
13905 ReturnNode* ret = new(Z) ReturnNode(expr->token_pos(), expr); | 13906 ReturnNode* ret = new(Z) ReturnNode(expr->token_pos(), expr); |
13906 // Compile time constant expressions cannot reference anything from a | 13907 // Compile time constant expressions cannot reference anything from a |
13907 // local scope. | 13908 // local scope. |
13908 LocalScope* empty_scope = new(Z) LocalScope(NULL, 0, 0); | 13909 LocalScope* empty_scope = new(Z) LocalScope(NULL, 0, 0); |
13909 SequenceNode* seq = new(Z) SequenceNode(expr->token_pos(), empty_scope); | 13910 SequenceNode* seq = new(Z) SequenceNode(expr->token_pos(), empty_scope); |
13910 seq->Add(ret); | 13911 seq->Add(ret); |
13911 | 13912 |
13912 Object& result = Object::Handle(Z, Compiler::ExecuteOnce(seq)); | 13913 Object& result = Object::Handle(Z, Compiler::ExecuteOnce(seq)); |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14276 void Parser::SkipQualIdent() { | 14277 void Parser::SkipQualIdent() { |
14277 ASSERT(IsIdentifier()); | 14278 ASSERT(IsIdentifier()); |
14278 ConsumeToken(); | 14279 ConsumeToken(); |
14279 if (CurrentToken() == Token::kPERIOD) { | 14280 if (CurrentToken() == Token::kPERIOD) { |
14280 ConsumeToken(); // Consume the kPERIOD token. | 14281 ConsumeToken(); // Consume the kPERIOD token. |
14281 ExpectIdentifier("identifier expected after '.'"); | 14282 ExpectIdentifier("identifier expected after '.'"); |
14282 } | 14283 } |
14283 } | 14284 } |
14284 | 14285 |
14285 } // namespace dart | 14286 } // namespace dart |
OLD | NEW |