| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 *variable_ = previous_; | 456 *variable_ = previous_; |
| 457 } | 457 } |
| 458 | 458 |
| 459 private: | 459 private: |
| 460 Target** variable_; | 460 Target** variable_; |
| 461 Target* previous_; | 461 Target* previous_; |
| 462 }; | 462 }; |
| 463 | 463 |
| 464 | 464 |
| 465 // ---------------------------------------------------------------------------- | 465 // ---------------------------------------------------------------------------- |
| 466 // FunctionState and BlockState together implement the parser's scope stack. | |
| 467 // The parser's current scope is in scope_. The BlockState and | |
| 468 // FunctionState constructors push on the scope stack and the destructors | |
| 469 // pop. They are also used to hold the parser's per-function and per-block | |
| 470 // state. | |
| 471 | |
| 472 class Parser::BlockState BASE_EMBEDDED { | |
| 473 public: | |
| 474 BlockState(Scope** scope_stack, Scope* scope) | |
| 475 : scope_stack_(scope_stack), | |
| 476 outer_scope_(*scope_stack) { | |
| 477 *scope_stack = scope; | |
| 478 } | |
| 479 | |
| 480 ~BlockState() { *scope_stack_ = outer_scope_; } | |
| 481 | |
| 482 private: | |
| 483 Scope** scope_stack_; | |
| 484 Scope* outer_scope_; | |
| 485 }; | |
| 486 | |
| 487 | |
| 488 Parser::FunctionState::FunctionState(FunctionState** function_state_stack, | |
| 489 Scope** scope_stack, Scope* scope, | |
| 490 Zone* zone) | |
| 491 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | |
| 492 next_handler_index_(0), | |
| 493 expected_property_count_(0), | |
| 494 generator_object_variable_(NULL), | |
| 495 function_state_stack_(function_state_stack), | |
| 496 outer_function_state_(*function_state_stack), | |
| 497 scope_stack_(scope_stack), | |
| 498 outer_scope_(*scope_stack), | |
| 499 isolate_(zone->isolate()), | |
| 500 saved_ast_node_id_(isolate_->ast_node_id()), | |
| 501 factory_(zone) { | |
| 502 *scope_stack_ = scope; | |
| 503 *function_state_stack = this; | |
| 504 isolate_->set_ast_node_id(BailoutId::FirstUsable().ToInt()); | |
| 505 } | |
| 506 | |
| 507 | |
| 508 Parser::FunctionState::~FunctionState() { | |
| 509 *scope_stack_ = outer_scope_; | |
| 510 *function_state_stack_ = outer_function_state_; | |
| 511 if (outer_function_state_ != NULL) { | |
| 512 isolate_->set_ast_node_id(saved_ast_node_id_); | |
| 513 } | |
| 514 } | |
| 515 | |
| 516 | |
| 517 // ---------------------------------------------------------------------------- | |
| 518 // The CHECK_OK macro is a convenient macro to enforce error | 466 // The CHECK_OK macro is a convenient macro to enforce error |
| 519 // handling for functions that may fail (by returning !*ok). | 467 // handling for functions that may fail (by returning !*ok). |
| 520 // | 468 // |
| 521 // CAUTION: This macro appends extra statements after a call, | 469 // CAUTION: This macro appends extra statements after a call, |
| 522 // thus it must never be used where only a single statement | 470 // thus it must never be used where only a single statement |
| 523 // is correct (e.g. an if statement branch w/o braces)! | 471 // is correct (e.g. an if statement branch w/o braces)! |
| 524 | 472 |
| 525 #define CHECK_OK ok); \ | 473 #define CHECK_OK ok); \ |
| 526 if (!*ok) return NULL; \ | 474 if (!*ok) return NULL; \ |
| 527 ((void)0 | 475 ((void)0 |
| 528 #define DUMMY ) // to make indentation work | 476 #define DUMMY ) // to make indentation work |
| 529 #undef DUMMY | 477 #undef DUMMY |
| 530 | 478 |
| 531 #define CHECK_FAILED /**/); \ | 479 #define CHECK_FAILED /**/); \ |
| 532 if (failed_) return NULL; \ | 480 if (failed_) return NULL; \ |
| 533 ((void)0 | 481 ((void)0 |
| 534 #define DUMMY ) // to make indentation work | 482 #define DUMMY ) // to make indentation work |
| 535 #undef DUMMY | 483 #undef DUMMY |
| 536 | 484 |
| 537 // ---------------------------------------------------------------------------- | 485 // ---------------------------------------------------------------------------- |
| 538 // Implementation of Parser | 486 // Implementation of Parser |
| 539 | 487 |
| 540 bool ParserTraits::is_classic_mode() const { | |
| 541 return parser_->scope_->is_classic_mode(); | |
| 542 } | |
| 543 | |
| 544 | |
| 545 bool ParserTraits::is_generator() const { | |
| 546 return parser_->function_state_->is_generator(); | |
| 547 } | |
| 548 | |
| 549 | |
| 550 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { | 488 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { |
| 551 return identifier.is_identical_to( | 489 return identifier.is_identical_to( |
| 552 parser_->isolate()->factory()->eval_string()) || | 490 parser_->isolate()->factory()->eval_string()) || |
| 553 identifier.is_identical_to( | 491 identifier.is_identical_to( |
| 554 parser_->isolate()->factory()->arguments_string()); | 492 parser_->isolate()->factory()->arguments_string()); |
| 555 } | 493 } |
| 556 | 494 |
| 557 | 495 |
| 558 int ParserTraits::NextMaterializedLiteralIndex() { | |
| 559 return parser_->function_state_->NextMaterializedLiteralIndex(); | |
| 560 } | |
| 561 | |
| 562 | |
| 563 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 496 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
| 564 const char* message, | 497 const char* message, |
| 565 Vector<const char*> args) { | 498 Vector<const char*> args) { |
| 566 MessageLocation location(parser_->script_, | 499 MessageLocation location(parser_->script_, |
| 567 source_location.beg_pos, | 500 source_location.beg_pos, |
| 568 source_location.end_pos); | 501 source_location.end_pos); |
| 569 Factory* factory = parser_->isolate()->factory(); | 502 Factory* factory = parser_->isolate()->factory(); |
| 570 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); | 503 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); |
| 571 for (int i = 0; i < args.length(); i++) { | 504 for (int i = 0; i < args.length(); i++) { |
| 572 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); | 505 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 if (scanner.is_next_literal_ascii()) { | 549 if (scanner.is_next_literal_ascii()) { |
| 617 return parser_->isolate_->factory()->NewStringFromAscii( | 550 return parser_->isolate_->factory()->NewStringFromAscii( |
| 618 scanner.next_literal_ascii_string(), tenured); | 551 scanner.next_literal_ascii_string(), tenured); |
| 619 } else { | 552 } else { |
| 620 return parser_->isolate_->factory()->NewStringFromTwoByte( | 553 return parser_->isolate_->factory()->NewStringFromTwoByte( |
| 621 scanner.next_literal_utf16_string(), tenured); | 554 scanner.next_literal_utf16_string(), tenured); |
| 622 } | 555 } |
| 623 } | 556 } |
| 624 | 557 |
| 625 | 558 |
| 626 Expression* ParserTraits::NewRegExpLiteral(Handle<String> js_pattern, | |
| 627 Handle<String> js_flags, | |
| 628 int literal_index, | |
| 629 int pos) { | |
| 630 return parser_->factory()->NewRegExpLiteral( | |
| 631 js_pattern, js_flags, literal_index, pos); | |
| 632 } | |
| 633 | |
| 634 Parser::Parser(CompilationInfo* info) | 559 Parser::Parser(CompilationInfo* info) |
| 635 : ParserBase<ParserTraits>(&scanner_, | 560 : ParserBase<ParserTraits>(&scanner_, |
| 636 info->isolate()->stack_guard()->real_climit(), | 561 info->isolate()->stack_guard()->real_climit(), |
| 637 this), | 562 this), |
| 638 isolate_(info->isolate()), | 563 isolate_(info->isolate()), |
| 639 symbol_cache_(0, info->zone()), | 564 symbol_cache_(0, info->zone()), |
| 640 script_(info->script()), | 565 script_(info->script()), |
| 641 scanner_(isolate_->unicode_cache()), | 566 scanner_(isolate_->unicode_cache()), |
| 642 reusable_preparser_(NULL), | 567 reusable_preparser_(NULL), |
| 643 scope_(NULL), | |
| 644 original_scope_(NULL), | 568 original_scope_(NULL), |
| 645 function_state_(NULL), | |
| 646 target_stack_(NULL), | 569 target_stack_(NULL), |
| 647 extension_(info->extension()), | 570 extension_(info->extension()), |
| 648 pre_parse_data_(NULL), | 571 pre_parse_data_(NULL), |
| 649 fni_(NULL), | 572 fni_(NULL), |
| 650 zone_(info->zone()), | 573 zone_(info->zone()), |
| 651 info_(info) { | 574 info_(info) { |
| 652 ASSERT(!script_.is_null()); | 575 ASSERT(!script_.is_null()); |
| 653 isolate_->set_ast_node_id(0); | 576 isolate_->set_ast_node_id(0); |
| 654 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 577 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
| 655 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 578 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
| (...skipping 3403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4059 scope_->SetScopeName(function_name); | 3982 scope_->SetScopeName(function_name); |
| 4060 | 3983 |
| 4061 if (is_generator) { | 3984 if (is_generator) { |
| 4062 // For generators, allocating variables in contexts is currently a win | 3985 // For generators, allocating variables in contexts is currently a win |
| 4063 // because it minimizes the work needed to suspend and resume an | 3986 // because it minimizes the work needed to suspend and resume an |
| 4064 // activation. | 3987 // activation. |
| 4065 scope_->ForceContextAllocation(); | 3988 scope_->ForceContextAllocation(); |
| 4066 | 3989 |
| 4067 // Calling a generator returns a generator object. That object is stored | 3990 // Calling a generator returns a generator object. That object is stored |
| 4068 // in a temporary variable, a definition that is used by "yield" | 3991 // in a temporary variable, a definition that is used by "yield" |
| 4069 // expressions. Presence of a variable for the generator object in the | 3992 // expressions. This also marks the FunctionState as a generator. |
| 4070 // FunctionState indicates that this function is a generator. | |
| 4071 Variable* temp = scope_->DeclarationScope()->NewTemporary( | 3993 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
| 4072 isolate()->factory()->dot_generator_object_string()); | 3994 isolate()->factory()->dot_generator_object_string()); |
| 4073 function_state.set_generator_object_variable(temp); | 3995 function_state.set_generator_object_variable(temp); |
| 4074 } | 3996 } |
| 4075 | 3997 |
| 4076 // FormalParameterList :: | 3998 // FormalParameterList :: |
| 4077 // '(' (Identifier)*[','] ')' | 3999 // '(' (Identifier)*[','] ')' |
| 4078 Expect(Token::LPAREN, CHECK_OK); | 4000 Expect(Token::LPAREN, CHECK_OK); |
| 4079 scope->set_start_position(scanner().location().beg_pos); | 4001 scope->set_start_position(scanner().location().beg_pos); |
| 4080 | 4002 |
| (...skipping 1448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5529 ASSERT(info()->isolate()->has_pending_exception()); | 5451 ASSERT(info()->isolate()->has_pending_exception()); |
| 5530 } else { | 5452 } else { |
| 5531 result = ParseProgram(); | 5453 result = ParseProgram(); |
| 5532 } | 5454 } |
| 5533 } | 5455 } |
| 5534 info()->SetFunction(result); | 5456 info()->SetFunction(result); |
| 5535 return (result != NULL); | 5457 return (result != NULL); |
| 5536 } | 5458 } |
| 5537 | 5459 |
| 5538 } } // namespace v8::internal | 5460 } } // namespace v8::internal |
| OLD | NEW |