| 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 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1191 if (parsed_function->has_finally_return_temp_var()) { | 1190 if (parsed_function->has_finally_return_temp_var()) { |
| 1192 body->scope()->AddVariable(parsed_function->finally_return_temp_var()); | 1191 body->scope()->AddVariable(parsed_function->finally_return_temp_var()); |
| 1193 } | 1192 } |
| 1194 // The instantiator is not required in a static expression. | 1193 // The instantiator is not required in a static expression. |
| 1195 ASSERT(!parser.IsInstantiatorRequired()); | 1194 ASSERT(!parser.IsInstantiatorRequired()); |
| 1196 | 1195 |
| 1197 return parsed_function; | 1196 return parsed_function; |
| 1198 } | 1197 } |
| 1199 | 1198 |
| 1200 | 1199 |
| 1201 RawObject* Parser::ParseFunctionFromSource(const Class& owning_class, | |
| 1202 const String& source) { | |
| 1203 Thread* thread = Thread::Current(); | |
| 1204 Isolate* isolate = thread->isolate(); | |
| 1205 StackZone stack_zone(thread); | |
| 1206 LongJumpScope jump; | |
| 1207 if (setjmp(*jump.Set()) == 0) { | |
| 1208 const String& uri = String::Handle(Symbols::New("dynamically-added")); | |
| 1209 const Script& script = Script::Handle( | |
| 1210 Script::New(uri, source, RawScript::kSourceTag)); | |
| 1211 const Library& owning_library = Library::Handle(owning_class.library()); | |
| 1212 const String& private_key = String::Handle(owning_library.private_key()); | |
| 1213 script.Tokenize(private_key); | |
| 1214 const intptr_t token_pos = 0; | |
| 1215 Parser parser(script, owning_library, token_pos); | |
| 1216 parser.is_top_level_ = true; | |
| 1217 parser.set_current_class(owning_class); | |
| 1218 const String& class_name = String::Handle(owning_class.Name()); | |
| 1219 ClassDesc members(stack_zone.GetZone(), | |
| 1220 owning_class, | |
| 1221 class_name, | |
| 1222 false, /* is_interface */ | |
| 1223 token_pos); | |
| 1224 const intptr_t metadata_pos = parser.SkipMetadata(); | |
| 1225 parser.ParseClassMemberDefinition(&members, metadata_pos); | |
| 1226 ASSERT(members.functions().length() == 1); | |
| 1227 const Function& func = *members.functions().At(0); | |
| 1228 func.set_eval_script(script); | |
| 1229 ParsedFunction* parsed_function = new ParsedFunction(thread, func); | |
| 1230 Parser::ParseFunction(parsed_function); | |
| 1231 return func.raw(); | |
| 1232 } else { | |
| 1233 const Error& error = Error::Handle(isolate->object_store()->sticky_error()); | |
| 1234 isolate->object_store()->clear_sticky_error(); | |
| 1235 return error.raw(); | |
| 1236 } | |
| 1237 UNREACHABLE(); | |
| 1238 return Object::null(); | |
| 1239 } | |
| 1240 | |
| 1241 | |
| 1242 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) { | 1200 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) { |
| 1243 TRACE_PARSER("ParseStaticFinalGetter"); | 1201 TRACE_PARSER("ParseStaticFinalGetter"); |
| 1244 ParamList params; | 1202 ParamList params; |
| 1245 ASSERT(func.num_fixed_parameters() == 0); // static. | 1203 ASSERT(func.num_fixed_parameters() == 0); // static. |
| 1246 ASSERT(!func.HasOptionalParameters()); | 1204 ASSERT(!func.HasOptionalParameters()); |
| 1247 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); | 1205 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
| 1248 | 1206 |
| 1249 // Build local scope for function and populate with the formal parameters. | 1207 // Build local scope for function and populate with the formal parameters. |
| 1250 OpenFunctionBlock(func); | 1208 OpenFunctionBlock(func); |
| 1251 AddFormalParamsToScope(¶ms, current_block_->scope); | 1209 AddFormalParamsToScope(¶ms, current_block_->scope); |
| (...skipping 3391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4643 } else { | 4601 } else { |
| 4644 CheckToken(Token::kLBRACE); | 4602 CheckToken(Token::kLBRACE); |
| 4645 SkipBlock(); | 4603 SkipBlock(); |
| 4646 ExpectToken(Token::kRBRACE); | 4604 ExpectToken(Token::kRBRACE); |
| 4647 } | 4605 } |
| 4648 } | 4606 } |
| 4649 | 4607 |
| 4650 | 4608 |
| 4651 void Parser::ParseClassDefinition(const Class& cls) { | 4609 void Parser::ParseClassDefinition(const Class& cls) { |
| 4652 TRACE_PARSER("ParseClassDefinition"); | 4610 TRACE_PARSER("ParseClassDefinition"); |
| 4653 INC_STAT(I, num_classes_compiled, 1); | 4611 INC_STAT(thread(), num_classes_parsed, 1); |
| 4654 set_current_class(cls); | 4612 set_current_class(cls); |
| 4655 is_top_level_ = true; | 4613 is_top_level_ = true; |
| 4656 String& class_name = String::Handle(Z, cls.Name()); | 4614 String& class_name = String::Handle(Z, cls.Name()); |
| 4657 SkipMetadata(); | 4615 SkipMetadata(); |
| 4658 if (is_patch_source() && | 4616 if (is_patch_source() && |
| 4659 (CurrentToken() == Token::kIDENT) && | 4617 (CurrentToken() == Token::kIDENT) && |
| 4660 CurrentLiteral()->Equals("patch")) { | 4618 CurrentLiteral()->Equals("patch")) { |
| 4661 ConsumeToken(); | 4619 ConsumeToken(); |
| 4662 } else if (CurrentToken() == Token::kABSTRACT) { | 4620 } else if (CurrentToken() == Token::kABSTRACT) { |
| 4663 ConsumeToken(); | 4621 ConsumeToken(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4703 Error& error = Error::Handle(Z); | 4661 Error& error = Error::Handle(Z); |
| 4704 if (!orig_class.ApplyPatch(cls, &error)) { | 4662 if (!orig_class.ApplyPatch(cls, &error)) { |
| 4705 Report::LongJumpF(error, script_, class_pos, "applying patch failed"); | 4663 Report::LongJumpF(error, script_, class_pos, "applying patch failed"); |
| 4706 } | 4664 } |
| 4707 } | 4665 } |
| 4708 } | 4666 } |
| 4709 | 4667 |
| 4710 | 4668 |
| 4711 void Parser::ParseEnumDefinition(const Class& cls) { | 4669 void Parser::ParseEnumDefinition(const Class& cls) { |
| 4712 TRACE_PARSER("ParseEnumDefinition"); | 4670 TRACE_PARSER("ParseEnumDefinition"); |
| 4713 INC_STAT(I, num_classes_compiled, 1); | 4671 INC_STAT(thread(), num_classes_parsed, 1); |
| 4714 | 4672 |
| 4715 SkipMetadata(); | 4673 SkipMetadata(); |
| 4716 ExpectToken(Token::kENUM); | 4674 ExpectToken(Token::kENUM); |
| 4717 | 4675 |
| 4718 const String& enum_name = String::Handle(Z, cls.Name()); | 4676 const String& enum_name = String::Handle(Z, cls.Name()); |
| 4719 ClassDesc enum_members(Z, cls, enum_name, false, cls.token_pos()); | 4677 ClassDesc enum_members(Z, cls, enum_name, false, cls.token_pos()); |
| 4720 | 4678 |
| 4721 // Add instance field 'final int index'. | 4679 // Add instance field 'final int index'. |
| 4722 Field& index_field = Field::ZoneHandle(Z); | 4680 Field& index_field = Field::ZoneHandle(Z); |
| 4723 const Type& int_type = Type::Handle(Z, Type::IntType()); | 4681 const Type& int_type = Type::Handle(Z, Type::IntType()); |
| (...skipping 2957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7681 ASSERT(existing_var != NULL); | 7639 ASSERT(existing_var != NULL); |
| 7682 // Use before define cases have already been detected and reported above. | 7640 // Use before define cases have already been detected and reported above. |
| 7683 ASSERT(existing_var->owner() == current_block_->scope); | 7641 ASSERT(existing_var->owner() == current_block_->scope); |
| 7684 ReportError(function_pos, "identifier '%s' already defined", | 7642 ReportError(function_pos, "identifier '%s' already defined", |
| 7685 function_variable->name().ToCString()); | 7643 function_variable->name().ToCString()); |
| 7686 } | 7644 } |
| 7687 } | 7645 } |
| 7688 | 7646 |
| 7689 // Parse the local function. | 7647 // Parse the local function. |
| 7690 SequenceNode* statements = Parser::ParseFunc(function); | 7648 SequenceNode* statements = Parser::ParseFunc(function); |
| 7649 INC_STAT(thread(), num_functions_parsed, 1); |
| 7691 | 7650 |
| 7692 // Now that the local function has formal parameters, lookup the signature | 7651 // Now that the local function has formal parameters, lookup the signature |
| 7693 // class in the current library (but not in its imports) and only create a new | 7652 // class in the current library (but not in its imports) and only create a new |
| 7694 // canonical signature class if it does not exist yet. | 7653 // canonical signature class if it does not exist yet. |
| 7695 const String& signature = String::Handle(Z, function.Signature()); | 7654 const String& signature = String::Handle(Z, function.Signature()); |
| 7696 Class& signature_class = Class::ZoneHandle(Z); | 7655 Class& signature_class = Class::ZoneHandle(Z); |
| 7697 if (!is_new_closure) { | 7656 if (!is_new_closure) { |
| 7698 signature_class = function.signature_class(); | 7657 signature_class = function.signature_class(); |
| 7699 } | 7658 } |
| 7700 if (signature_class.IsNull()) { | 7659 if (signature_class.IsNull()) { |
| (...skipping 6587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14288 void Parser::SkipQualIdent() { | 14247 void Parser::SkipQualIdent() { |
| 14289 ASSERT(IsIdentifier()); | 14248 ASSERT(IsIdentifier()); |
| 14290 ConsumeToken(); | 14249 ConsumeToken(); |
| 14291 if (CurrentToken() == Token::kPERIOD) { | 14250 if (CurrentToken() == Token::kPERIOD) { |
| 14292 ConsumeToken(); // Consume the kPERIOD token. | 14251 ConsumeToken(); // Consume the kPERIOD token. |
| 14293 ExpectIdentifier("identifier expected after '.'"); | 14252 ExpectIdentifier("identifier expected after '.'"); |
| 14294 } | 14253 } |
| 14295 } | 14254 } |
| 14296 | 14255 |
| 14297 } // namespace dart | 14256 } // namespace dart |
| OLD | NEW |