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 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 void Parser::ComputeCurrentToken() { | 459 void Parser::ComputeCurrentToken() { |
460 ASSERT(token_kind_ == Token::kILLEGAL); | 460 ASSERT(token_kind_ == Token::kILLEGAL); |
461 token_kind_ = tokens_iterator_.CurrentTokenKind(); | 461 token_kind_ = tokens_iterator_.CurrentTokenKind(); |
462 if (token_kind_ == Token::kERROR) { | 462 if (token_kind_ == Token::kERROR) { |
463 ReportError(TokenPos(), "%s", CurrentLiteral()->ToCString()); | 463 ReportError(TokenPos(), "%s", CurrentLiteral()->ToCString()); |
464 } | 464 } |
465 } | 465 } |
466 | 466 |
467 | 467 |
468 Token::Kind Parser::LookaheadToken(int num_tokens) { | 468 Token::Kind Parser::LookaheadToken(int num_tokens) { |
469 INC_STAT(I, num_tokens_lookahead, 1); | |
470 INC_STAT(I, num_token_checks, 1); | |
471 return tokens_iterator_.LookaheadTokenKind(num_tokens); | 469 return tokens_iterator_.LookaheadTokenKind(num_tokens); |
472 } | 470 } |
473 | 471 |
474 | 472 |
475 String* Parser::CurrentLiteral() const { | 473 String* Parser::CurrentLiteral() const { |
476 String& result = | 474 String& result = |
477 String::ZoneHandle(Z, tokens_iterator_.CurrentLiteral()); | 475 String::ZoneHandle(Z, tokens_iterator_.CurrentLiteral()); |
478 return &result; | 476 return &result; |
479 } | 477 } |
480 | 478 |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
797 } | 795 } |
798 | 796 |
799 private: | 797 private: |
800 Zone* zone_; | 798 Zone* zone_; |
801 GrowableArray<const Field*> fields_; | 799 GrowableArray<const Field*> fields_; |
802 GrowableArray<const Function*> functions_; | 800 GrowableArray<const Function*> functions_; |
803 }; | 801 }; |
804 | 802 |
805 | 803 |
806 void Parser::ParseClass(const Class& cls) { | 804 void Parser::ParseClass(const Class& cls) { |
| 805 Thread* thread = Thread::Current(); |
| 806 Zone* zone = thread->zone(); |
| 807 const int64_t num_tokes_before = STAT_VALUE(thread, num_tokens_consumed); |
807 if (!cls.is_synthesized_class()) { | 808 if (!cls.is_synthesized_class()) { |
808 Thread* thread = Thread::Current(); | 809 ASSERT(thread->long_jump_base()->IsSafeToJump()); |
809 Zone* zone = thread->zone(); | |
810 CSTAT_TIMER_SCOPE(thread, parser_timer); | 810 CSTAT_TIMER_SCOPE(thread, parser_timer); |
811 ASSERT(thread->long_jump_base()->IsSafeToJump()); | |
812 const Script& script = Script::Handle(zone, cls.script()); | 811 const Script& script = Script::Handle(zone, cls.script()); |
813 const Library& lib = Library::Handle(zone, cls.library()); | 812 const Library& lib = Library::Handle(zone, cls.library()); |
814 Parser parser(script, lib, cls.token_pos()); | 813 Parser parser(script, lib, cls.token_pos()); |
815 parser.ParseClassDefinition(cls); | 814 parser.ParseClassDefinition(cls); |
816 } else if (cls.is_enum_class()) { | 815 } else if (cls.is_enum_class()) { |
817 Thread* thread = Thread::Current(); | 816 ASSERT(thread->long_jump_base()->IsSafeToJump()); |
818 Zone* zone = thread->zone(); | |
819 CSTAT_TIMER_SCOPE(thread, parser_timer); | 817 CSTAT_TIMER_SCOPE(thread, parser_timer); |
820 ASSERT(thread->long_jump_base()->IsSafeToJump()); | |
821 const Script& script = Script::Handle(zone, cls.script()); | 818 const Script& script = Script::Handle(zone, cls.script()); |
822 const Library& lib = Library::Handle(zone, cls.library()); | 819 const Library& lib = Library::Handle(zone, cls.library()); |
823 Parser parser(script, lib, cls.token_pos()); | 820 Parser parser(script, lib, cls.token_pos()); |
824 parser.ParseEnumDefinition(cls); | 821 parser.ParseEnumDefinition(cls); |
825 } | 822 } |
| 823 const int64_t num_tokes_after = STAT_VALUE(thread, num_tokens_consumed); |
| 824 INC_STAT(thread, num_class_tokens, num_tokes_after - num_tokes_before); |
826 } | 825 } |
827 | 826 |
828 | 827 |
829 RawObject* Parser::ParseFunctionParameters(const Function& func) { | 828 RawObject* Parser::ParseFunctionParameters(const Function& func) { |
830 ASSERT(!func.IsNull()); | 829 ASSERT(!func.IsNull()); |
831 Thread* thread = Thread::Current(); | 830 Thread* thread = Thread::Current(); |
832 Isolate* isolate = thread->isolate(); | 831 Isolate* isolate = thread->isolate(); |
833 StackZone stack_zone(thread); | 832 StackZone stack_zone(thread); |
834 Zone* zone = stack_zone.GetZone(); | 833 Zone* zone = stack_zone.GetZone(); |
835 LongJumpScope jump; | 834 LongJumpScope jump; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
902 return false; | 901 return false; |
903 } | 902 } |
904 UNREACHABLE(); | 903 UNREACHABLE(); |
905 return false; | 904 return false; |
906 } | 905 } |
907 | 906 |
908 | 907 |
909 void Parser::ParseFunction(ParsedFunction* parsed_function) { | 908 void Parser::ParseFunction(ParsedFunction* parsed_function) { |
910 Thread* thread = parsed_function->thread(); | 909 Thread* thread = parsed_function->thread(); |
911 ASSERT(thread == Thread::Current()); | 910 ASSERT(thread == Thread::Current()); |
912 Isolate* isolate = thread->isolate(); | |
913 Zone* zone = thread->zone(); | 911 Zone* zone = thread->zone(); |
914 CSTAT_TIMER_SCOPE(thread, parser_timer); | 912 CSTAT_TIMER_SCOPE(thread, parser_timer); |
915 INC_STAT(isolate, num_functions_compiled, 1); | 913 INC_STAT(thread, num_functions_parsed, 1); |
916 VMTagScope tagScope(thread, VMTag::kCompileParseFunctionTagId, | 914 VMTagScope tagScope(thread, VMTag::kCompileParseFunctionTagId, |
917 FLAG_profile_vm); | 915 FLAG_profile_vm); |
918 | 916 |
919 ASSERT(thread->long_jump_base()->IsSafeToJump()); | 917 ASSERT(thread->long_jump_base()->IsSafeToJump()); |
920 ASSERT(parsed_function != NULL); | 918 ASSERT(parsed_function != NULL); |
921 const Function& func = parsed_function->function(); | 919 const Function& func = parsed_function->function(); |
922 const Script& script = Script::Handle(zone, func.script()); | 920 const Script& script = Script::Handle(zone, func.script()); |
923 Parser parser(script, parsed_function, func.token_pos()); | 921 Parser parser(script, parsed_function, func.token_pos()); |
924 SequenceNode* node_sequence = NULL; | 922 SequenceNode* node_sequence = NULL; |
925 switch (func.kind()) { | 923 switch (func.kind()) { |
(...skipping 23 matching lines...) Expand all Loading... |
949 case RawFunction::kImplicitGetter: | 947 case RawFunction::kImplicitGetter: |
950 ASSERT(!func.is_static()); | 948 ASSERT(!func.is_static()); |
951 node_sequence = parser.ParseInstanceGetter(func); | 949 node_sequence = parser.ParseInstanceGetter(func); |
952 break; | 950 break; |
953 case RawFunction::kImplicitSetter: | 951 case RawFunction::kImplicitSetter: |
954 ASSERT(!func.is_static()); | 952 ASSERT(!func.is_static()); |
955 node_sequence = parser.ParseInstanceSetter(func); | 953 node_sequence = parser.ParseInstanceSetter(func); |
956 break; | 954 break; |
957 case RawFunction::kImplicitStaticFinalGetter: | 955 case RawFunction::kImplicitStaticFinalGetter: |
958 node_sequence = parser.ParseStaticFinalGetter(func); | 956 node_sequence = parser.ParseStaticFinalGetter(func); |
959 INC_STAT(isolate, num_implicit_final_getters, 1); | 957 INC_STAT(thread, num_implicit_final_getters, 1); |
960 break; | 958 break; |
961 case RawFunction::kMethodExtractor: | 959 case RawFunction::kMethodExtractor: |
962 node_sequence = parser.ParseMethodExtractor(func); | 960 node_sequence = parser.ParseMethodExtractor(func); |
| 961 INC_STAT(thread, num_method_extractors, 1); |
963 break; | 962 break; |
964 case RawFunction::kNoSuchMethodDispatcher: | 963 case RawFunction::kNoSuchMethodDispatcher: |
965 node_sequence = | 964 node_sequence = |
966 parser.ParseNoSuchMethodDispatcher(func); | 965 parser.ParseNoSuchMethodDispatcher(func); |
967 break; | 966 break; |
968 case RawFunction::kInvokeFieldDispatcher: | 967 case RawFunction::kInvokeFieldDispatcher: |
969 node_sequence = | 968 node_sequence = |
970 parser.ParseInvokeFieldDispatcher(func); | 969 parser.ParseInvokeFieldDispatcher(func); |
971 break; | 970 break; |
972 case RawFunction::kIrregexpFunction: | 971 case RawFunction::kIrregexpFunction: |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1185 if (parsed_function->has_finally_return_temp_var()) { | 1184 if (parsed_function->has_finally_return_temp_var()) { |
1186 body->scope()->AddVariable(parsed_function->finally_return_temp_var()); | 1185 body->scope()->AddVariable(parsed_function->finally_return_temp_var()); |
1187 } | 1186 } |
1188 // The instantiator is not required in a static expression. | 1187 // The instantiator is not required in a static expression. |
1189 ASSERT(!parser.IsInstantiatorRequired()); | 1188 ASSERT(!parser.IsInstantiatorRequired()); |
1190 | 1189 |
1191 return parsed_function; | 1190 return parsed_function; |
1192 } | 1191 } |
1193 | 1192 |
1194 | 1193 |
1195 RawObject* Parser::ParseFunctionFromSource(const Class& owning_class, | |
1196 const String& source) { | |
1197 Thread* thread = Thread::Current(); | |
1198 Isolate* isolate = thread->isolate(); | |
1199 StackZone stack_zone(thread); | |
1200 LongJumpScope jump; | |
1201 if (setjmp(*jump.Set()) == 0) { | |
1202 const String& uri = String::Handle(Symbols::New("dynamically-added")); | |
1203 const Script& script = Script::Handle( | |
1204 Script::New(uri, source, RawScript::kSourceTag)); | |
1205 const Library& owning_library = Library::Handle(owning_class.library()); | |
1206 const String& private_key = String::Handle(owning_library.private_key()); | |
1207 script.Tokenize(private_key); | |
1208 const intptr_t token_pos = 0; | |
1209 Parser parser(script, owning_library, token_pos); | |
1210 parser.is_top_level_ = true; | |
1211 parser.set_current_class(owning_class); | |
1212 const String& class_name = String::Handle(owning_class.Name()); | |
1213 ClassDesc members(stack_zone.GetZone(), | |
1214 owning_class, | |
1215 class_name, | |
1216 false, /* is_interface */ | |
1217 token_pos); | |
1218 const intptr_t metadata_pos = parser.SkipMetadata(); | |
1219 parser.ParseClassMemberDefinition(&members, metadata_pos); | |
1220 ASSERT(members.functions().length() == 1); | |
1221 const Function& func = *members.functions().At(0); | |
1222 func.set_eval_script(script); | |
1223 ParsedFunction* parsed_function = new ParsedFunction(thread, func); | |
1224 Parser::ParseFunction(parsed_function); | |
1225 return func.raw(); | |
1226 } else { | |
1227 const Error& error = Error::Handle(isolate->object_store()->sticky_error()); | |
1228 isolate->object_store()->clear_sticky_error(); | |
1229 return error.raw(); | |
1230 } | |
1231 UNREACHABLE(); | |
1232 return Object::null(); | |
1233 } | |
1234 | |
1235 | |
1236 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) { | 1194 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) { |
1237 TRACE_PARSER("ParseStaticFinalGetter"); | 1195 TRACE_PARSER("ParseStaticFinalGetter"); |
1238 ParamList params; | 1196 ParamList params; |
1239 ASSERT(func.num_fixed_parameters() == 0); // static. | 1197 ASSERT(func.num_fixed_parameters() == 0); // static. |
1240 ASSERT(!func.HasOptionalParameters()); | 1198 ASSERT(!func.HasOptionalParameters()); |
1241 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); | 1199 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
1242 | 1200 |
1243 // Build local scope for function and populate with the formal parameters. | 1201 // Build local scope for function and populate with the formal parameters. |
1244 OpenFunctionBlock(func); | 1202 OpenFunctionBlock(func); |
1245 AddFormalParamsToScope(¶ms, current_block_->scope); | 1203 AddFormalParamsToScope(¶ms, current_block_->scope); |
(...skipping 3377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4623 } else { | 4581 } else { |
4624 CheckToken(Token::kLBRACE); | 4582 CheckToken(Token::kLBRACE); |
4625 SkipBlock(); | 4583 SkipBlock(); |
4626 ExpectToken(Token::kRBRACE); | 4584 ExpectToken(Token::kRBRACE); |
4627 } | 4585 } |
4628 } | 4586 } |
4629 | 4587 |
4630 | 4588 |
4631 void Parser::ParseClassDefinition(const Class& cls) { | 4589 void Parser::ParseClassDefinition(const Class& cls) { |
4632 TRACE_PARSER("ParseClassDefinition"); | 4590 TRACE_PARSER("ParseClassDefinition"); |
4633 INC_STAT(I, num_classes_compiled, 1); | 4591 INC_STAT(thread(), num_classes_parsed, 1); |
4634 set_current_class(cls); | 4592 set_current_class(cls); |
4635 is_top_level_ = true; | 4593 is_top_level_ = true; |
4636 String& class_name = String::Handle(Z, cls.Name()); | 4594 String& class_name = String::Handle(Z, cls.Name()); |
4637 SkipMetadata(); | 4595 SkipMetadata(); |
4638 if (is_patch_source() && | 4596 if (is_patch_source() && |
4639 (CurrentToken() == Token::kIDENT) && | 4597 (CurrentToken() == Token::kIDENT) && |
4640 CurrentLiteral()->Equals("patch")) { | 4598 CurrentLiteral()->Equals("patch")) { |
4641 ConsumeToken(); | 4599 ConsumeToken(); |
4642 } else if (CurrentToken() == Token::kABSTRACT) { | 4600 } else if (CurrentToken() == Token::kABSTRACT) { |
4643 ConsumeToken(); | 4601 ConsumeToken(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4683 Error& error = Error::Handle(Z); | 4641 Error& error = Error::Handle(Z); |
4684 if (!orig_class.ApplyPatch(cls, &error)) { | 4642 if (!orig_class.ApplyPatch(cls, &error)) { |
4685 Report::LongJumpF(error, script_, class_pos, "applying patch failed"); | 4643 Report::LongJumpF(error, script_, class_pos, "applying patch failed"); |
4686 } | 4644 } |
4687 } | 4645 } |
4688 } | 4646 } |
4689 | 4647 |
4690 | 4648 |
4691 void Parser::ParseEnumDefinition(const Class& cls) { | 4649 void Parser::ParseEnumDefinition(const Class& cls) { |
4692 TRACE_PARSER("ParseEnumDefinition"); | 4650 TRACE_PARSER("ParseEnumDefinition"); |
4693 INC_STAT(I, num_classes_compiled, 1); | 4651 INC_STAT(thread(), num_classes_parsed, 1); |
4694 | 4652 |
4695 SkipMetadata(); | 4653 SkipMetadata(); |
4696 ExpectToken(Token::kENUM); | 4654 ExpectToken(Token::kENUM); |
4697 | 4655 |
4698 const String& enum_name = String::Handle(Z, cls.Name()); | 4656 const String& enum_name = String::Handle(Z, cls.Name()); |
4699 ClassDesc enum_members(Z, cls, enum_name, false, cls.token_pos()); | 4657 ClassDesc enum_members(Z, cls, enum_name, false, cls.token_pos()); |
4700 | 4658 |
4701 // Add instance field 'final int index'. | 4659 // Add instance field 'final int index'. |
4702 Field& index_field = Field::ZoneHandle(Z); | 4660 Field& index_field = Field::ZoneHandle(Z); |
4703 const Type& int_type = Type::Handle(Z, Type::IntType()); | 4661 const Type& int_type = Type::Handle(Z, Type::IntType()); |
(...skipping 2998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7702 ASSERT(existing_var != NULL); | 7660 ASSERT(existing_var != NULL); |
7703 // Use before define cases have already been detected and reported above. | 7661 // Use before define cases have already been detected and reported above. |
7704 ASSERT(existing_var->owner() == current_block_->scope); | 7662 ASSERT(existing_var->owner() == current_block_->scope); |
7705 ReportError(function_pos, "identifier '%s' already defined", | 7663 ReportError(function_pos, "identifier '%s' already defined", |
7706 function_variable->name().ToCString()); | 7664 function_variable->name().ToCString()); |
7707 } | 7665 } |
7708 } | 7666 } |
7709 | 7667 |
7710 // Parse the local function. | 7668 // Parse the local function. |
7711 SequenceNode* statements = Parser::ParseFunc(function); | 7669 SequenceNode* statements = Parser::ParseFunc(function); |
| 7670 INC_STAT(thread(), num_functions_parsed, 1); |
7712 | 7671 |
7713 // Now that the local function has formal parameters, lookup the signature | 7672 // Now that the local function has formal parameters, lookup the signature |
7714 // class in the current library (but not in its imports) and only create a new | 7673 // class in the current library (but not in its imports) and only create a new |
7715 // canonical signature class if it does not exist yet. | 7674 // canonical signature class if it does not exist yet. |
7716 const String& signature = String::Handle(Z, function.Signature()); | 7675 const String& signature = String::Handle(Z, function.Signature()); |
7717 Class& signature_class = Class::ZoneHandle(Z); | 7676 Class& signature_class = Class::ZoneHandle(Z); |
7718 if (!is_new_closure) { | 7677 if (!is_new_closure) { |
7719 signature_class = function.signature_class(); | 7678 signature_class = function.signature_class(); |
7720 } | 7679 } |
7721 if (signature_class.IsNull()) { | 7680 if (signature_class.IsNull()) { |
(...skipping 6567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14289 void Parser::SkipQualIdent() { | 14248 void Parser::SkipQualIdent() { |
14290 ASSERT(IsIdentifier()); | 14249 ASSERT(IsIdentifier()); |
14291 ConsumeToken(); | 14250 ConsumeToken(); |
14292 if (CurrentToken() == Token::kPERIOD) { | 14251 if (CurrentToken() == Token::kPERIOD) { |
14293 ConsumeToken(); // Consume the kPERIOD token. | 14252 ConsumeToken(); // Consume the kPERIOD token. |
14294 ExpectIdentifier("identifier expected after '.'"); | 14253 ExpectIdentifier("identifier expected after '.'"); |
14295 } | 14254 } |
14296 } | 14255 } |
14297 | 14256 |
14298 } // namespace dart | 14257 } // namespace dart |
OLD | NEW |