Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(610)

Side by Side Diff: runtime/vm/parser.cc

Issue 1722733002: In background compilation make a copy of Field in order to freeze its state (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: e Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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 = &current_class(); 10680 const Class* target_cls = &current_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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698