Chromium Code Reviews| 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 "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 253 | 253 |
| 254 // For parsing a compilation unit. | 254 // For parsing a compilation unit. |
| 255 Parser::Parser(const Script& script, const Library& library) | 255 Parser::Parser(const Script& script, const Library& library) |
| 256 : script_(script), | 256 : script_(script), |
| 257 tokens_iterator_(TokenStream::Handle(script.tokens()), 0), | 257 tokens_iterator_(TokenStream::Handle(script.tokens()), 0), |
| 258 token_kind_(Token::kILLEGAL), | 258 token_kind_(Token::kILLEGAL), |
| 259 current_block_(NULL), | 259 current_block_(NULL), |
| 260 is_top_level_(false), | 260 is_top_level_(false), |
| 261 current_member_(NULL), | 261 current_member_(NULL), |
| 262 allow_function_literals_(true), | 262 allow_function_literals_(true), |
| 263 current_function_(Function::Handle()), | 263 parsed_function_(NULL), |
| 264 innermost_function_(Function::Handle()), | 264 innermost_function_(Function::Handle()), |
| 265 current_class_(Class::Handle()), | 265 current_class_(Class::Handle()), |
| 266 library_(library), | 266 library_(library), |
| 267 try_blocks_list_(NULL), | 267 try_blocks_list_(NULL) { |
| 268 expression_temp_(NULL), | |
| 269 saved_current_context_(NULL) { | |
| 270 ASSERT(tokens_iterator_.IsValid()); | 268 ASSERT(tokens_iterator_.IsValid()); |
| 271 ASSERT(!library.IsNull()); | 269 ASSERT(!library.IsNull()); |
| 272 } | 270 } |
| 273 | 271 |
| 274 | 272 |
| 275 // For parsing a function. | 273 // For parsing a function. |
| 276 Parser::Parser(const Script& script, | 274 Parser::Parser(const Script& script, |
| 277 const Function& function, | 275 ParsedFunction* parsed_function, |
| 278 intptr_t token_position) | 276 intptr_t token_position) |
| 279 : script_(script), | 277 : script_(script), |
| 280 tokens_iterator_(TokenStream::Handle(script.tokens()), token_position), | 278 tokens_iterator_(TokenStream::Handle(script.tokens()), token_position), |
| 281 token_kind_(Token::kILLEGAL), | 279 token_kind_(Token::kILLEGAL), |
| 282 current_block_(NULL), | 280 current_block_(NULL), |
| 283 is_top_level_(false), | 281 is_top_level_(false), |
| 284 current_member_(NULL), | 282 current_member_(NULL), |
| 285 allow_function_literals_(true), | 283 allow_function_literals_(true), |
| 286 current_function_(function), | 284 parsed_function_(parsed_function), |
| 287 innermost_function_(Function::Handle(function.raw())), | 285 innermost_function_(Function::Handle(parsed_function->function().raw())), |
| 288 current_class_(Class::Handle(current_function_.Owner())), | 286 current_class_(Class::Handle(parsed_function->function().Owner())), |
| 289 library_(Library::Handle(current_class_.library())), | 287 library_(Library::Handle(current_class_.library())), |
| 290 try_blocks_list_(NULL), | 288 try_blocks_list_(NULL) { |
| 291 expression_temp_(NULL), | |
| 292 saved_current_context_(NULL) { | |
| 293 ASSERT(tokens_iterator_.IsValid()); | 289 ASSERT(tokens_iterator_.IsValid()); |
| 294 ASSERT(!function.IsNull()); | 290 ASSERT(!current_function().IsNull()); |
| 295 if (FLAG_enable_type_checks) { | 291 if (FLAG_enable_type_checks) { |
| 296 EnsureExpressionTemp(); | 292 EnsureExpressionTemp(); |
| 297 } | 293 } |
| 298 } | 294 } |
| 299 | 295 |
| 300 | 296 |
| 301 bool Parser::SetAllowFunctionLiterals(bool value) { | 297 bool Parser::SetAllowFunctionLiterals(bool value) { |
| 302 bool current_value = allow_function_literals_; | 298 bool current_value = allow_function_literals_; |
| 303 allow_function_literals_ = value; | 299 allow_function_literals_ = value; |
| 304 return current_value; | 300 return current_value; |
| 305 } | 301 } |
| 306 | 302 |
| 307 | 303 |
| 308 const Function& Parser::current_function() const { | 304 const Function& Parser::current_function() const { |
| 309 return current_function_; | 305 ASSERT(parsed_function() != NULL); |
|
hausner
2013/02/12 19:34:04
You make it illegal to call current_function() whe
siva
2013/02/12 20:47:07
Initially I implemented this to check if parsed_fu
| |
| 306 return parsed_function()->function(); | |
| 310 } | 307 } |
| 311 | 308 |
| 312 | 309 |
| 313 const Function& Parser::innermost_function() const { | 310 const Function& Parser::innermost_function() const { |
| 314 return innermost_function_; | 311 return innermost_function_; |
| 315 } | 312 } |
| 316 | 313 |
| 317 | 314 |
| 318 const Class& Parser::current_class() const { | 315 const Class& Parser::current_class() const { |
| 319 return current_class_; | 316 return current_class_; |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 723 } | 720 } |
| 724 | 721 |
| 725 | 722 |
| 726 void Parser::ParseFunction(ParsedFunction* parsed_function) { | 723 void Parser::ParseFunction(ParsedFunction* parsed_function) { |
| 727 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | 724 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
| 728 Isolate* isolate = Isolate::Current(); | 725 Isolate* isolate = Isolate::Current(); |
| 729 ASSERT(isolate->long_jump_base()->IsSafeToJump()); | 726 ASSERT(isolate->long_jump_base()->IsSafeToJump()); |
| 730 ASSERT(parsed_function != NULL); | 727 ASSERT(parsed_function != NULL); |
| 731 const Function& func = parsed_function->function(); | 728 const Function& func = parsed_function->function(); |
| 732 const Script& script = Script::Handle(isolate, func.script()); | 729 const Script& script = Script::Handle(isolate, func.script()); |
| 733 Parser parser(script, func, func.token_pos()); | 730 Parser parser(script, parsed_function, func.token_pos()); |
| 734 SequenceNode* node_sequence = NULL; | 731 SequenceNode* node_sequence = NULL; |
| 735 Array& default_parameter_values = Array::ZoneHandle(isolate, Array::null()); | 732 Array& default_parameter_values = Array::ZoneHandle(isolate, Array::null()); |
| 736 switch (func.kind()) { | 733 switch (func.kind()) { |
| 737 case RawFunction::kRegularFunction: | 734 case RawFunction::kRegularFunction: |
| 738 case RawFunction::kClosureFunction: | 735 case RawFunction::kClosureFunction: |
| 739 case RawFunction::kGetterFunction: | 736 case RawFunction::kGetterFunction: |
| 740 case RawFunction::kSetterFunction: | 737 case RawFunction::kSetterFunction: |
| 741 case RawFunction::kConstructor: | 738 case RawFunction::kConstructor: |
| 742 // The call to a redirecting factory is redirected. | 739 // The call to a redirecting factory is redirected. |
| 743 ASSERT(!func.IsRedirectingFactory()); | 740 ASSERT(!func.IsRedirectingFactory()); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 758 node_sequence = parser.ParseMethodExtractor(func); | 755 node_sequence = parser.ParseMethodExtractor(func); |
| 759 break; | 756 break; |
| 760 default: | 757 default: |
| 761 UNREACHABLE(); | 758 UNREACHABLE(); |
| 762 } | 759 } |
| 763 | 760 |
| 764 if (!HasReturnNode(node_sequence)) { | 761 if (!HasReturnNode(node_sequence)) { |
| 765 // Add implicit return node. | 762 // Add implicit return node. |
| 766 node_sequence->Add(new ReturnNode(func.end_token_pos())); | 763 node_sequence->Add(new ReturnNode(func.end_token_pos())); |
| 767 } | 764 } |
| 768 if (parser.expression_temp_ != NULL) { | |
| 769 parsed_function->set_expression_temp_var(parser.expression_temp_); | |
| 770 } | |
| 771 if (parsed_function->has_expression_temp_var()) { | 765 if (parsed_function->has_expression_temp_var()) { |
| 772 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); | 766 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); |
| 773 } | 767 } |
| 774 if (parser.saved_current_context_ != NULL) { | 768 if (parsed_function->has_saved_current_context_var()) { |
| 775 parsed_function->set_saved_current_context_var( | |
| 776 parser.saved_current_context_); | |
| 777 node_sequence->scope()->AddVariable( | 769 node_sequence->scope()->AddVariable( |
| 778 parsed_function->saved_current_context_var()); | 770 parsed_function->saved_current_context_var()); |
| 779 } | 771 } |
| 780 parsed_function->SetNodeSequence(node_sequence); | 772 parsed_function->SetNodeSequence(node_sequence); |
| 781 | 773 |
| 782 // The instantiator may be required at run time for generic type checks or | 774 // The instantiator may be required at run time for generic type checks or |
| 783 // allocation of generic types. | 775 // allocation of generic types. |
| 784 if (parser.IsInstantiatorRequired()) { | 776 if (parser.IsInstantiatorRequired()) { |
| 785 // In the case of a local function, only set the instantiator if the | 777 // In the case of a local function, only set the instantiator if the |
| 786 // receiver (or type arguments parameter of a factory) was captured. | 778 // receiver (or type arguments parameter of a factory) was captured. |
| (...skipping 5989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6776 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 6768 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 6777 list->Add(expr); | 6769 list->Add(expr); |
| 6778 } | 6770 } |
| 6779 expressions = list; | 6771 expressions = list; |
| 6780 } | 6772 } |
| 6781 return expressions; | 6773 return expressions; |
| 6782 } | 6774 } |
| 6783 | 6775 |
| 6784 | 6776 |
| 6785 const LocalVariable* Parser::GetIncrementTempLocal() { | 6777 const LocalVariable* Parser::GetIncrementTempLocal() { |
| 6786 if (expression_temp_ == NULL) { | 6778 if (!parsed_function()->has_expression_temp_var()) { |
| 6787 expression_temp_ = ParsedFunction::CreateExpressionTempVar( | 6779 LocalVariable* temp = ParsedFunction::CreateExpressionTempVar( |
| 6788 current_function().token_pos()); | 6780 current_function().token_pos()); |
| 6789 ASSERT(expression_temp_ != NULL); | 6781 ASSERT(temp != NULL); |
| 6782 parsed_function()->set_expression_temp_var(temp); | |
| 6790 } | 6783 } |
| 6791 return expression_temp_; | 6784 ASSERT(parsed_function()->has_expression_temp_var()); |
| 6785 return parsed_function()->expression_temp_var(); | |
| 6792 } | 6786 } |
| 6793 | 6787 |
| 6794 | 6788 |
| 6795 void Parser::EnsureExpressionTemp() { | 6789 void Parser::EnsureExpressionTemp() { |
| 6796 // Temporary used later by the flow_graph_builder. | 6790 // Temporary used later by the flow_graph_builder. |
| 6797 GetIncrementTempLocal(); | 6791 GetIncrementTempLocal(); |
| 6798 } | 6792 } |
| 6799 | 6793 |
| 6800 | 6794 |
| 6801 void Parser::EnsureSavedCurrentContext() { | 6795 void Parser::EnsureSavedCurrentContext() { |
| 6802 // Used later by the flow_graph_builder to save current context. | 6796 // Used later by the flow_graph_builder to save current context. |
| 6803 if (saved_current_context_ == NULL) { | 6797 if (!parsed_function()->has_saved_current_context_var()) { |
| 6804 // Allocate a local variable to save the current context when we call into | 6798 LocalVariable* temp = |
| 6805 // any closure function as the call will destroy the current context. | |
| 6806 saved_current_context_ = | |
| 6807 new LocalVariable(current_function().token_pos(), | 6799 new LocalVariable(current_function().token_pos(), |
| 6808 Symbols::SavedCurrentContextVar(), | 6800 Symbols::SavedCurrentContextVar(), |
| 6809 Type::ZoneHandle(Type::DynamicType())); | 6801 Type::ZoneHandle(Type::DynamicType())); |
| 6802 ASSERT(temp != NULL); | |
| 6803 parsed_function()->set_saved_current_context_var(temp); | |
| 6810 } | 6804 } |
| 6811 } | 6805 } |
| 6812 | 6806 |
| 6813 | 6807 |
| 6814 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, | 6808 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, |
| 6815 const char* s) { | 6809 const char* s) { |
| 6816 char name[64]; | 6810 char name[64]; |
| 6817 OS::SNPrint(name, 64, ":%s%"Pd, s, token_pos); | 6811 OS::SNPrint(name, 64, ":%s%"Pd, s, token_pos); |
| 6818 LocalVariable* temp = | 6812 LocalVariable* temp = |
| 6819 new LocalVariable(token_pos, | 6813 new LocalVariable(token_pos, |
| (...skipping 2964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9784 void Parser::SkipQualIdent() { | 9778 void Parser::SkipQualIdent() { |
| 9785 ASSERT(IsIdentifier()); | 9779 ASSERT(IsIdentifier()); |
| 9786 ConsumeToken(); | 9780 ConsumeToken(); |
| 9787 if (CurrentToken() == Token::kPERIOD) { | 9781 if (CurrentToken() == Token::kPERIOD) { |
| 9788 ConsumeToken(); // Consume the kPERIOD token. | 9782 ConsumeToken(); // Consume the kPERIOD token. |
| 9789 ExpectIdentifier("identifier expected after '.'"); | 9783 ExpectIdentifier("identifier expected after '.'"); |
| 9790 } | 9784 } |
| 9791 } | 9785 } |
| 9792 | 9786 |
| 9793 } // namespace dart | 9787 } // namespace dart |
| OLD | NEW |