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