| 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 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 isolate->object_store()->clear_sticky_error(); | 754 isolate->object_store()->clear_sticky_error(); |
| 755 return error.raw(); | 755 return error.raw(); |
| 756 } | 756 } |
| 757 UNREACHABLE(); | 757 UNREACHABLE(); |
| 758 return Object::null(); | 758 return Object::null(); |
| 759 } | 759 } |
| 760 | 760 |
| 761 | 761 |
| 762 void Parser::ParseFunction(ParsedFunction* parsed_function) { | 762 void Parser::ParseFunction(ParsedFunction* parsed_function) { |
| 763 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | 763 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
| 764 CompilerStats::num_functions_compiled++; |
| 764 Isolate* isolate = Isolate::Current(); | 765 Isolate* isolate = Isolate::Current(); |
| 765 ASSERT(isolate->long_jump_base()->IsSafeToJump()); | 766 ASSERT(isolate->long_jump_base()->IsSafeToJump()); |
| 766 ASSERT(parsed_function != NULL); | 767 ASSERT(parsed_function != NULL); |
| 767 const Function& func = parsed_function->function(); | 768 const Function& func = parsed_function->function(); |
| 768 const Script& script = Script::Handle(isolate, func.script()); | 769 const Script& script = Script::Handle(isolate, func.script()); |
| 769 Parser parser(script, parsed_function, func.token_pos()); | 770 Parser parser(script, parsed_function, func.token_pos()); |
| 770 SequenceNode* node_sequence = NULL; | 771 SequenceNode* node_sequence = NULL; |
| 771 Array& default_parameter_values = Array::ZoneHandle(isolate, Array::null()); | 772 Array& default_parameter_values = Array::ZoneHandle(isolate, Array::null()); |
| 772 switch (func.kind()) { | 773 switch (func.kind()) { |
| 773 case RawFunction::kRegularFunction: | 774 case RawFunction::kRegularFunction: |
| (...skipping 11 matching lines...) Expand all Loading... |
| 785 case RawFunction::kImplicitGetter: | 786 case RawFunction::kImplicitGetter: |
| 786 ASSERT(!func.is_static()); | 787 ASSERT(!func.is_static()); |
| 787 node_sequence = parser.ParseInstanceGetter(func); | 788 node_sequence = parser.ParseInstanceGetter(func); |
| 788 break; | 789 break; |
| 789 case RawFunction::kImplicitSetter: | 790 case RawFunction::kImplicitSetter: |
| 790 ASSERT(!func.is_static()); | 791 ASSERT(!func.is_static()); |
| 791 node_sequence = parser.ParseInstanceSetter(func); | 792 node_sequence = parser.ParseInstanceSetter(func); |
| 792 break; | 793 break; |
| 793 case RawFunction::kImplicitStaticFinalGetter: | 794 case RawFunction::kImplicitStaticFinalGetter: |
| 794 node_sequence = parser.ParseStaticFinalGetter(func); | 795 node_sequence = parser.ParseStaticFinalGetter(func); |
| 796 CompilerStats::num_implicit_final_getters++; |
| 795 break; | 797 break; |
| 796 case RawFunction::kStaticInitializer: | 798 case RawFunction::kStaticInitializer: |
| 797 node_sequence = parser.ParseStaticInitializer(func); | 799 node_sequence = parser.ParseStaticInitializer(func); |
| 800 CompilerStats::num_static_initializer_funcs++; |
| 798 break; | 801 break; |
| 799 case RawFunction::kMethodExtractor: | 802 case RawFunction::kMethodExtractor: |
| 800 node_sequence = parser.ParseMethodExtractor(func); | 803 node_sequence = parser.ParseMethodExtractor(func); |
| 801 break; | 804 break; |
| 802 case RawFunction::kNoSuchMethodDispatcher: | 805 case RawFunction::kNoSuchMethodDispatcher: |
| 803 node_sequence = | 806 node_sequence = |
| 804 parser.ParseNoSuchMethodDispatcher(func, default_parameter_values); | 807 parser.ParseNoSuchMethodDispatcher(func, default_parameter_values); |
| 805 break; | 808 break; |
| 806 case RawFunction::kInvokeFieldDispatcher: | 809 case RawFunction::kInvokeFieldDispatcher: |
| 807 node_sequence = | 810 node_sequence = |
| (...skipping 2590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3398 Function& getter = Function::Handle(); | 3401 Function& getter = Function::Handle(); |
| 3399 Function& setter = Function::Handle(); | 3402 Function& setter = Function::Handle(); |
| 3400 Field& class_field = Field::ZoneHandle(); | 3403 Field& class_field = Field::ZoneHandle(); |
| 3401 Instance& init_value = Instance::Handle(); | 3404 Instance& init_value = Instance::Handle(); |
| 3402 while (true) { | 3405 while (true) { |
| 3403 bool has_initializer = CurrentToken() == Token::kASSIGN; | 3406 bool has_initializer = CurrentToken() == Token::kASSIGN; |
| 3404 bool has_simple_literal = false; | 3407 bool has_simple_literal = false; |
| 3405 if (has_initializer) { | 3408 if (has_initializer) { |
| 3406 ConsumeToken(); | 3409 ConsumeToken(); |
| 3407 init_value = Object::sentinel().raw(); | 3410 init_value = Object::sentinel().raw(); |
| 3408 // For static const fields and static final non-const fields, the | 3411 // For static fields, the initialization expression will be parsed |
| 3409 // initialization expression will be parsed through the | 3412 // through the kImplicitStaticFinalGetter method invocation/compilation. |
| 3410 // kImplicitStaticFinalGetter method invocation/compilation. | |
| 3411 // For instance fields, the expression is parsed when a constructor | 3413 // For instance fields, the expression is parsed when a constructor |
| 3412 // is compiled. | 3414 // is compiled. |
| 3413 // For static const fields and static final non-const fields with very | 3415 // For static fields with very simple initializer expressions |
| 3414 // simple initializer expressions (e.g. a literal number or string), we | 3416 // (e.g. a literal number or string), we optimize away the |
| 3415 // optimize away the kImplicitStaticFinalGetter and initialize the field | 3417 // kImplicitStaticFinalGetter and initialize the field here. |
| 3416 // here. However, the class finalizer will check the value type for | 3418 // However, the class finalizer will check the value type for |
| 3417 // assignability once the declared field type can be resolved. If the | 3419 // assignability once the declared field type can be resolved. If the |
| 3418 // value is not assignable (assuming checked mode and disregarding actual | 3420 // value is not assignable (assuming checked mode and disregarding actual |
| 3419 // mode), the field value is reset and a kImplicitStaticFinalGetter is | 3421 // mode), the field value is reset and a kImplicitStaticFinalGetter is |
| 3420 // created at finalization time. | 3422 // created at finalization time. |
| 3421 | 3423 if (field->has_static && (LookaheadToken(1) == Token::kSEMICOLON)) { |
| 3422 if (field->has_static && (field->has_const || field->has_final) && | |
| 3423 (LookaheadToken(1) == Token::kSEMICOLON)) { | |
| 3424 has_simple_literal = IsSimpleLiteral(*field->type, &init_value); | 3424 has_simple_literal = IsSimpleLiteral(*field->type, &init_value); |
| 3425 } | 3425 } |
| 3426 SkipExpr(); | 3426 SkipExpr(); |
| 3427 } else { | 3427 } else { |
| 3428 // Static const and static final fields must have an initializer. | 3428 // Static const and static final fields must have an initializer. |
| 3429 // Static const fields are implicitly final. | 3429 // Static const fields are implicitly final. |
| 3430 if (field->has_static && field->has_final) { | 3430 if (field->has_static && field->has_final) { |
| 3431 ErrorMsg(field->name_pos, | 3431 ErrorMsg(field->name_pos, |
| 3432 "static %s field '%s' must have an initializer expression", | 3432 "static %s field '%s' must have an initializer expression", |
| 3433 field->has_const ? "const" : "final", | 3433 field->has_const ? "const" : "final", |
| (...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3959 } else { | 3959 } else { |
| 3960 CheckToken(Token::kLBRACE); | 3960 CheckToken(Token::kLBRACE); |
| 3961 SkipBlock(); | 3961 SkipBlock(); |
| 3962 ExpectToken(Token::kRBRACE); | 3962 ExpectToken(Token::kRBRACE); |
| 3963 } | 3963 } |
| 3964 } | 3964 } |
| 3965 | 3965 |
| 3966 | 3966 |
| 3967 void Parser::ParseClassDefinition(const Class& cls) { | 3967 void Parser::ParseClassDefinition(const Class& cls) { |
| 3968 TRACE_PARSER("ParseClassDefinition"); | 3968 TRACE_PARSER("ParseClassDefinition"); |
| 3969 CompilerStats::num_classes_compiled++; |
| 3969 set_current_class(cls); | 3970 set_current_class(cls); |
| 3970 is_top_level_ = true; | 3971 is_top_level_ = true; |
| 3971 String& class_name = String::Handle(cls.Name()); | 3972 String& class_name = String::Handle(cls.Name()); |
| 3972 const intptr_t class_pos = TokenPos(); | 3973 const intptr_t class_pos = TokenPos(); |
| 3973 ClassDesc members(cls, class_name, false, class_pos); | 3974 ClassDesc members(cls, class_name, false, class_pos); |
| 3974 while (CurrentToken() != Token::kLBRACE) { | 3975 while (CurrentToken() != Token::kLBRACE) { |
| 3975 ConsumeToken(); | 3976 ConsumeToken(); |
| 3976 } | 3977 } |
| 3977 ExpectToken(Token::kLBRACE); | 3978 ExpectToken(Token::kLBRACE); |
| 3978 while (CurrentToken() != Token::kRBRACE) { | 3979 while (CurrentToken() != Token::kRBRACE) { |
| (...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4573 field.set_value(Instance::Handle(Instance::null())); | 4574 field.set_value(Instance::Handle(Instance::null())); |
| 4574 top_level->fields.Add(field); | 4575 top_level->fields.Add(field); |
| 4575 library_.AddObject(field, var_name); | 4576 library_.AddObject(field, var_name); |
| 4576 if (metadata_pos >= 0) { | 4577 if (metadata_pos >= 0) { |
| 4577 library_.AddFieldMetadata(field, metadata_pos); | 4578 library_.AddFieldMetadata(field, metadata_pos); |
| 4578 } | 4579 } |
| 4579 if (CurrentToken() == Token::kASSIGN) { | 4580 if (CurrentToken() == Token::kASSIGN) { |
| 4580 ConsumeToken(); | 4581 ConsumeToken(); |
| 4581 Instance& field_value = Instance::Handle(Object::sentinel().raw()); | 4582 Instance& field_value = Instance::Handle(Object::sentinel().raw()); |
| 4582 bool has_simple_literal = false; | 4583 bool has_simple_literal = false; |
| 4583 if ((is_const || is_final) && (LookaheadToken(1) == Token::kSEMICOLON)) { | 4584 if (LookaheadToken(1) == Token::kSEMICOLON) { |
| 4584 has_simple_literal = IsSimpleLiteral(type, &field_value); | 4585 has_simple_literal = IsSimpleLiteral(type, &field_value); |
| 4585 } | 4586 } |
| 4586 SkipExpr(); | 4587 SkipExpr(); |
| 4587 field.set_value(field_value); | 4588 field.set_value(field_value); |
| 4588 if (!has_simple_literal) { | 4589 if (!has_simple_literal) { |
| 4589 // Create a static final getter. | 4590 // Create a static final getter. |
| 4590 String& getter_name = String::Handle(Field::GetterSymbol(var_name)); | 4591 String& getter_name = String::Handle(Field::GetterSymbol(var_name)); |
| 4591 getter = Function::New(getter_name, | 4592 getter = Function::New(getter_name, |
| 4592 RawFunction::kImplicitStaticFinalGetter, | 4593 RawFunction::kImplicitStaticFinalGetter, |
| 4593 is_static, | 4594 is_static, |
| (...skipping 6180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10774 void Parser::SkipQualIdent() { | 10775 void Parser::SkipQualIdent() { |
| 10775 ASSERT(IsIdentifier()); | 10776 ASSERT(IsIdentifier()); |
| 10776 ConsumeToken(); | 10777 ConsumeToken(); |
| 10777 if (CurrentToken() == Token::kPERIOD) { | 10778 if (CurrentToken() == Token::kPERIOD) { |
| 10778 ConsumeToken(); // Consume the kPERIOD token. | 10779 ConsumeToken(); // Consume the kPERIOD token. |
| 10779 ExpectIdentifier("identifier expected after '.'"); | 10780 ExpectIdentifier("identifier expected after '.'"); |
| 10780 } | 10781 } |
| 10781 } | 10782 } |
| 10782 | 10783 |
| 10783 } // namespace dart | 10784 } // namespace dart |
| OLD | NEW |