| 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 |