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 #include "vm/flags.h" | 6 #include "vm/flags.h" |
7 | 7 |
8 #ifndef DART_PRECOMPILED_RUNTIME | 8 #ifndef DART_PRECOMPILED_RUNTIME |
9 | 9 |
10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 void ParsedFunction::AddToGuardedFields(const Field* field) const { | 155 void ParsedFunction::AddToGuardedFields(const Field* field) const { |
156 if ((field->guarded_cid() == kDynamicCid) || | 156 if ((field->guarded_cid() == kDynamicCid) || |
157 (field->guarded_cid() == kIllegalCid)) { | 157 (field->guarded_cid() == kIllegalCid)) { |
158 return; | 158 return; |
159 } | 159 } |
160 for (intptr_t j = 0; j < guarded_fields_->length(); j++) { | 160 for (intptr_t j = 0; j < guarded_fields_->length(); j++) { |
161 if ((*guarded_fields_)[j]->raw() == field->raw()) { | 161 if ((*guarded_fields_)[j]->raw() == field->raw()) { |
162 return; | 162 return; |
163 } | 163 } |
164 } | 164 } |
165 guarded_fields_->Add(field); | 165 guarded_fields_->Add(field->OriginalAsHandle(Z)); |
166 } | 166 } |
167 | 167 |
168 | 168 |
169 LocalVariable* ParsedFunction::EnsureExpressionTemp() { | 169 LocalVariable* ParsedFunction::EnsureExpressionTemp() { |
170 if (!has_expression_temp_var()) { | 170 if (!has_expression_temp_var()) { |
171 LocalVariable* temp = | 171 LocalVariable* temp = |
172 new (Z) LocalVariable(function_.token_pos(), | 172 new (Z) LocalVariable(function_.token_pos(), |
173 Symbols::ExprTemp(), | 173 Symbols::ExprTemp(), |
174 Object::dynamic_type()); | 174 Object::dynamic_type()); |
175 ASSERT(temp != NULL); | 175 ASSERT(temp != NULL); |
(...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1070 } | 1070 } |
1071 } | 1071 } |
1072 | 1072 |
1073 | 1073 |
1074 RawObject* Parser::ParseMetadata(const Field& meta_data) { | 1074 RawObject* Parser::ParseMetadata(const Field& meta_data) { |
1075 LongJumpScope jump; | 1075 LongJumpScope jump; |
1076 if (setjmp(*jump.Set()) == 0) { | 1076 if (setjmp(*jump.Set()) == 0) { |
1077 Thread* thread = Thread::Current(); | 1077 Thread* thread = Thread::Current(); |
1078 StackZone stack_zone(thread); | 1078 StackZone stack_zone(thread); |
1079 Zone* zone = stack_zone.GetZone(); | 1079 Zone* zone = stack_zone.GetZone(); |
1080 const Class& owner_class = Class::Handle(zone, meta_data.owner()); | 1080 const Class& owner_class = Class::Handle(zone, meta_data.Owner()); |
1081 const Script& script = Script::Handle(zone, meta_data.script()); | 1081 const Script& script = Script::Handle(zone, meta_data.Script()); |
1082 const TokenPosition token_pos = meta_data.token_pos(); | 1082 const TokenPosition token_pos = meta_data.token_pos(); |
1083 // Parsing metadata can involve following paths in the parser that are | 1083 // Parsing metadata can involve following paths in the parser that are |
1084 // normally used for expressions and assume current_function is non-null, | 1084 // normally used for expressions and assume current_function is non-null, |
1085 // so we create a fake function to use as the current_function rather than | 1085 // so we create a fake function to use as the current_function rather than |
1086 // scattering special cases throughout the parser. | 1086 // scattering special cases throughout the parser. |
1087 const Function& fake_function = Function::ZoneHandle(zone, Function::New( | 1087 const Function& fake_function = Function::ZoneHandle(zone, Function::New( |
1088 Symbols::At(), | 1088 Symbols::At(), |
1089 RawFunction::kRegularFunction, | 1089 RawFunction::kRegularFunction, |
1090 true, // is_static | 1090 true, // is_static |
1091 false, // is_const | 1091 false, // is_const |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1211 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { | 1211 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { |
1212 ASSERT(field.is_static()); | 1212 ASSERT(field.is_static()); |
1213 Thread* thread = Thread::Current(); | 1213 Thread* thread = Thread::Current(); |
1214 // TODO(koda): Should there be a StackZone here? | 1214 // TODO(koda): Should there be a StackZone here? |
1215 Zone* zone = thread->zone(); | 1215 Zone* zone = thread->zone(); |
1216 | 1216 |
1217 const String& field_name = String::Handle(zone, field.name()); | 1217 const String& field_name = String::Handle(zone, field.name()); |
1218 String& init_name = String::Handle(zone, | 1218 String& init_name = String::Handle(zone, |
1219 Symbols::FromConcat(Symbols::InitPrefix(), field_name)); | 1219 Symbols::FromConcat(Symbols::InitPrefix(), field_name)); |
1220 | 1220 |
1221 const Script& script = Script::Handle(zone, field.script()); | 1221 const Script& script = Script::Handle(zone, field.Script()); |
1222 Object& initializer_owner = Object::Handle(field.owner()); | 1222 Object& initializer_owner = Object::Handle(field.Owner()); |
1223 initializer_owner = | 1223 initializer_owner = |
1224 PatchClass::New(Class::Handle(field.owner()), script); | 1224 PatchClass::New(Class::Handle(field.Owner()), script); |
1225 | 1225 |
1226 const Function& initializer = Function::ZoneHandle(zone, | 1226 const Function& initializer = Function::ZoneHandle(zone, |
1227 Function::New(init_name, | 1227 Function::New(init_name, |
1228 RawFunction::kImplicitStaticFinalGetter, | 1228 RawFunction::kImplicitStaticFinalGetter, |
1229 true, // static | 1229 true, // static |
1230 false, // !const | 1230 false, // !const |
1231 false, // !abstract | 1231 false, // !abstract |
1232 false, // !external | 1232 false, // !external |
1233 false, // !native | 1233 false, // !native |
1234 initializer_owner, | 1234 initializer_owner, |
(...skipping 1306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2541 if (field.is_static()) { | 2541 if (field.is_static()) { |
2542 continue; | 2542 continue; |
2543 } | 2543 } |
2544 | 2544 |
2545 bool found = false; | 2545 bool found = false; |
2546 for (int i = 0; i < initializers->length(); i++) { | 2546 for (int i = 0; i < initializers->length(); i++) { |
2547 found = false; | 2547 found = false; |
2548 if (initializers->NodeAt(i)->IsStoreInstanceFieldNode()) { | 2548 if (initializers->NodeAt(i)->IsStoreInstanceFieldNode()) { |
2549 StoreInstanceFieldNode* initializer = | 2549 StoreInstanceFieldNode* initializer = |
2550 initializers->NodeAt(i)->AsStoreInstanceFieldNode(); | 2550 initializers->NodeAt(i)->AsStoreInstanceFieldNode(); |
2551 if (initializer->field().raw() == field.raw()) { | 2551 ASSERT(field.IsOriginal()); |
| 2552 if (initializer->field().Original() == field.raw()) { |
2552 found = true; | 2553 found = true; |
2553 break; | 2554 break; |
2554 } | 2555 } |
2555 } | 2556 } |
2556 } | 2557 } |
2557 | 2558 |
2558 if (found) continue; | 2559 if (found) continue; |
2559 | 2560 |
2560 field.RecordStore(Object::null_object()); | 2561 field.RecordStore(Object::null_object()); |
2561 } | 2562 } |
2562 } | 2563 } |
2563 | 2564 |
2564 | 2565 |
2565 AstNode* Parser::ParseExternalInitializedField(const Field& field) { | 2566 AstNode* Parser::ParseExternalInitializedField(const Field& field) { |
2566 // Only use this function if the initialized field originates | 2567 // Only use this function if the initialized field originates |
2567 // from a different class. We need to save and restore current | 2568 // from a different class. We need to save and restore current |
2568 // class, library, and token stream (script). | 2569 // class, library, and token stream (script). |
2569 ASSERT(current_class().raw() != field.origin()); | 2570 ASSERT(current_class().raw() != field.Origin()); |
2570 const Class& saved_class = Class::Handle(Z, current_class().raw()); | 2571 const Class& saved_class = Class::Handle(Z, current_class().raw()); |
2571 const Library& saved_library = Library::Handle(Z, library().raw()); | 2572 const Library& saved_library = Library::Handle(Z, library().raw()); |
2572 const Script& saved_script = Script::Handle(Z, script().raw()); | 2573 const Script& saved_script = Script::Handle(Z, script().raw()); |
2573 const TokenPosition saved_token_pos = TokenPos(); | 2574 const TokenPosition saved_token_pos = TokenPos(); |
2574 | 2575 |
2575 set_current_class(Class::Handle(Z, field.origin())); | 2576 set_current_class(Class::Handle(Z, field.Origin())); |
2576 set_library(Library::Handle(Z, current_class().library())); | 2577 set_library(Library::Handle(Z, current_class().library())); |
2577 SetScript(Script::Handle(Z, current_class().script()), field.token_pos()); | 2578 SetScript(Script::Handle(Z, current_class().script()), field.token_pos()); |
2578 | 2579 |
2579 ASSERT(IsIdentifier()); | 2580 ASSERT(IsIdentifier()); |
2580 ConsumeToken(); | 2581 ConsumeToken(); |
2581 ExpectToken(Token::kASSIGN); | 2582 ExpectToken(Token::kASSIGN); |
2582 AstNode* init_expr = NULL; | 2583 AstNode* init_expr = NULL; |
2583 TokenPosition expr_pos = TokenPos(); | 2584 TokenPosition expr_pos = TokenPos(); |
2584 if (field.is_const()) { | 2585 if (field.is_const()) { |
2585 init_expr = ParseConstExpr(); | 2586 init_expr = ParseConstExpr(); |
(...skipping 27 matching lines...) Expand all Loading... |
2613 if (!f.is_static() && f.has_initializer()) { | 2614 if (!f.is_static() && f.has_initializer()) { |
2614 Field& field = Field::ZoneHandle(Z); | 2615 Field& field = Field::ZoneHandle(Z); |
2615 field ^= fields.At(i); | 2616 field ^= fields.At(i); |
2616 if (field.is_final()) { | 2617 if (field.is_final()) { |
2617 // Final fields with initializer expression may not be initialized | 2618 // Final fields with initializer expression may not be initialized |
2618 // again by constructors. Remember that this field is already | 2619 // again by constructors. Remember that this field is already |
2619 // initialized. | 2620 // initialized. |
2620 initialized_fields->Add(&field); | 2621 initialized_fields->Add(&field); |
2621 } | 2622 } |
2622 AstNode* init_expr = NULL; | 2623 AstNode* init_expr = NULL; |
2623 if (current_class().raw() != field.origin()) { | 2624 if (current_class().raw() != field.Origin()) { |
2624 init_expr = ParseExternalInitializedField(field); | 2625 init_expr = ParseExternalInitializedField(field); |
2625 } else { | 2626 } else { |
2626 SetPosition(field.token_pos()); | 2627 SetPosition(field.token_pos()); |
2627 ASSERT(IsIdentifier()); | 2628 ASSERT(IsIdentifier()); |
2628 ConsumeToken(); | 2629 ConsumeToken(); |
2629 ExpectToken(Token::kASSIGN); | 2630 ExpectToken(Token::kASSIGN); |
2630 if (current_class().is_const()) { | 2631 if (current_class().is_const()) { |
2631 // If the class has a const contructor, the initializer | 2632 // If the class has a const contructor, the initializer |
2632 // expression must be a compile-time constant. | 2633 // expression must be a compile-time constant. |
2633 init_expr = ParseConstExpr(); | 2634 init_expr = ParseConstExpr(); |
(...skipping 8041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10675 bool is_compound /* = false */) { | 10676 bool is_compound /* = false */) { |
10676 AstNode* result = original->MakeAssignmentNode(rhs); | 10677 AstNode* result = original->MakeAssignmentNode(rhs); |
10677 if (result == NULL) { | 10678 if (result == NULL) { |
10678 String& name = String::ZoneHandle(Z); | 10679 String& name = String::ZoneHandle(Z); |
10679 const Class* target_cls = ¤t_class(); | 10680 const Class* target_cls = ¤t_class(); |
10680 if (original->IsTypeNode()) { | 10681 if (original->IsTypeNode()) { |
10681 name = Symbols::New(original->AsTypeNode()->TypeName()); | 10682 name = Symbols::New(original->AsTypeNode()->TypeName()); |
10682 } else if (original->IsLoadStaticFieldNode()) { | 10683 } else if (original->IsLoadStaticFieldNode()) { |
10683 name = original->AsLoadStaticFieldNode()->field().name(); | 10684 name = original->AsLoadStaticFieldNode()->field().name(); |
10684 target_cls = &Class::Handle(Z, | 10685 target_cls = &Class::Handle(Z, |
10685 original->AsLoadStaticFieldNode()->field().owner()); | 10686 original->AsLoadStaticFieldNode()->field().Owner()); |
10686 } else if ((left_ident != NULL) && | 10687 } else if ((left_ident != NULL) && |
10687 (original->IsLiteralNode() || | 10688 (original->IsLiteralNode() || |
10688 original->IsLoadLocalNode())) { | 10689 original->IsLoadLocalNode())) { |
10689 name = left_ident->raw(); | 10690 name = left_ident->raw(); |
10690 } | 10691 } |
10691 if (name.IsNull()) { | 10692 if (name.IsNull()) { |
10692 ReportError(left_pos, "expression is not assignable"); | 10693 ReportError(left_pos, "expression is not assignable"); |
10693 } | 10694 } |
10694 LetNode* let_node = new(Z) LetNode(left_pos); | 10695 LetNode* let_node = new(Z) LetNode(left_pos); |
10695 let_node->AddInitializer(rhs); | 10696 let_node->AddInitializer(rhs); |
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11173 // If the static field has an initializer, initialize the field at compile | 11174 // If the static field has an initializer, initialize the field at compile |
11174 // time, which is only possible if the field is const. | 11175 // time, which is only possible if the field is const. |
11175 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); | 11176 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); |
11176 if (initializing_getter != NULL) { | 11177 if (initializing_getter != NULL) { |
11177 // The field is not yet initialized and could not be initialized at compile | 11178 // The field is not yet initialized and could not be initialized at compile |
11178 // time. The getter will initialize the field. | 11179 // time. The getter will initialize the field. |
11179 return initializing_getter; | 11180 return initializing_getter; |
11180 } | 11181 } |
11181 // The field is initialized. | 11182 // The field is initialized. |
11182 ASSERT(field.is_static()); | 11183 ASSERT(field.is_static()); |
11183 const Class& field_owner = Class::ZoneHandle(Z, field.owner()); | 11184 const Class& field_owner = Class::ZoneHandle(Z, field.Owner()); |
11184 const String& field_name = String::ZoneHandle(Z, field.name()); | 11185 const String& field_name = String::ZoneHandle(Z, field.name()); |
11185 const String& getter_name = | 11186 const String& getter_name = |
11186 String::Handle(Z, Field::GetterSymbol(field_name)); | 11187 String::Handle(Z, Field::GetterSymbol(field_name)); |
11187 const Function& getter = Function::Handle(Z, | 11188 const Function& getter = Function::Handle(Z, |
11188 field_owner.LookupStaticFunction(getter_name)); | 11189 field_owner.LookupStaticFunction(getter_name)); |
11189 // Never load field directly if there is a getter (deterministic AST). | 11190 // Never load field directly if there is a getter (deterministic AST). |
11190 if (getter.IsNull() || field.is_const()) { | 11191 if (getter.IsNull() || field.is_const()) { |
11191 return new(Z) LoadStaticFieldNode( | 11192 return new(Z) LoadStaticFieldNode( |
11192 ident_pos, Field::ZoneHandle(Z, field.raw())); | 11193 ident_pos, Field::ZoneHandle(Z, field.raw())); |
11193 } else { | 11194 } else { |
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12016 return result.raw(); | 12017 return result.raw(); |
12017 } | 12018 } |
12018 | 12019 |
12019 | 12020 |
12020 // If the field is already initialized, return no ast (NULL). | 12021 // If the field is already initialized, return no ast (NULL). |
12021 // Otherwise, if the field is constant, initialize the field and return no ast. | 12022 // Otherwise, if the field is constant, initialize the field and return no ast. |
12022 // If the field is not initialized and not const, return the ast for the getter. | 12023 // If the field is not initialized and not const, return the ast for the getter. |
12023 StaticGetterNode* Parser::RunStaticFieldInitializer( | 12024 StaticGetterNode* Parser::RunStaticFieldInitializer( |
12024 const Field& field, TokenPosition field_ref_pos) { | 12025 const Field& field, TokenPosition field_ref_pos) { |
12025 ASSERT(field.is_static()); | 12026 ASSERT(field.is_static()); |
12026 const Class& field_owner = Class::ZoneHandle(Z, field.owner()); | 12027 const Class& field_owner = Class::ZoneHandle(Z, field.Owner()); |
12027 const String& field_name = String::ZoneHandle(Z, field.name()); | 12028 const String& field_name = String::ZoneHandle(Z, field.name()); |
12028 const String& getter_name = | 12029 const String& getter_name = |
12029 String::Handle(Z, Field::GetterSymbol(field_name)); | 12030 String::Handle(Z, Field::GetterSymbol(field_name)); |
12030 const Function& getter = Function::Handle(Z, | 12031 const Function& getter = Function::Handle(Z, |
12031 field_owner.LookupStaticFunction(getter_name)); | 12032 field_owner.LookupStaticFunction(getter_name)); |
12032 const Instance& value = Instance::Handle(Z, field.StaticValue()); | 12033 const Instance& value = Instance::Handle(Z, field.StaticValue()); |
12033 if (value.raw() == Object::transition_sentinel().raw()) { | 12034 if (value.raw() == Object::transition_sentinel().raw()) { |
12034 if (field.is_const()) { | 12035 if (field.is_const()) { |
12035 ReportError("circular dependency while initializing static field '%s'", | 12036 ReportError("circular dependency while initializing static field '%s'", |
12036 field_name.ToCString()); | 12037 field_name.ToCString()); |
(...skipping 2376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14413 const ArgumentListNode& function_args, | 14414 const ArgumentListNode& function_args, |
14414 const LocalVariable* temp_for_last_arg, | 14415 const LocalVariable* temp_for_last_arg, |
14415 bool is_super_invocation) { | 14416 bool is_super_invocation) { |
14416 UNREACHABLE(); | 14417 UNREACHABLE(); |
14417 return NULL; | 14418 return NULL; |
14418 } | 14419 } |
14419 | 14420 |
14420 } // namespace dart | 14421 } // namespace dart |
14421 | 14422 |
14422 #endif // DART_PRECOMPILED_RUNTIME | 14423 #endif // DART_PRECOMPILED_RUNTIME |
OLD | NEW |