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 |