OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "api.h" | 7 #include "api.h" |
8 #include "ast.h" | 8 #include "ast.h" |
9 #include "bootstrapper.h" | 9 #include "bootstrapper.h" |
10 #include "char-predicates-inl.h" | 10 #include "char-predicates-inl.h" |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 return store_[PreparseDataConstants::kHeaderSize + position]; | 319 return store_[PreparseDataConstants::kHeaderSize + position]; |
320 } | 320 } |
321 | 321 |
322 | 322 |
323 unsigned* ScriptData::ReadAddress(int position) const { | 323 unsigned* ScriptData::ReadAddress(int position) const { |
324 return &store_[PreparseDataConstants::kHeaderSize + position]; | 324 return &store_[PreparseDataConstants::kHeaderSize + position]; |
325 } | 325 } |
326 | 326 |
327 | 327 |
328 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { | 328 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { |
329 Scope* result = new(zone()) Scope(parent, scope_type, zone()); | 329 ASSERT(string_table_); |
| 330 Scope* result = new(zone()) Scope(parent, scope_type, string_table_, zone()); |
330 result->Initialize(); | 331 result->Initialize(); |
331 return result; | 332 return result; |
332 } | 333 } |
333 | 334 |
334 | 335 |
335 // ---------------------------------------------------------------------------- | 336 // ---------------------------------------------------------------------------- |
336 // Target is a support class to facilitate manipulation of the | 337 // Target is a support class to facilitate manipulation of the |
337 // Parser's target_stack_ (the stack of potential 'break' and | 338 // Parser's target_stack_ (the stack of potential 'break' and |
338 // 'continue' statement targets). Upon construction, a new target is | 339 // 'continue' statement targets). Upon construction, a new target is |
339 // added; it is removed upon destruction. | 340 // added; it is removed upon destruction. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 | 393 |
393 #define CHECK_FAILED /**/); \ | 394 #define CHECK_FAILED /**/); \ |
394 if (failed_) return NULL; \ | 395 if (failed_) return NULL; \ |
395 ((void)0 | 396 ((void)0 |
396 #define DUMMY ) // to make indentation work | 397 #define DUMMY ) // to make indentation work |
397 #undef DUMMY | 398 #undef DUMMY |
398 | 399 |
399 // ---------------------------------------------------------------------------- | 400 // ---------------------------------------------------------------------------- |
400 // Implementation of Parser | 401 // Implementation of Parser |
401 | 402 |
402 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { | 403 bool ParserTraits::IsEvalOrArguments(const AstString* identifier) const { |
403 Factory* factory = parser_->isolate()->factory(); | 404 return identifier == parser_->string_table_->eval_string() || |
404 return identifier.is_identical_to(factory->eval_string()) | 405 identifier == parser_->string_table_->arguments_string(); |
405 || identifier.is_identical_to(factory->arguments_string()); | |
406 } | 406 } |
407 | 407 |
408 | 408 |
409 bool ParserTraits::IsThisProperty(Expression* expression) { | 409 bool ParserTraits::IsThisProperty(Expression* expression) { |
410 ASSERT(expression != NULL); | 410 ASSERT(expression != NULL); |
411 Property* property = expression->AsProperty(); | 411 Property* property = expression->AsProperty(); |
412 return property != NULL && | 412 return property != NULL && |
413 property->obj()->AsVariableProxy() != NULL && | 413 property->obj()->AsVariableProxy() != NULL && |
414 property->obj()->AsVariableProxy()->is_this(); | 414 property->obj()->AsVariableProxy()->is_this(); |
415 } | 415 } |
416 | 416 |
417 | 417 |
418 bool ParserTraits::IsIdentifier(Expression* expression) { | 418 bool ParserTraits::IsIdentifier(Expression* expression) { |
419 VariableProxy* operand = expression->AsVariableProxy(); | 419 VariableProxy* operand = expression->AsVariableProxy(); |
420 return operand != NULL && !operand->is_this(); | 420 return operand != NULL && !operand->is_this(); |
421 } | 421 } |
422 | 422 |
423 | 423 |
424 void ParserTraits::PushPropertyName(FuncNameInferrer* fni, | 424 void ParserTraits::PushPropertyName(FuncNameInferrer* fni, |
425 Expression* expression) { | 425 Expression* expression) { |
426 if (expression->IsPropertyName()) { | 426 if (expression->IsPropertyName()) { |
427 fni->PushLiteralName(expression->AsLiteral()->AsPropertyName()); | 427 fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName()); |
428 } else { | 428 } else { |
429 fni->PushLiteralName( | 429 fni->PushLiteralName(parser_->string_table_->anonymous_function_string()); |
430 parser_->isolate()->factory()->anonymous_function_string()); | |
431 } | 430 } |
432 } | 431 } |
433 | 432 |
434 | 433 |
435 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, | 434 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, |
436 Expression* right) { | 435 Expression* right) { |
437 ASSERT(left != NULL); | 436 ASSERT(left != NULL); |
438 if (left->AsProperty() != NULL && | 437 if (left->AsProperty() != NULL && |
439 right->AsFunctionLiteral() != NULL) { | 438 right->AsFunctionLiteral() != NULL) { |
440 right->AsFunctionLiteral()->set_pretenure(); | 439 right->AsFunctionLiteral()->set_pretenure(); |
441 } | 440 } |
442 } | 441 } |
443 | 442 |
444 | 443 |
445 void ParserTraits::CheckPossibleEvalCall(Expression* expression, | 444 void ParserTraits::CheckPossibleEvalCall(Expression* expression, |
446 Scope* scope) { | 445 Scope* scope) { |
447 VariableProxy* callee = expression->AsVariableProxy(); | 446 VariableProxy* callee = expression->AsVariableProxy(); |
448 if (callee != NULL && | 447 if (callee != NULL && |
449 callee->IsVariable(parser_->isolate()->factory()->eval_string())) { | 448 callee->raw_name() == parser_->string_table_->eval_string()) { |
450 scope->DeclarationScope()->RecordEvalCall(); | 449 scope->DeclarationScope()->RecordEvalCall(); |
451 } | 450 } |
452 } | 451 } |
453 | 452 |
454 | 453 |
455 Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) { | 454 Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) { |
456 VariableProxy* proxy = expression != NULL | 455 VariableProxy* proxy = expression != NULL |
457 ? expression->AsVariableProxy() | 456 ? expression->AsVariableProxy() |
458 : NULL; | 457 : NULL; |
459 if (proxy != NULL) proxy->MarkAsLValue(); | 458 if (proxy != NULL) proxy->MarkAsLValue(); |
460 return expression; | 459 return expression; |
461 } | 460 } |
462 | 461 |
463 | 462 |
464 bool ParserTraits::ShortcutNumericLiteralBinaryExpression( | 463 bool ParserTraits::ShortcutNumericLiteralBinaryExpression( |
465 Expression** x, Expression* y, Token::Value op, int pos, | 464 Expression** x, Expression* y, Token::Value op, int pos, |
466 AstNodeFactory<AstConstructionVisitor>* factory) { | 465 AstNodeFactory<AstConstructionVisitor>* factory) { |
467 if ((*x)->AsLiteral() && (*x)->AsLiteral()->value()->IsNumber() && | 466 if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() && |
468 y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) { | 467 y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) { |
469 double x_val = (*x)->AsLiteral()->value()->Number(); | 468 double x_val = (*x)->AsLiteral()->raw_value()->AsNumber(); |
470 double y_val = y->AsLiteral()->value()->Number(); | 469 double y_val = y->AsLiteral()->raw_value()->AsNumber(); |
471 switch (op) { | 470 switch (op) { |
472 case Token::ADD: | 471 case Token::ADD: |
473 *x = factory->NewNumberLiteral(x_val + y_val, pos); | 472 *x = factory->NewNumberLiteral(x_val + y_val, pos); |
474 return true; | 473 return true; |
475 case Token::SUB: | 474 case Token::SUB: |
476 *x = factory->NewNumberLiteral(x_val - y_val, pos); | 475 *x = factory->NewNumberLiteral(x_val - y_val, pos); |
477 return true; | 476 return true; |
478 case Token::MUL: | 477 case Token::MUL: |
479 *x = factory->NewNumberLiteral(x_val * y_val, pos); | 478 *x = factory->NewNumberLiteral(x_val * y_val, pos); |
480 return true; | 479 return true; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 } | 518 } |
520 return false; | 519 return false; |
521 } | 520 } |
522 | 521 |
523 | 522 |
524 Expression* ParserTraits::BuildUnaryExpression( | 523 Expression* ParserTraits::BuildUnaryExpression( |
525 Expression* expression, Token::Value op, int pos, | 524 Expression* expression, Token::Value op, int pos, |
526 AstNodeFactory<AstConstructionVisitor>* factory) { | 525 AstNodeFactory<AstConstructionVisitor>* factory) { |
527 ASSERT(expression != NULL); | 526 ASSERT(expression != NULL); |
528 if (expression->IsLiteral()) { | 527 if (expression->IsLiteral()) { |
529 Handle<Object> literal = expression->AsLiteral()->value(); | 528 const AstValue* literal = expression->AsLiteral()->raw_value(); |
530 if (op == Token::NOT) { | 529 if (op == Token::NOT) { |
531 // Convert the literal to a boolean condition and negate it. | 530 // Convert the literal to a boolean condition and negate it. |
532 bool condition = literal->BooleanValue(); | 531 bool condition = literal->BooleanValue(); |
533 Handle<Object> result = | 532 return factory->NewLiteral(!condition, pos); |
534 parser_->isolate()->factory()->ToBoolean(!condition); | |
535 return factory->NewLiteral(result, pos); | |
536 } else if (literal->IsNumber()) { | 533 } else if (literal->IsNumber()) { |
537 // Compute some expressions involving only number literals. | 534 // Compute some expressions involving only number literals. |
538 double value = literal->Number(); | 535 double value = literal->AsNumber(); |
539 switch (op) { | 536 switch (op) { |
540 case Token::ADD: | 537 case Token::ADD: |
541 return expression; | 538 return expression; |
542 case Token::SUB: | 539 case Token::SUB: |
543 return factory->NewNumberLiteral(-value, pos); | 540 return factory->NewNumberLiteral(-value, pos); |
544 case Token::BIT_NOT: | 541 case Token::BIT_NOT: |
545 return factory->NewNumberLiteral(~DoubleToInt32(value), pos); | 542 return factory->NewNumberLiteral(~DoubleToInt32(value), pos); |
546 default: | 543 default: |
547 break; | 544 break; |
548 } | 545 } |
(...skipping 12 matching lines...) Expand all Loading... |
561 // ...and one more time for '~foo' => 'foo^(~0)'. | 558 // ...and one more time for '~foo' => 'foo^(~0)'. |
562 if (op == Token::BIT_NOT) { | 559 if (op == Token::BIT_NOT) { |
563 return factory->NewBinaryOperation( | 560 return factory->NewBinaryOperation( |
564 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); | 561 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); |
565 } | 562 } |
566 return factory->NewUnaryOperation(op, expression, pos); | 563 return factory->NewUnaryOperation(op, expression, pos); |
567 } | 564 } |
568 | 565 |
569 | 566 |
570 Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) { | 567 Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) { |
571 return NewThrowError( | 568 return NewThrowError(parser_->string_table_->make_reference_error_string(), |
572 parser_->isolate()->factory()->MakeReferenceError_string(), | 569 message, NULL, pos); |
573 message, HandleVector<Object>(NULL, 0), pos); | |
574 } | 570 } |
575 | 571 |
576 | 572 |
577 Expression* ParserTraits::NewThrowSyntaxError( | 573 Expression* ParserTraits::NewThrowSyntaxError( |
578 const char* message, Handle<Object> arg, int pos) { | 574 const char* message, const AstString* arg, int pos) { |
579 int argc = arg.is_null() ? 0 : 1; | 575 return NewThrowError(parser_->string_table_->make_syntax_error_string(), |
580 Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc); | 576 message, arg, pos); |
581 return NewThrowError( | |
582 parser_->isolate()->factory()->MakeSyntaxError_string(), | |
583 message, arguments, pos); | |
584 } | 577 } |
585 | 578 |
586 | 579 |
587 Expression* ParserTraits::NewThrowTypeError( | 580 Expression* ParserTraits::NewThrowTypeError( |
588 const char* message, Handle<Object> arg, int pos) { | 581 const char* message, const AstString* arg, int pos) { |
589 int argc = arg.is_null() ? 0 : 1; | 582 return NewThrowError(parser_->string_table_->make_type_error_string(), |
590 Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc); | 583 message, arg, pos); |
591 return NewThrowError( | |
592 parser_->isolate()->factory()->MakeTypeError_string(), | |
593 message, arguments, pos); | |
594 } | 584 } |
595 | 585 |
596 | 586 |
597 Expression* ParserTraits::NewThrowError( | 587 Expression* ParserTraits::NewThrowError( |
598 Handle<String> constructor, const char* message, | 588 const AstString* constructor, const char* message, |
599 Vector<Handle<Object> > arguments, int pos) { | 589 const AstString* arg, int pos) { |
600 Zone* zone = parser_->zone(); | 590 Zone* zone = parser_->zone(); |
601 Factory* factory = parser_->isolate()->factory(); | 591 int argc = arg != NULL ? 1 : 0; |
602 int argc = arguments.length(); | 592 const AstString* type = |
603 Handle<FixedArray> elements = factory->NewFixedArray(argc, TENURED); | 593 parser_->string_table_->GetOneByteString(Vector<const uint8_t>( |
604 for (int i = 0; i < argc; i++) { | 594 reinterpret_cast<const uint8_t*>(message), StrLength(message))); |
605 Handle<Object> element = arguments[i]; | 595 ZoneList<const AstString*>* array = |
606 if (!element.is_null()) { | 596 new (zone) ZoneList<const AstString*>(argc, zone); |
607 elements->set(i, *element); | 597 if (arg != NULL) { |
608 } | 598 array->Add(arg, zone); |
609 } | 599 } |
610 Handle<JSArray> array = | 600 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone); |
611 factory->NewJSArrayWithElements(elements, FAST_ELEMENTS, TENURED); | |
612 | |
613 ZoneList<Expression*>* args = new(zone) ZoneList<Expression*>(2, zone); | |
614 Handle<String> type = factory->InternalizeUtf8String(message); | |
615 args->Add(parser_->factory()->NewLiteral(type, pos), zone); | 601 args->Add(parser_->factory()->NewLiteral(type, pos), zone); |
616 args->Add(parser_->factory()->NewLiteral(array, pos), zone); | 602 args->Add(parser_->factory()->NewLiteral(array, pos), zone); |
617 CallRuntime* call_constructor = | 603 CallRuntime* call_constructor = |
618 parser_->factory()->NewCallRuntime(constructor, NULL, args, pos); | 604 parser_->factory()->NewCallRuntime(constructor, NULL, args, pos); |
619 return parser_->factory()->NewThrow(call_constructor, pos); | 605 return parser_->factory()->NewThrow(call_constructor, pos); |
620 } | 606 } |
621 | 607 |
622 | 608 |
623 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 609 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
624 const char* message, | 610 const char* message, |
625 const char* arg, | 611 const char* arg, |
626 bool is_reference_error) { | 612 bool is_reference_error) { |
627 if (parser_->stack_overflow()) { | 613 if (parser_->stack_overflow()) { |
628 // Suppress the error message (syntax error or such) in the presence of a | 614 // Suppress the error message (syntax error or such) in the presence of a |
629 // stack overflow. The isolate allows only one pending exception at at time | 615 // stack overflow. The isolate allows only one pending exception at at time |
630 // and we want to report the stack overflow later. | 616 // and we want to report the stack overflow later. |
631 return; | 617 return; |
632 } | 618 } |
633 parser_->has_pending_error_ = true; | 619 parser_->has_pending_error_ = true; |
634 parser_->pending_error_location_ = source_location; | 620 parser_->pending_error_location_ = source_location; |
635 parser_->pending_error_message_ = message; | 621 parser_->pending_error_message_ = message; |
636 parser_->pending_error_char_arg_ = arg; | 622 parser_->pending_error_char_arg_ = arg; |
637 parser_->pending_error_arg_ = Handle<String>(); | 623 parser_->pending_error_arg_ = NULL; |
638 parser_->pending_error_is_reference_error_ = is_reference_error; | 624 parser_->pending_error_is_reference_error_ = is_reference_error; |
639 } | 625 } |
640 | 626 |
641 | 627 |
642 void ParserTraits::ReportMessage(const char* message, | 628 void ParserTraits::ReportMessage(const char* message, |
643 MaybeHandle<String> arg, | 629 const char* char_arg, |
| 630 bool is_reference_error) { |
| 631 Scanner::Location source_location = parser_->scanner()->location(); |
| 632 ReportMessageAt(source_location, message, char_arg, is_reference_error); |
| 633 } |
| 634 |
| 635 |
| 636 void ParserTraits::ReportMessage(const char* message, |
| 637 const AstString* arg, |
644 bool is_reference_error) { | 638 bool is_reference_error) { |
645 Scanner::Location source_location = parser_->scanner()->location(); | 639 Scanner::Location source_location = parser_->scanner()->location(); |
646 ReportMessageAt(source_location, message, arg, is_reference_error); | 640 ReportMessageAt(source_location, message, arg, is_reference_error); |
647 } | 641 } |
648 | 642 |
649 | 643 |
650 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 644 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
651 const char* message, | 645 const char* message, |
652 MaybeHandle<String> arg, | 646 const AstString* arg, |
653 bool is_reference_error) { | 647 bool is_reference_error) { |
654 if (parser_->stack_overflow()) { | 648 if (parser_->stack_overflow()) { |
655 // Suppress the error message (syntax error or such) in the presence of a | 649 // Suppress the error message (syntax error or such) in the presence of a |
656 // stack overflow. The isolate allows only one pending exception at at time | 650 // stack overflow. The isolate allows only one pending exception at at time |
657 // and we want to report the stack overflow later. | 651 // and we want to report the stack overflow later. |
658 return; | 652 return; |
659 } | 653 } |
660 parser_->has_pending_error_ = true; | 654 parser_->has_pending_error_ = true; |
661 parser_->pending_error_location_ = source_location; | 655 parser_->pending_error_location_ = source_location; |
662 parser_->pending_error_message_ = message; | 656 parser_->pending_error_message_ = message; |
663 parser_->pending_error_char_arg_ = NULL; | 657 parser_->pending_error_char_arg_ = NULL; |
664 parser_->pending_error_arg_ = arg; | 658 parser_->pending_error_arg_ = arg; |
665 parser_->pending_error_is_reference_error_ = is_reference_error; | 659 parser_->pending_error_is_reference_error_ = is_reference_error; |
666 } | 660 } |
667 | 661 |
668 | 662 |
669 Handle<String> ParserTraits::GetSymbol(Scanner* scanner) { | 663 const AstString* ParserTraits::GetSymbol(Scanner* scanner) { |
670 Handle<String> result = | 664 const AstString* result = |
671 parser_->scanner()->AllocateInternalizedString(parser_->isolate()); | 665 parser_->scanner()->CurrentSymbol(parser_->string_table_); |
672 ASSERT(!result.is_null()); | 666 ASSERT(result != NULL); |
673 return result; | 667 return result; |
674 } | 668 } |
675 | 669 |
676 | 670 |
677 Handle<String> ParserTraits::NextLiteralString(Scanner* scanner, | 671 const AstString* ParserTraits::GetNextSymbol(Scanner* scanner) { |
678 PretenureFlag tenured) { | 672 return parser_->scanner()->NextSymbol(parser_->string_table_); |
679 return scanner->AllocateNextLiteralString(parser_->isolate(), tenured); | |
680 } | 673 } |
681 | 674 |
682 | 675 |
683 Expression* ParserTraits::ThisExpression( | 676 Expression* ParserTraits::ThisExpression( |
684 Scope* scope, | 677 Scope* scope, |
685 AstNodeFactory<AstConstructionVisitor>* factory) { | 678 AstNodeFactory<AstConstructionVisitor>* factory) { |
686 return factory->NewVariableProxy(scope->receiver()); | 679 return factory->NewVariableProxy(scope->receiver()); |
687 } | 680 } |
688 | 681 |
689 | 682 |
690 Literal* ParserTraits::ExpressionFromLiteral( | 683 Literal* ParserTraits::ExpressionFromLiteral( |
691 Token::Value token, int pos, | 684 Token::Value token, int pos, |
692 Scanner* scanner, | 685 Scanner* scanner, |
693 AstNodeFactory<AstConstructionVisitor>* factory) { | 686 AstNodeFactory<AstConstructionVisitor>* factory) { |
694 Factory* isolate_factory = parser_->isolate()->factory(); | |
695 switch (token) { | 687 switch (token) { |
696 case Token::NULL_LITERAL: | 688 case Token::NULL_LITERAL: |
697 return factory->NewLiteral(isolate_factory->null_value(), pos); | 689 return factory->NewLiteral( |
| 690 parser_->string_table_->NewValue(AstValue::NULL_TYPE), pos); |
698 case Token::TRUE_LITERAL: | 691 case Token::TRUE_LITERAL: |
699 return factory->NewLiteral(isolate_factory->true_value(), pos); | 692 return factory->NewLiteral(true, pos); |
700 case Token::FALSE_LITERAL: | 693 case Token::FALSE_LITERAL: |
701 return factory->NewLiteral(isolate_factory->false_value(), pos); | 694 return factory->NewLiteral(false, pos); |
702 case Token::NUMBER: { | 695 case Token::NUMBER: { |
703 double value = scanner->DoubleValue(); | 696 double value = scanner->DoubleValue(); |
704 return factory->NewNumberLiteral(value, pos); | 697 return factory->NewNumberLiteral(value, pos); |
705 } | 698 } |
706 default: | 699 default: |
707 ASSERT(false); | 700 ASSERT(false); |
708 } | 701 } |
709 return NULL; | 702 return NULL; |
710 } | 703 } |
711 | 704 |
712 | 705 |
713 Expression* ParserTraits::ExpressionFromIdentifier( | 706 Expression* ParserTraits::ExpressionFromIdentifier( |
714 Handle<String> name, int pos, Scope* scope, | 707 const AstString* name, int pos, Scope* scope, |
715 AstNodeFactory<AstConstructionVisitor>* factory) { | 708 AstNodeFactory<AstConstructionVisitor>* factory) { |
716 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); | 709 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); |
717 // The name may refer to a module instance object, so its type is unknown. | 710 // The name may refer to a module instance object, so its type is unknown. |
718 #ifdef DEBUG | 711 #ifdef DEBUG |
719 if (FLAG_print_interface_details) | 712 if (FLAG_print_interface_details) |
720 PrintF("# Variable %s ", name->ToAsciiArray()); | 713 PrintF("# Variable %.*s ", name->length(), name->raw_data()); |
721 #endif | 714 #endif |
722 Interface* interface = Interface::NewUnknown(parser_->zone()); | 715 Interface* interface = Interface::NewUnknown(parser_->zone()); |
723 return scope->NewUnresolved(factory, name, interface, pos); | 716 return scope->NewUnresolved(factory, name, interface, pos); |
724 } | 717 } |
725 | 718 |
726 | 719 |
727 Expression* ParserTraits::ExpressionFromString( | 720 Expression* ParserTraits::ExpressionFromString( |
728 int pos, Scanner* scanner, | 721 int pos, Scanner* scanner, |
729 AstNodeFactory<AstConstructionVisitor>* factory) { | 722 AstNodeFactory<AstConstructionVisitor>* factory) { |
730 Handle<String> symbol = GetSymbol(scanner); | 723 const AstString* symbol = GetSymbol(scanner); |
731 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); | 724 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); |
732 return factory->NewLiteral(symbol, pos); | 725 return factory->NewLiteral(symbol, pos); |
733 } | 726 } |
734 | 727 |
735 | 728 |
736 Literal* ParserTraits::GetLiteralTheHole( | 729 Literal* ParserTraits::GetLiteralTheHole( |
737 int position, AstNodeFactory<AstConstructionVisitor>* factory) { | 730 int position, AstNodeFactory<AstConstructionVisitor>* factory) { |
738 return factory->NewLiteral(parser_->isolate()->factory()->the_hole_value(), | 731 return factory->NewLiteral( |
739 RelocInfo::kNoPosition); | 732 parser_->string_table_->NewValue(AstValue::THE_HOLE), |
| 733 RelocInfo::kNoPosition); |
740 } | 734 } |
741 | 735 |
742 | 736 |
743 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { | 737 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { |
744 return parser_->ParseV8Intrinsic(ok); | 738 return parser_->ParseV8Intrinsic(ok); |
745 } | 739 } |
746 | 740 |
747 | 741 |
748 FunctionLiteral* ParserTraits::ParseFunctionLiteral( | 742 FunctionLiteral* ParserTraits::ParseFunctionLiteral( |
749 Handle<String> name, | 743 const AstString* name, |
750 Scanner::Location function_name_location, | 744 Scanner::Location function_name_location, |
751 bool name_is_strict_reserved, | 745 bool name_is_strict_reserved, |
752 bool is_generator, | 746 bool is_generator, |
753 int function_token_position, | 747 int function_token_position, |
754 FunctionLiteral::FunctionType type, | 748 FunctionLiteral::FunctionType type, |
755 bool* ok) { | 749 bool* ok) { |
756 return parser_->ParseFunctionLiteral(name, function_name_location, | 750 return parser_->ParseFunctionLiteral(name, function_name_location, |
757 name_is_strict_reserved, is_generator, | 751 name_is_strict_reserved, is_generator, |
758 function_token_position, type, ok); | 752 function_token_position, type, ok); |
759 } | 753 } |
760 | 754 |
761 | 755 |
762 Parser::Parser(CompilationInfo* info) | 756 Parser::Parser(CompilationInfo* info) |
763 : ParserBase<ParserTraits>(&scanner_, | 757 : ParserBase<ParserTraits>(&scanner_, |
764 info->isolate()->stack_guard()->real_climit(), | 758 info->isolate()->stack_guard()->real_climit(), |
765 info->extension(), | 759 info->extension(), |
766 NULL, | 760 NULL, |
767 info->zone(), | 761 info->zone(), |
768 this), | 762 this), |
769 isolate_(info->isolate()), | 763 isolate_(info->isolate()), |
770 script_(info->script()), | 764 script_(info->script()), |
771 scanner_(isolate_->unicode_cache()), | 765 scanner_(isolate_->unicode_cache()), |
772 reusable_preparser_(NULL), | 766 reusable_preparser_(NULL), |
773 original_scope_(NULL), | 767 original_scope_(NULL), |
774 target_stack_(NULL), | 768 target_stack_(NULL), |
775 cached_data_(NULL), | 769 cached_data_(NULL), |
776 cached_data_mode_(NO_CACHED_DATA), | 770 cached_data_mode_(NO_CACHED_DATA), |
| 771 string_table_(NULL), |
777 info_(info), | 772 info_(info), |
778 has_pending_error_(false), | 773 has_pending_error_(false), |
779 pending_error_message_(NULL), | 774 pending_error_message_(NULL), |
| 775 pending_error_arg_(NULL), |
780 pending_error_char_arg_(NULL) { | 776 pending_error_char_arg_(NULL) { |
781 ASSERT(!script_.is_null()); | 777 ASSERT(!script_.is_null()); |
782 isolate_->set_ast_node_id(0); | 778 isolate_->set_ast_node_id(0); |
783 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 779 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
784 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 780 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
785 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 781 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
786 set_allow_lazy(false); // Must be explicitly enabled. | 782 set_allow_lazy(false); // Must be explicitly enabled. |
787 set_allow_generators(FLAG_harmony_generators); | 783 set_allow_generators(FLAG_harmony_generators); |
788 set_allow_for_of(FLAG_harmony_iteration); | 784 set_allow_for_of(FLAG_harmony_iteration); |
789 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 785 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
790 } | 786 } |
791 | 787 |
792 | 788 |
793 FunctionLiteral* Parser::ParseProgram() { | 789 FunctionLiteral* Parser::ParseProgram() { |
794 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, | 790 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
795 // see comment for HistogramTimerScope class. | 791 // see comment for HistogramTimerScope class. |
796 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); | 792 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); |
797 Handle<String> source(String::cast(script_->source())); | 793 Handle<String> source(String::cast(script_->source())); |
798 isolate()->counters()->total_parse_size()->Increment(source->length()); | 794 isolate()->counters()->total_parse_size()->Increment(source->length()); |
799 ElapsedTimer timer; | 795 ElapsedTimer timer; |
800 if (FLAG_trace_parse) { | 796 if (FLAG_trace_parse) { |
801 timer.Start(); | 797 timer.Start(); |
802 } | 798 } |
803 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 799 fni_ = new(zone()) FuncNameInferrer(string_table_, zone()); |
804 | 800 |
805 // Initialize parser state. | 801 // Initialize parser state. |
806 CompleteParserRecorder recorder; | 802 CompleteParserRecorder recorder; |
807 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { | 803 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { |
808 log_ = &recorder; | 804 log_ = &recorder; |
809 } else if (cached_data_mode_ == CONSUME_CACHED_DATA) { | 805 } else if (cached_data_mode_ == CONSUME_CACHED_DATA) { |
810 (*cached_data_)->Initialize(); | 806 (*cached_data_)->Initialize(); |
811 } | 807 } |
812 | 808 |
813 source = String::Flatten(source); | 809 source = String::Flatten(source); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
848 } | 844 } |
849 return result; | 845 return result; |
850 } | 846 } |
851 | 847 |
852 | 848 |
853 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, | 849 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
854 Handle<String> source) { | 850 Handle<String> source) { |
855 ASSERT(scope_ == NULL); | 851 ASSERT(scope_ == NULL); |
856 ASSERT(target_stack_ == NULL); | 852 ASSERT(target_stack_ == NULL); |
857 | 853 |
858 Handle<String> no_name = isolate()->factory()->empty_string(); | |
859 | |
860 FunctionLiteral* result = NULL; | 854 FunctionLiteral* result = NULL; |
861 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); | 855 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
862 info->SetGlobalScope(scope); | 856 info->SetGlobalScope(scope); |
863 if (!info->context().is_null()) { | 857 if (!info->context().is_null()) { |
864 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); | 858 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); |
| 859 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this |
| 860 // means the Parser cannot operate independent of the V8 heap. Tell the |
| 861 // string table to internalize strings and values right after they're |
| 862 // created. |
| 863 string_table_->Internalize(isolate()); |
865 } | 864 } |
866 original_scope_ = scope; | 865 original_scope_ = scope; |
867 if (info->is_eval()) { | 866 if (info->is_eval()) { |
868 if (!scope->is_global_scope() || info->strict_mode() == STRICT) { | 867 if (!scope->is_global_scope() || info->strict_mode() == STRICT) { |
869 scope = NewScope(scope, EVAL_SCOPE); | 868 scope = NewScope(scope, EVAL_SCOPE); |
870 } | 869 } |
871 } else if (info->is_global()) { | 870 } else if (info->is_global()) { |
872 scope = NewScope(scope, GLOBAL_SCOPE); | 871 scope = NewScope(scope, GLOBAL_SCOPE); |
873 } | 872 } |
874 scope->set_start_position(0); | 873 scope->set_start_position(0); |
875 scope->set_end_position(source->length()); | 874 scope->set_end_position(source->length()); |
876 | 875 |
877 // Compute the parsing mode. | 876 // Compute the parsing mode. |
878 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; | 877 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; |
879 if (allow_natives_syntax() || | 878 if (allow_natives_syntax() || |
880 extension_ != NULL || | 879 extension_ != NULL || |
881 scope->is_eval_scope()) { | 880 scope->is_eval_scope()) { |
882 mode = PARSE_EAGERLY; | 881 mode = PARSE_EAGERLY; |
883 } | 882 } |
884 ParsingModeScope parsing_mode(this, mode); | 883 ParsingModeScope parsing_mode(this, mode); |
885 | 884 |
886 // Enters 'scope'. | 885 // Enters 'scope'. |
887 FunctionState function_state(&function_state_, &scope_, scope, zone()); | 886 FunctionState function_state(&function_state_, &scope_, scope, zone(), |
| 887 string_table_); |
888 | 888 |
889 scope_->SetStrictMode(info->strict_mode()); | 889 scope_->SetStrictMode(info->strict_mode()); |
890 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 890 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
891 bool ok = true; | 891 bool ok = true; |
892 int beg_pos = scanner()->location().beg_pos; | 892 int beg_pos = scanner()->location().beg_pos; |
893 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); | 893 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); |
894 if (ok && strict_mode() == STRICT) { | 894 if (ok && strict_mode() == STRICT) { |
895 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); | 895 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); |
896 } | 896 } |
897 | 897 |
898 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { | 898 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { |
899 CheckConflictingVarDeclarations(scope_, &ok); | 899 CheckConflictingVarDeclarations(scope_, &ok); |
900 } | 900 } |
901 | 901 |
902 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 902 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
903 if (body->length() != 1 || | 903 if (body->length() != 1 || |
904 !body->at(0)->IsExpressionStatement() || | 904 !body->at(0)->IsExpressionStatement() || |
905 !body->at(0)->AsExpressionStatement()-> | 905 !body->at(0)->AsExpressionStatement()-> |
906 expression()->IsFunctionLiteral()) { | 906 expression()->IsFunctionLiteral()) { |
907 ReportMessage("single_function_literal"); | 907 ReportMessage("single_function_literal"); |
908 ok = false; | 908 ok = false; |
909 } | 909 } |
910 } | 910 } |
911 | 911 |
912 if (ok) { | 912 if (ok) { |
913 result = factory()->NewFunctionLiteral( | 913 result = factory()->NewFunctionLiteral( |
914 no_name, | 914 string_table_->empty_string(), |
| 915 string_table_, |
915 scope_, | 916 scope_, |
916 body, | 917 body, |
917 function_state.materialized_literal_count(), | 918 function_state.materialized_literal_count(), |
918 function_state.expected_property_count(), | 919 function_state.expected_property_count(), |
919 function_state.handler_count(), | 920 function_state.handler_count(), |
920 0, | 921 0, |
921 FunctionLiteral::kNoDuplicateParameters, | 922 FunctionLiteral::kNoDuplicateParameters, |
922 FunctionLiteral::ANONYMOUS_EXPRESSION, | 923 FunctionLiteral::ANONYMOUS_EXPRESSION, |
923 FunctionLiteral::kGlobalOrEval, | 924 FunctionLiteral::kGlobalOrEval, |
924 FunctionLiteral::kNotParenthesized, | 925 FunctionLiteral::kNotParenthesized, |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
976 } | 977 } |
977 | 978 |
978 | 979 |
979 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { | 980 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { |
980 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 981 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); |
981 scanner_.Initialize(source); | 982 scanner_.Initialize(source); |
982 ASSERT(scope_ == NULL); | 983 ASSERT(scope_ == NULL); |
983 ASSERT(target_stack_ == NULL); | 984 ASSERT(target_stack_ == NULL); |
984 | 985 |
985 Handle<String> name(String::cast(shared_info->name())); | 986 Handle<String> name(String::cast(shared_info->name())); |
986 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 987 ASSERT(string_table_); |
987 fni_->PushEnclosingName(name); | 988 fni_ = new(zone()) FuncNameInferrer(string_table_, zone()); |
| 989 const AstString* raw_name = string_table_->GetString(name); |
| 990 fni_->PushEnclosingName(raw_name); |
988 | 991 |
989 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 992 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
990 | 993 |
991 // Place holder for the result. | 994 // Place holder for the result. |
992 FunctionLiteral* result = NULL; | 995 FunctionLiteral* result = NULL; |
993 | 996 |
994 { | 997 { |
995 // Parse the function literal. | 998 // Parse the function literal. |
996 Scope* scope = NewScope(scope_, GLOBAL_SCOPE); | 999 Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
997 info()->SetGlobalScope(scope); | 1000 info()->SetGlobalScope(scope); |
998 if (!info()->closure().is_null()) { | 1001 if (!info()->closure().is_null()) { |
999 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, | 1002 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, |
1000 zone()); | 1003 zone()); |
1001 } | 1004 } |
1002 original_scope_ = scope; | 1005 original_scope_ = scope; |
1003 FunctionState function_state(&function_state_, &scope_, scope, zone()); | 1006 FunctionState function_state(&function_state_, &scope_, scope, zone(), |
| 1007 string_table_); |
1004 ASSERT(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT); | 1008 ASSERT(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT); |
1005 ASSERT(info()->strict_mode() == shared_info->strict_mode()); | 1009 ASSERT(info()->strict_mode() == shared_info->strict_mode()); |
1006 scope->SetStrictMode(shared_info->strict_mode()); | 1010 scope->SetStrictMode(shared_info->strict_mode()); |
1007 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 1011 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
1008 ? (shared_info->is_anonymous() | 1012 ? (shared_info->is_anonymous() |
1009 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 1013 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
1010 : FunctionLiteral::NAMED_EXPRESSION) | 1014 : FunctionLiteral::NAMED_EXPRESSION) |
1011 : FunctionLiteral::DECLARATION; | 1015 : FunctionLiteral::DECLARATION; |
1012 bool ok = true; | 1016 bool ok = true; |
1013 result = ParseFunctionLiteral(name, | 1017 result = ParseFunctionLiteral(raw_name, |
1014 Scanner::Location::invalid(), | 1018 Scanner::Location::invalid(), |
1015 false, // Strict mode name already checked. | 1019 false, // Strict mode name already checked. |
1016 shared_info->is_generator(), | 1020 shared_info->is_generator(), |
1017 RelocInfo::kNoPosition, | 1021 RelocInfo::kNoPosition, |
1018 function_type, | 1022 function_type, |
1019 &ok); | 1023 &ok); |
1020 // Make sure the results agree. | 1024 // Make sure the results agree. |
1021 ASSERT(ok == (result != NULL)); | 1025 ASSERT(ok == (result != NULL)); |
1022 } | 1026 } |
1023 | 1027 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1072 continue; | 1076 continue; |
1073 } | 1077 } |
1074 | 1078 |
1075 if (directive_prologue) { | 1079 if (directive_prologue) { |
1076 // A shot at a directive. | 1080 // A shot at a directive. |
1077 ExpressionStatement* e_stat; | 1081 ExpressionStatement* e_stat; |
1078 Literal* literal; | 1082 Literal* literal; |
1079 // Still processing directive prologue? | 1083 // Still processing directive prologue? |
1080 if ((e_stat = stat->AsExpressionStatement()) != NULL && | 1084 if ((e_stat = stat->AsExpressionStatement()) != NULL && |
1081 (literal = e_stat->expression()->AsLiteral()) != NULL && | 1085 (literal = e_stat->expression()->AsLiteral()) != NULL && |
1082 literal->value()->IsString()) { | 1086 literal->raw_value()->IsString()) { |
1083 Handle<String> directive = Handle<String>::cast(literal->value()); | |
1084 | |
1085 // Check "use strict" directive (ES5 14.1). | 1087 // Check "use strict" directive (ES5 14.1). |
1086 if (strict_mode() == SLOPPY && | 1088 if (strict_mode() == SLOPPY && |
1087 String::Equals(isolate()->factory()->use_strict_string(), | 1089 literal->raw_value()->AsString() == |
1088 directive) && | 1090 string_table_->use_strict_string() && |
1089 token_loc.end_pos - token_loc.beg_pos == | 1091 token_loc.end_pos - token_loc.beg_pos == 12) { |
1090 isolate()->heap()->use_strict_string()->length() + 2) { | |
1091 // TODO(mstarzinger): Global strict eval calls, need their own scope | 1092 // TODO(mstarzinger): Global strict eval calls, need their own scope |
1092 // as specified in ES5 10.4.2(3). The correct fix would be to always | 1093 // as specified in ES5 10.4.2(3). The correct fix would be to always |
1093 // add this scope in DoParseProgram(), but that requires adaptations | 1094 // add this scope in DoParseProgram(), but that requires adaptations |
1094 // all over the code base, so we go with a quick-fix for now. | 1095 // all over the code base, so we go with a quick-fix for now. |
1095 // In the same manner, we have to patch the parsing mode. | 1096 // In the same manner, we have to patch the parsing mode. |
1096 if (is_eval && !scope_->is_eval_scope()) { | 1097 if (is_eval && !scope_->is_eval_scope()) { |
1097 ASSERT(scope_->is_global_scope()); | 1098 ASSERT(scope_->is_global_scope()); |
1098 Scope* scope = NewScope(scope_, EVAL_SCOPE); | 1099 Scope* scope = NewScope(scope_, EVAL_SCOPE); |
1099 scope->set_start_position(scope_->start_position()); | 1100 scope->set_start_position(scope_->start_position()); |
1100 scope->set_end_position(scope_->end_position()); | 1101 scope->set_end_position(scope_->end_position()); |
(...skipping 10 matching lines...) Expand all Loading... |
1111 } | 1112 } |
1112 } | 1113 } |
1113 | 1114 |
1114 processor->Add(stat, zone()); | 1115 processor->Add(stat, zone()); |
1115 } | 1116 } |
1116 | 1117 |
1117 return 0; | 1118 return 0; |
1118 } | 1119 } |
1119 | 1120 |
1120 | 1121 |
1121 Statement* Parser::ParseModuleElement(ZoneStringList* labels, | 1122 Statement* Parser::ParseModuleElement(ZoneList<const AstString*>* labels, |
1122 bool* ok) { | 1123 bool* ok) { |
1123 // (Ecma 262 5th Edition, clause 14): | 1124 // (Ecma 262 5th Edition, clause 14): |
1124 // SourceElement: | 1125 // SourceElement: |
1125 // Statement | 1126 // Statement |
1126 // FunctionDeclaration | 1127 // FunctionDeclaration |
1127 // | 1128 // |
1128 // In harmony mode we allow additionally the following productions | 1129 // In harmony mode we allow additionally the following productions |
1129 // ModuleElement: | 1130 // ModuleElement: |
1130 // LetDeclaration | 1131 // LetDeclaration |
1131 // ConstDeclaration | 1132 // ConstDeclaration |
(...skipping 13 matching lines...) Expand all Loading... |
1145 case Token::EXPORT: | 1146 case Token::EXPORT: |
1146 return ParseExportDeclaration(ok); | 1147 return ParseExportDeclaration(ok); |
1147 default: { | 1148 default: { |
1148 Statement* stmt = ParseStatement(labels, CHECK_OK); | 1149 Statement* stmt = ParseStatement(labels, CHECK_OK); |
1149 // Handle 'module' as a context-sensitive keyword. | 1150 // Handle 'module' as a context-sensitive keyword. |
1150 if (FLAG_harmony_modules && | 1151 if (FLAG_harmony_modules && |
1151 peek() == Token::IDENTIFIER && | 1152 peek() == Token::IDENTIFIER && |
1152 !scanner()->HasAnyLineTerminatorBeforeNext() && | 1153 !scanner()->HasAnyLineTerminatorBeforeNext() && |
1153 stmt != NULL) { | 1154 stmt != NULL) { |
1154 ExpressionStatement* estmt = stmt->AsExpressionStatement(); | 1155 ExpressionStatement* estmt = stmt->AsExpressionStatement(); |
1155 if (estmt != NULL && | 1156 if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL && |
1156 estmt->expression()->AsVariableProxy() != NULL && | 1157 estmt->expression()->AsVariableProxy()->raw_name() == |
1157 String::Equals(isolate()->factory()->module_string(), | 1158 string_table_->module_string() && |
1158 estmt->expression()->AsVariableProxy()->name()) && | |
1159 !scanner()->literal_contains_escapes()) { | 1159 !scanner()->literal_contains_escapes()) { |
1160 return ParseModuleDeclaration(NULL, ok); | 1160 return ParseModuleDeclaration(NULL, ok); |
1161 } | 1161 } |
1162 } | 1162 } |
1163 return stmt; | 1163 return stmt; |
1164 } | 1164 } |
1165 } | 1165 } |
1166 } | 1166 } |
1167 | 1167 |
1168 | 1168 |
1169 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { | 1169 Statement* Parser::ParseModuleDeclaration(ZoneList<const AstString*>* names, |
| 1170 bool* ok) { |
1170 // ModuleDeclaration: | 1171 // ModuleDeclaration: |
1171 // 'module' Identifier Module | 1172 // 'module' Identifier Module |
1172 | 1173 |
1173 int pos = peek_position(); | 1174 int pos = peek_position(); |
1174 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1175 const AstString* name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
1175 | 1176 |
1176 #ifdef DEBUG | 1177 #ifdef DEBUG |
1177 if (FLAG_print_interface_details) | 1178 if (FLAG_print_interface_details) |
1178 PrintF("# Module %s...\n", name->ToAsciiArray()); | 1179 PrintF("# Module %.*s ", name->length(), name->raw_data()); |
1179 #endif | 1180 #endif |
1180 | 1181 |
1181 Module* module = ParseModule(CHECK_OK); | 1182 Module* module = ParseModule(CHECK_OK); |
1182 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); | 1183 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); |
1183 Declaration* declaration = | 1184 Declaration* declaration = |
1184 factory()->NewModuleDeclaration(proxy, module, scope_, pos); | 1185 factory()->NewModuleDeclaration(proxy, module, scope_, pos); |
1185 Declare(declaration, true, CHECK_OK); | 1186 Declare(declaration, true, CHECK_OK); |
1186 | 1187 |
1187 #ifdef DEBUG | 1188 #ifdef DEBUG |
1188 if (FLAG_print_interface_details) | 1189 if (FLAG_print_interface_details) |
1189 PrintF("# Module %s.\n", name->ToAsciiArray()); | 1190 PrintF("# Module %.*s ", name->length(), name->raw_data()); |
1190 | |
1191 if (FLAG_print_interfaces) { | 1191 if (FLAG_print_interfaces) { |
1192 PrintF("module %s : ", name->ToAsciiArray()); | 1192 PrintF("module %.*s: ", name->length(), name->raw_data()); |
1193 module->interface()->Print(); | 1193 module->interface()->Print(); |
1194 } | 1194 } |
1195 #endif | 1195 #endif |
1196 | 1196 |
1197 if (names) names->Add(name, zone()); | 1197 if (names) names->Add(name, zone()); |
1198 if (module->body() == NULL) | 1198 if (module->body() == NULL) |
1199 return factory()->NewEmptyStatement(pos); | 1199 return factory()->NewEmptyStatement(pos); |
1200 else | 1200 else |
1201 return factory()->NewModuleStatement(proxy, module->body(), pos); | 1201 return factory()->NewModuleStatement(proxy, module->body(), pos); |
1202 } | 1202 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1283 | 1283 |
1284 | 1284 |
1285 Module* Parser::ParseModulePath(bool* ok) { | 1285 Module* Parser::ParseModulePath(bool* ok) { |
1286 // ModulePath: | 1286 // ModulePath: |
1287 // Identifier | 1287 // Identifier |
1288 // ModulePath '.' Identifier | 1288 // ModulePath '.' Identifier |
1289 | 1289 |
1290 int pos = peek_position(); | 1290 int pos = peek_position(); |
1291 Module* result = ParseModuleVariable(CHECK_OK); | 1291 Module* result = ParseModuleVariable(CHECK_OK); |
1292 while (Check(Token::PERIOD)) { | 1292 while (Check(Token::PERIOD)) { |
1293 Handle<String> name = ParseIdentifierName(CHECK_OK); | 1293 const AstString* name = ParseIdentifierName(CHECK_OK); |
1294 #ifdef DEBUG | 1294 #ifdef DEBUG |
1295 if (FLAG_print_interface_details) | 1295 if (FLAG_print_interface_details) |
1296 PrintF("# Path .%s ", name->ToAsciiArray()); | 1296 PrintF("# Path .%.*s ", name->length(), name->raw_data()); |
1297 #endif | 1297 #endif |
1298 Module* member = factory()->NewModulePath(result, name, pos); | 1298 Module* member = factory()->NewModulePath(result, name, pos); |
1299 result->interface()->Add(name, member->interface(), zone(), ok); | 1299 result->interface()->Add(name, member->interface(), zone(), ok); |
1300 if (!*ok) { | 1300 if (!*ok) { |
1301 #ifdef DEBUG | 1301 #ifdef DEBUG |
1302 if (FLAG_print_interfaces) { | 1302 if (FLAG_print_interfaces) { |
1303 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); | 1303 PrintF("PATH TYPE ERROR at '%.*s'\n", name->length(), name->raw_data()); |
1304 PrintF("result: "); | 1304 PrintF("result: "); |
1305 result->interface()->Print(); | 1305 result->interface()->Print(); |
1306 PrintF("member: "); | 1306 PrintF("member: "); |
1307 member->interface()->Print(); | 1307 member->interface()->Print(); |
1308 } | 1308 } |
1309 #endif | 1309 #endif |
1310 ParserTraits::ReportMessage("invalid_module_path", name); | 1310 ParserTraits::ReportMessage("invalid_module_path", name); |
1311 return NULL; | 1311 return NULL; |
1312 } | 1312 } |
1313 result = member; | 1313 result = member; |
1314 } | 1314 } |
1315 | 1315 |
1316 return result; | 1316 return result; |
1317 } | 1317 } |
1318 | 1318 |
1319 | 1319 |
1320 Module* Parser::ParseModuleVariable(bool* ok) { | 1320 Module* Parser::ParseModuleVariable(bool* ok) { |
1321 // ModulePath: | 1321 // ModulePath: |
1322 // Identifier | 1322 // Identifier |
1323 | 1323 |
1324 int pos = peek_position(); | 1324 int pos = peek_position(); |
1325 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1325 const AstString* name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
1326 #ifdef DEBUG | 1326 #ifdef DEBUG |
1327 if (FLAG_print_interface_details) | 1327 if (FLAG_print_interface_details) |
1328 PrintF("# Module variable %s ", name->ToAsciiArray()); | 1328 PrintF("# Module variable %.*s ", name->length(), name->raw_data()); |
1329 #endif | 1329 #endif |
1330 VariableProxy* proxy = scope_->NewUnresolved( | 1330 VariableProxy* proxy = scope_->NewUnresolved( |
1331 factory(), name, Interface::NewModule(zone()), | 1331 factory(), name, Interface::NewModule(zone()), |
1332 scanner()->location().beg_pos); | 1332 scanner()->location().beg_pos); |
1333 | 1333 |
1334 return factory()->NewModuleVariable(proxy, pos); | 1334 return factory()->NewModuleVariable(proxy, pos); |
1335 } | 1335 } |
1336 | 1336 |
1337 | 1337 |
1338 Module* Parser::ParseModuleUrl(bool* ok) { | 1338 Module* Parser::ParseModuleUrl(bool* ok) { |
1339 // Module: | 1339 // Module: |
1340 // String | 1340 // String |
1341 | 1341 |
1342 int pos = peek_position(); | 1342 int pos = peek_position(); |
1343 Expect(Token::STRING, CHECK_OK); | 1343 Expect(Token::STRING, CHECK_OK); |
1344 Handle<String> symbol = GetSymbol(); | 1344 const AstString* symbol = GetSymbol(scanner()); |
1345 | 1345 |
1346 // TODO(ES6): Request JS resource from environment... | 1346 // TODO(ES6): Request JS resource from environment... |
1347 | 1347 |
1348 #ifdef DEBUG | 1348 #ifdef DEBUG |
1349 if (FLAG_print_interface_details) PrintF("# Url "); | 1349 if (FLAG_print_interface_details) PrintF("# Url "); |
1350 #endif | 1350 #endif |
1351 | 1351 |
1352 // Create an empty literal as long as the feature isn't finished. | 1352 // Create an empty literal as long as the feature isn't finished. |
1353 USE(symbol); | 1353 USE(symbol); |
1354 Scope* scope = NewScope(scope_, MODULE_SCOPE); | 1354 Scope* scope = NewScope(scope_, MODULE_SCOPE); |
(...skipping 23 matching lines...) Expand all Loading... |
1378 | 1378 |
1379 | 1379 |
1380 Block* Parser::ParseImportDeclaration(bool* ok) { | 1380 Block* Parser::ParseImportDeclaration(bool* ok) { |
1381 // ImportDeclaration: | 1381 // ImportDeclaration: |
1382 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' | 1382 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' |
1383 // | 1383 // |
1384 // TODO(ES6): implement destructuring ImportSpecifiers | 1384 // TODO(ES6): implement destructuring ImportSpecifiers |
1385 | 1385 |
1386 int pos = peek_position(); | 1386 int pos = peek_position(); |
1387 Expect(Token::IMPORT, CHECK_OK); | 1387 Expect(Token::IMPORT, CHECK_OK); |
1388 ZoneStringList names(1, zone()); | 1388 ZoneList<const AstString*> names(1, zone()); |
1389 | 1389 |
1390 Handle<String> name = ParseIdentifierName(CHECK_OK); | 1390 const AstString* name = ParseIdentifierName(CHECK_OK); |
1391 names.Add(name, zone()); | 1391 names.Add(name, zone()); |
1392 while (peek() == Token::COMMA) { | 1392 while (peek() == Token::COMMA) { |
1393 Consume(Token::COMMA); | 1393 Consume(Token::COMMA); |
1394 name = ParseIdentifierName(CHECK_OK); | 1394 name = ParseIdentifierName(CHECK_OK); |
1395 names.Add(name, zone()); | 1395 names.Add(name, zone()); |
1396 } | 1396 } |
1397 | 1397 |
1398 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); | 1398 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
1399 Module* module = ParseModuleSpecifier(CHECK_OK); | 1399 Module* module = ParseModuleSpecifier(CHECK_OK); |
1400 ExpectSemicolon(CHECK_OK); | 1400 ExpectSemicolon(CHECK_OK); |
1401 | 1401 |
1402 // Generate a separate declaration for each identifier. | 1402 // Generate a separate declaration for each identifier. |
1403 // TODO(ES6): once we implement destructuring, make that one declaration. | 1403 // TODO(ES6): once we implement destructuring, make that one declaration. |
1404 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); | 1404 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); |
1405 for (int i = 0; i < names.length(); ++i) { | 1405 for (int i = 0; i < names.length(); ++i) { |
1406 #ifdef DEBUG | 1406 #ifdef DEBUG |
1407 if (FLAG_print_interface_details) | 1407 if (FLAG_print_interface_details) |
1408 PrintF("# Import %s ", names[i]->ToAsciiArray()); | 1408 PrintF("# Import %.*s ", name->length(), name->raw_data()); |
1409 #endif | 1409 #endif |
1410 Interface* interface = Interface::NewUnknown(zone()); | 1410 Interface* interface = Interface::NewUnknown(zone()); |
1411 module->interface()->Add(names[i], interface, zone(), ok); | 1411 module->interface()->Add(names[i], interface, zone(), ok); |
1412 if (!*ok) { | 1412 if (!*ok) { |
1413 #ifdef DEBUG | 1413 #ifdef DEBUG |
1414 if (FLAG_print_interfaces) { | 1414 if (FLAG_print_interfaces) { |
1415 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); | 1415 PrintF("IMPORT TYPE ERROR at '%.*s'\n", name->length(), |
| 1416 name->raw_data()); |
1416 PrintF("module: "); | 1417 PrintF("module: "); |
1417 module->interface()->Print(); | 1418 module->interface()->Print(); |
1418 } | 1419 } |
1419 #endif | 1420 #endif |
1420 ParserTraits::ReportMessage("invalid_module_path", name); | 1421 ParserTraits::ReportMessage("invalid_module_path", name); |
1421 return NULL; | 1422 return NULL; |
1422 } | 1423 } |
1423 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); | 1424 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); |
1424 Declaration* declaration = | 1425 Declaration* declaration = |
1425 factory()->NewImportDeclaration(proxy, module, scope_, pos); | 1426 factory()->NewImportDeclaration(proxy, module, scope_, pos); |
(...skipping 10 matching lines...) Expand all Loading... |
1436 // 'export' VariableDeclaration | 1437 // 'export' VariableDeclaration |
1437 // 'export' FunctionDeclaration | 1438 // 'export' FunctionDeclaration |
1438 // 'export' GeneratorDeclaration | 1439 // 'export' GeneratorDeclaration |
1439 // 'export' ModuleDeclaration | 1440 // 'export' ModuleDeclaration |
1440 // | 1441 // |
1441 // TODO(ES6): implement structuring ExportSpecifiers | 1442 // TODO(ES6): implement structuring ExportSpecifiers |
1442 | 1443 |
1443 Expect(Token::EXPORT, CHECK_OK); | 1444 Expect(Token::EXPORT, CHECK_OK); |
1444 | 1445 |
1445 Statement* result = NULL; | 1446 Statement* result = NULL; |
1446 ZoneStringList names(1, zone()); | 1447 ZoneList<const AstString*> names(1, zone()); |
1447 switch (peek()) { | 1448 switch (peek()) { |
1448 case Token::IDENTIFIER: { | 1449 case Token::IDENTIFIER: { |
1449 int pos = position(); | 1450 int pos = position(); |
1450 Handle<String> name = | 1451 const AstString* name = |
1451 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1452 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
1452 // Handle 'module' as a context-sensitive keyword. | 1453 // Handle 'module' as a context-sensitive keyword. |
1453 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { | 1454 if (name != string_table_->module_string()) { |
1454 names.Add(name, zone()); | 1455 names.Add(name, zone()); |
1455 while (peek() == Token::COMMA) { | 1456 while (peek() == Token::COMMA) { |
1456 Consume(Token::COMMA); | 1457 Consume(Token::COMMA); |
1457 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1458 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
1458 names.Add(name, zone()); | 1459 names.Add(name, zone()); |
1459 } | 1460 } |
1460 ExpectSemicolon(CHECK_OK); | 1461 ExpectSemicolon(CHECK_OK); |
1461 result = factory()->NewEmptyStatement(pos); | 1462 result = factory()->NewEmptyStatement(pos); |
1462 } else { | 1463 } else { |
1463 result = ParseModuleDeclaration(&names, CHECK_OK); | 1464 result = ParseModuleDeclaration(&names, CHECK_OK); |
(...skipping 15 matching lines...) Expand all Loading... |
1479 *ok = false; | 1480 *ok = false; |
1480 ReportUnexpectedToken(scanner()->current_token()); | 1481 ReportUnexpectedToken(scanner()->current_token()); |
1481 return NULL; | 1482 return NULL; |
1482 } | 1483 } |
1483 | 1484 |
1484 // Extract declared names into export declarations and interface. | 1485 // Extract declared names into export declarations and interface. |
1485 Interface* interface = scope_->interface(); | 1486 Interface* interface = scope_->interface(); |
1486 for (int i = 0; i < names.length(); ++i) { | 1487 for (int i = 0; i < names.length(); ++i) { |
1487 #ifdef DEBUG | 1488 #ifdef DEBUG |
1488 if (FLAG_print_interface_details) | 1489 if (FLAG_print_interface_details) |
1489 PrintF("# Export %s ", names[i]->ToAsciiArray()); | 1490 PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data()); |
1490 #endif | 1491 #endif |
1491 Interface* inner = Interface::NewUnknown(zone()); | 1492 Interface* inner = Interface::NewUnknown(zone()); |
1492 interface->Add(names[i], inner, zone(), CHECK_OK); | 1493 interface->Add(names[i], inner, zone(), CHECK_OK); |
1493 if (!*ok) | 1494 if (!*ok) |
1494 return NULL; | 1495 return NULL; |
1495 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); | 1496 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); |
1496 USE(proxy); | 1497 USE(proxy); |
1497 // TODO(rossberg): Rethink whether we actually need to store export | 1498 // TODO(rossberg): Rethink whether we actually need to store export |
1498 // declarations (for compilation?). | 1499 // declarations (for compilation?). |
1499 // ExportDeclaration* declaration = | 1500 // ExportDeclaration* declaration = |
1500 // factory()->NewExportDeclaration(proxy, scope_, position); | 1501 // factory()->NewExportDeclaration(proxy, scope_, position); |
1501 // scope_->AddDeclaration(declaration); | 1502 // scope_->AddDeclaration(declaration); |
1502 } | 1503 } |
1503 | 1504 |
1504 ASSERT(result != NULL); | 1505 ASSERT(result != NULL); |
1505 return result; | 1506 return result; |
1506 } | 1507 } |
1507 | 1508 |
1508 | 1509 |
1509 Statement* Parser::ParseBlockElement(ZoneStringList* labels, | 1510 Statement* Parser::ParseBlockElement(ZoneList<const AstString*>* labels, |
1510 bool* ok) { | 1511 bool* ok) { |
1511 // (Ecma 262 5th Edition, clause 14): | 1512 // (Ecma 262 5th Edition, clause 14): |
1512 // SourceElement: | 1513 // SourceElement: |
1513 // Statement | 1514 // Statement |
1514 // FunctionDeclaration | 1515 // FunctionDeclaration |
1515 // | 1516 // |
1516 // In harmony mode we allow additionally the following productions | 1517 // In harmony mode we allow additionally the following productions |
1517 // BlockElement (aka SourceElement): | 1518 // BlockElement (aka SourceElement): |
1518 // LetDeclaration | 1519 // LetDeclaration |
1519 // ConstDeclaration | 1520 // ConstDeclaration |
1520 // GeneratorDeclaration | 1521 // GeneratorDeclaration |
1521 | 1522 |
1522 switch (peek()) { | 1523 switch (peek()) { |
1523 case Token::FUNCTION: | 1524 case Token::FUNCTION: |
1524 return ParseFunctionDeclaration(NULL, ok); | 1525 return ParseFunctionDeclaration(NULL, ok); |
1525 case Token::LET: | 1526 case Token::LET: |
1526 case Token::CONST: | 1527 case Token::CONST: |
1527 return ParseVariableStatement(kModuleElement, NULL, ok); | 1528 return ParseVariableStatement(kModuleElement, NULL, ok); |
1528 default: | 1529 default: |
1529 return ParseStatement(labels, ok); | 1530 return ParseStatement(labels, ok); |
1530 } | 1531 } |
1531 } | 1532 } |
1532 | 1533 |
1533 | 1534 |
1534 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { | 1535 Statement* Parser::ParseStatement(ZoneList<const AstString*>* labels, |
| 1536 bool* ok) { |
1535 // Statement :: | 1537 // Statement :: |
1536 // Block | 1538 // Block |
1537 // VariableStatement | 1539 // VariableStatement |
1538 // EmptyStatement | 1540 // EmptyStatement |
1539 // ExpressionStatement | 1541 // ExpressionStatement |
1540 // IfStatement | 1542 // IfStatement |
1541 // IterationStatement | 1543 // IterationStatement |
1542 // ContinueStatement | 1544 // ContinueStatement |
1543 // BreakStatement | 1545 // BreakStatement |
1544 // ReturnStatement | 1546 // ReturnStatement |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1634 | 1636 |
1635 case Token::DEBUGGER: | 1637 case Token::DEBUGGER: |
1636 return ParseDebuggerStatement(ok); | 1638 return ParseDebuggerStatement(ok); |
1637 | 1639 |
1638 default: | 1640 default: |
1639 return ParseExpressionOrLabelledStatement(labels, ok); | 1641 return ParseExpressionOrLabelledStatement(labels, ok); |
1640 } | 1642 } |
1641 } | 1643 } |
1642 | 1644 |
1643 | 1645 |
1644 VariableProxy* Parser::NewUnresolved( | 1646 VariableProxy* Parser::NewUnresolved(const AstString* name, VariableMode mode, |
1645 Handle<String> name, VariableMode mode, Interface* interface) { | 1647 Interface* interface) { |
1646 // If we are inside a function, a declaration of a var/const variable is a | 1648 // If we are inside a function, a declaration of a var/const variable is a |
1647 // truly local variable, and the scope of the variable is always the function | 1649 // truly local variable, and the scope of the variable is always the function |
1648 // scope. | 1650 // scope. |
1649 // Let/const variables in harmony mode are always added to the immediately | 1651 // Let/const variables in harmony mode are always added to the immediately |
1650 // enclosing scope. | 1652 // enclosing scope. |
1651 return DeclarationScope(mode)->NewUnresolved( | 1653 return DeclarationScope(mode)->NewUnresolved( |
1652 factory(), name, interface, position()); | 1654 factory(), name, interface, position()); |
1653 } | 1655 } |
1654 | 1656 |
1655 | 1657 |
1656 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { | 1658 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { |
1657 VariableProxy* proxy = declaration->proxy(); | 1659 VariableProxy* proxy = declaration->proxy(); |
1658 Handle<String> name = proxy->name(); | 1660 ASSERT(proxy->raw_name() != NULL); |
| 1661 const AstString* name = proxy->raw_name(); |
1659 VariableMode mode = declaration->mode(); | 1662 VariableMode mode = declaration->mode(); |
1660 Scope* declaration_scope = DeclarationScope(mode); | 1663 Scope* declaration_scope = DeclarationScope(mode); |
1661 Variable* var = NULL; | 1664 Variable* var = NULL; |
1662 | 1665 |
1663 // If a suitable scope exists, then we can statically declare this | 1666 // If a suitable scope exists, then we can statically declare this |
1664 // variable and also set its mode. In any case, a Declaration node | 1667 // variable and also set its mode. In any case, a Declaration node |
1665 // will be added to the scope so that the declaration can be added | 1668 // will be added to the scope so that the declaration can be added |
1666 // to the corresponding activation frame at runtime if necessary. | 1669 // to the corresponding activation frame at runtime if necessary. |
1667 // For instance declarations inside an eval scope need to be added | 1670 // For instance declarations inside an eval scope need to be added |
1668 // to the calling function context. | 1671 // to the calling function context. |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1776 // with a context slot index and a context chain length for this | 1779 // with a context slot index and a context chain length for this |
1777 // initialization code. Thus, inside the 'with' statement, we need | 1780 // initialization code. Thus, inside the 'with' statement, we need |
1778 // both access to the static and the dynamic context chain; the | 1781 // both access to the static and the dynamic context chain; the |
1779 // runtime needs to provide both. | 1782 // runtime needs to provide both. |
1780 if (resolve && var != NULL) { | 1783 if (resolve && var != NULL) { |
1781 proxy->BindTo(var); | 1784 proxy->BindTo(var); |
1782 | 1785 |
1783 if (FLAG_harmony_modules) { | 1786 if (FLAG_harmony_modules) { |
1784 bool ok; | 1787 bool ok; |
1785 #ifdef DEBUG | 1788 #ifdef DEBUG |
1786 if (FLAG_print_interface_details) | 1789 if (FLAG_print_interface_details) { |
1787 PrintF("# Declare %s\n", var->name()->ToAsciiArray()); | 1790 PrintF("# Declare %.*s ", var->raw_name()->length(), |
| 1791 var->raw_name()->raw_data()); |
| 1792 } |
1788 #endif | 1793 #endif |
1789 proxy->interface()->Unify(var->interface(), zone(), &ok); | 1794 proxy->interface()->Unify(var->interface(), zone(), &ok); |
1790 if (!ok) { | 1795 if (!ok) { |
1791 #ifdef DEBUG | 1796 #ifdef DEBUG |
1792 if (FLAG_print_interfaces) { | 1797 if (FLAG_print_interfaces) { |
1793 PrintF("DECLARE TYPE ERROR\n"); | 1798 PrintF("DECLARE TYPE ERROR\n"); |
1794 PrintF("proxy: "); | 1799 PrintF("proxy: "); |
1795 proxy->interface()->Print(); | 1800 proxy->interface()->Print(); |
1796 PrintF("var: "); | 1801 PrintF("var: "); |
1797 var->interface()->Print(); | 1802 var->interface()->Print(); |
1798 } | 1803 } |
1799 #endif | 1804 #endif |
1800 ParserTraits::ReportMessage("module_type_error", name); | 1805 ParserTraits::ReportMessage("module_type_error", name); |
1801 } | 1806 } |
1802 } | 1807 } |
1803 } | 1808 } |
1804 } | 1809 } |
1805 | 1810 |
1806 | 1811 |
1807 // Language extension which is only enabled for source files loaded | 1812 // Language extension which is only enabled for source files loaded |
1808 // through the API's extension mechanism. A native function | 1813 // through the API's extension mechanism. A native function |
1809 // declaration is resolved by looking up the function through a | 1814 // declaration is resolved by looking up the function through a |
1810 // callback provided by the extension. | 1815 // callback provided by the extension. |
1811 Statement* Parser::ParseNativeDeclaration(bool* ok) { | 1816 Statement* Parser::ParseNativeDeclaration(bool* ok) { |
1812 int pos = peek_position(); | 1817 int pos = peek_position(); |
1813 Expect(Token::FUNCTION, CHECK_OK); | 1818 Expect(Token::FUNCTION, CHECK_OK); |
1814 // Allow "eval" or "arguments" for backward compatibility. | 1819 // Allow "eval" or "arguments" for backward compatibility. |
1815 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1820 const AstString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
1816 Expect(Token::LPAREN, CHECK_OK); | 1821 Expect(Token::LPAREN, CHECK_OK); |
1817 bool done = (peek() == Token::RPAREN); | 1822 bool done = (peek() == Token::RPAREN); |
1818 while (!done) { | 1823 while (!done) { |
1819 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1824 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
1820 done = (peek() == Token::RPAREN); | 1825 done = (peek() == Token::RPAREN); |
1821 if (!done) { | 1826 if (!done) { |
1822 Expect(Token::COMMA, CHECK_OK); | 1827 Expect(Token::COMMA, CHECK_OK); |
1823 } | 1828 } |
1824 } | 1829 } |
1825 Expect(Token::RPAREN, CHECK_OK); | 1830 Expect(Token::RPAREN, CHECK_OK); |
(...skipping 14 matching lines...) Expand all Loading... |
1840 Declare(declaration, true, CHECK_OK); | 1845 Declare(declaration, true, CHECK_OK); |
1841 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( | 1846 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( |
1842 name, extension_, RelocInfo::kNoPosition); | 1847 name, extension_, RelocInfo::kNoPosition); |
1843 return factory()->NewExpressionStatement( | 1848 return factory()->NewExpressionStatement( |
1844 factory()->NewAssignment( | 1849 factory()->NewAssignment( |
1845 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), | 1850 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), |
1846 pos); | 1851 pos); |
1847 } | 1852 } |
1848 | 1853 |
1849 | 1854 |
1850 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { | 1855 Statement* Parser::ParseFunctionDeclaration(ZoneList<const AstString*>* names, |
| 1856 bool* ok) { |
1851 // FunctionDeclaration :: | 1857 // FunctionDeclaration :: |
1852 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 1858 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
1853 // GeneratorDeclaration :: | 1859 // GeneratorDeclaration :: |
1854 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 1860 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
1855 // '{' FunctionBody '}' | 1861 // '{' FunctionBody '}' |
1856 Expect(Token::FUNCTION, CHECK_OK); | 1862 Expect(Token::FUNCTION, CHECK_OK); |
1857 int pos = position(); | 1863 int pos = position(); |
1858 bool is_generator = allow_generators() && Check(Token::MUL); | 1864 bool is_generator = allow_generators() && Check(Token::MUL); |
1859 bool is_strict_reserved = false; | 1865 bool is_strict_reserved = false; |
1860 Handle<String> name = ParseIdentifierOrStrictReservedWord( | 1866 const AstString* name = ParseIdentifierOrStrictReservedWord( |
1861 &is_strict_reserved, CHECK_OK); | 1867 &is_strict_reserved, CHECK_OK); |
1862 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1868 FunctionLiteral* fun = ParseFunctionLiteral(name, |
1863 scanner()->location(), | 1869 scanner()->location(), |
1864 is_strict_reserved, | 1870 is_strict_reserved, |
1865 is_generator, | 1871 is_generator, |
1866 pos, | 1872 pos, |
1867 FunctionLiteral::DECLARATION, | 1873 FunctionLiteral::DECLARATION, |
1868 CHECK_OK); | 1874 CHECK_OK); |
1869 // Even if we're not at the top-level of the global or a function | 1875 // Even if we're not at the top-level of the global or a function |
1870 // scope, we treat it as such and introduce the function with its | 1876 // scope, we treat it as such and introduce the function with its |
1871 // initial value upon entering the corresponding scope. | 1877 // initial value upon entering the corresponding scope. |
1872 // In extended mode, a function behaves as a lexical binding, except in the | 1878 // In extended mode, a function behaves as a lexical binding, except in the |
1873 // global scope. | 1879 // global scope. |
1874 VariableMode mode = | 1880 VariableMode mode = |
1875 allow_harmony_scoping() && | 1881 allow_harmony_scoping() && |
1876 strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR; | 1882 strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR; |
1877 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); | 1883 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); |
1878 Declaration* declaration = | 1884 Declaration* declaration = |
1879 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); | 1885 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); |
1880 Declare(declaration, true, CHECK_OK); | 1886 Declare(declaration, true, CHECK_OK); |
1881 if (names) names->Add(name, zone()); | 1887 if (names) names->Add(name, zone()); |
1882 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 1888 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
1883 } | 1889 } |
1884 | 1890 |
1885 | 1891 |
1886 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1892 Block* Parser::ParseBlock(ZoneList<const AstString*>* labels, bool* ok) { |
1887 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 1893 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
1888 return ParseScopedBlock(labels, ok); | 1894 return ParseScopedBlock(labels, ok); |
1889 } | 1895 } |
1890 | 1896 |
1891 // Block :: | 1897 // Block :: |
1892 // '{' Statement* '}' | 1898 // '{' Statement* '}' |
1893 | 1899 |
1894 // Note that a Block does not introduce a new execution scope! | 1900 // Note that a Block does not introduce a new execution scope! |
1895 // (ECMA-262, 3rd, 12.2) | 1901 // (ECMA-262, 3rd, 12.2) |
1896 // | 1902 // |
1897 // Construct block expecting 16 statements. | 1903 // Construct block expecting 16 statements. |
1898 Block* result = | 1904 Block* result = |
1899 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1905 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
1900 Target target(&this->target_stack_, result); | 1906 Target target(&this->target_stack_, result); |
1901 Expect(Token::LBRACE, CHECK_OK); | 1907 Expect(Token::LBRACE, CHECK_OK); |
1902 while (peek() != Token::RBRACE) { | 1908 while (peek() != Token::RBRACE) { |
1903 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1909 Statement* stat = ParseStatement(NULL, CHECK_OK); |
1904 if (stat && !stat->IsEmpty()) { | 1910 if (stat && !stat->IsEmpty()) { |
1905 result->AddStatement(stat, zone()); | 1911 result->AddStatement(stat, zone()); |
1906 } | 1912 } |
1907 } | 1913 } |
1908 Expect(Token::RBRACE, CHECK_OK); | 1914 Expect(Token::RBRACE, CHECK_OK); |
1909 return result; | 1915 return result; |
1910 } | 1916 } |
1911 | 1917 |
1912 | 1918 |
1913 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { | 1919 Block* Parser::ParseScopedBlock(ZoneList<const AstString*>* labels, bool* ok) { |
1914 // The harmony mode uses block elements instead of statements. | 1920 // The harmony mode uses block elements instead of statements. |
1915 // | 1921 // |
1916 // Block :: | 1922 // Block :: |
1917 // '{' BlockElement* '}' | 1923 // '{' BlockElement* '}' |
1918 | 1924 |
1919 // Construct block expecting 16 statements. | 1925 // Construct block expecting 16 statements. |
1920 Block* body = | 1926 Block* body = |
1921 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1927 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
1922 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); | 1928 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); |
1923 | 1929 |
(...skipping 14 matching lines...) Expand all Loading... |
1938 } | 1944 } |
1939 Expect(Token::RBRACE, CHECK_OK); | 1945 Expect(Token::RBRACE, CHECK_OK); |
1940 block_scope->set_end_position(scanner()->location().end_pos); | 1946 block_scope->set_end_position(scanner()->location().end_pos); |
1941 block_scope = block_scope->FinalizeBlockScope(); | 1947 block_scope = block_scope->FinalizeBlockScope(); |
1942 body->set_scope(block_scope); | 1948 body->set_scope(block_scope); |
1943 return body; | 1949 return body; |
1944 } | 1950 } |
1945 | 1951 |
1946 | 1952 |
1947 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, | 1953 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
1948 ZoneStringList* names, | 1954 ZoneList<const AstString*>* names, |
1949 bool* ok) { | 1955 bool* ok) { |
1950 // VariableStatement :: | 1956 // VariableStatement :: |
1951 // VariableDeclarations ';' | 1957 // VariableDeclarations ';' |
1952 | 1958 |
1953 Handle<String> ignore; | 1959 const AstString* ignore; |
1954 Block* result = | 1960 Block* result = |
1955 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); | 1961 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); |
1956 ExpectSemicolon(CHECK_OK); | 1962 ExpectSemicolon(CHECK_OK); |
1957 return result; | 1963 return result; |
1958 } | 1964 } |
1959 | 1965 |
1960 | 1966 |
1961 // If the variable declaration declares exactly one non-const | 1967 // If the variable declaration declares exactly one non-const |
1962 // variable, then *out is set to that variable. In all other cases, | 1968 // variable, then *out is set to that variable. In all other cases, |
1963 // *out is untouched; in particular, it is the caller's responsibility | 1969 // *out is untouched; in particular, it is the caller's responsibility |
1964 // to initialize it properly. This mechanism is used for the parsing | 1970 // to initialize it properly. This mechanism is used for the parsing |
1965 // of 'for-in' loops. | 1971 // of 'for-in' loops. |
1966 Block* Parser::ParseVariableDeclarations( | 1972 Block* Parser::ParseVariableDeclarations( |
1967 VariableDeclarationContext var_context, | 1973 VariableDeclarationContext var_context, |
1968 VariableDeclarationProperties* decl_props, | 1974 VariableDeclarationProperties* decl_props, |
1969 ZoneStringList* names, | 1975 ZoneList<const AstString*>* names, |
1970 Handle<String>* out, | 1976 const AstString** out, |
1971 bool* ok) { | 1977 bool* ok) { |
1972 // VariableDeclarations :: | 1978 // VariableDeclarations :: |
1973 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] | 1979 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] |
1974 // | 1980 // |
1975 // The ES6 Draft Rev3 specifies the following grammar for const declarations | 1981 // The ES6 Draft Rev3 specifies the following grammar for const declarations |
1976 // | 1982 // |
1977 // ConstDeclaration :: | 1983 // ConstDeclaration :: |
1978 // const ConstBinding (',' ConstBinding)* ';' | 1984 // const ConstBinding (',' ConstBinding)* ';' |
1979 // ConstBinding :: | 1985 // ConstBinding :: |
1980 // Identifier '=' AssignmentExpression | 1986 // Identifier '=' AssignmentExpression |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2068 // | 2074 // |
2069 // We mark the block as initializer block because we don't want the | 2075 // We mark the block as initializer block because we don't want the |
2070 // rewriter to add a '.result' assignment to such a block (to get compliant | 2076 // rewriter to add a '.result' assignment to such a block (to get compliant |
2071 // behavior for code such as print(eval('var x = 7')), and for cosmetic | 2077 // behavior for code such as print(eval('var x = 7')), and for cosmetic |
2072 // reasons when pretty-printing. Also, unless an assignment (initialization) | 2078 // reasons when pretty-printing. Also, unless an assignment (initialization) |
2073 // is inside an initializer block, it is ignored. | 2079 // is inside an initializer block, it is ignored. |
2074 // | 2080 // |
2075 // Create new block with one expected declaration. | 2081 // Create new block with one expected declaration. |
2076 Block* block = factory()->NewBlock(NULL, 1, true, pos); | 2082 Block* block = factory()->NewBlock(NULL, 1, true, pos); |
2077 int nvars = 0; // the number of variables declared | 2083 int nvars = 0; // the number of variables declared |
2078 Handle<String> name; | 2084 const AstString* name = NULL; |
2079 do { | 2085 do { |
2080 if (fni_ != NULL) fni_->Enter(); | 2086 if (fni_ != NULL) fni_->Enter(); |
2081 | 2087 |
2082 // Parse variable name. | 2088 // Parse variable name. |
2083 if (nvars > 0) Consume(Token::COMMA); | 2089 if (nvars > 0) Consume(Token::COMMA); |
2084 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2090 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
2085 if (fni_ != NULL) fni_->PushVariableName(name); | 2091 if (fni_ != NULL) fni_->PushVariableName(name); |
2086 | 2092 |
2087 // Declare variable. | 2093 // Declare variable. |
2088 // Note that we *always* must treat the initial value via a separate init | 2094 // Note that we *always* must treat the initial value via a separate init |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2199 | 2205 |
2200 if (is_const) { | 2206 if (is_const) { |
2201 arguments->Add(value, zone()); | 2207 arguments->Add(value, zone()); |
2202 value = NULL; // zap the value to avoid the unnecessary assignment | 2208 value = NULL; // zap the value to avoid the unnecessary assignment |
2203 | 2209 |
2204 // Construct the call to Runtime_InitializeConstGlobal | 2210 // Construct the call to Runtime_InitializeConstGlobal |
2205 // and add it to the initialization statement block. | 2211 // and add it to the initialization statement block. |
2206 // Note that the function does different things depending on | 2212 // Note that the function does different things depending on |
2207 // the number of arguments (1 or 2). | 2213 // the number of arguments (1 or 2). |
2208 initialize = factory()->NewCallRuntime( | 2214 initialize = factory()->NewCallRuntime( |
2209 isolate()->factory()->InitializeConstGlobal_string(), | 2215 string_table_->initialize_const_global_string(), |
2210 Runtime::FunctionForId(Runtime::kHiddenInitializeConstGlobal), | 2216 Runtime::FunctionForId(Runtime::kHiddenInitializeConstGlobal), |
2211 arguments, pos); | 2217 arguments, pos); |
2212 } else { | 2218 } else { |
2213 // Add strict mode. | 2219 // Add strict mode. |
2214 // We may want to pass singleton to avoid Literal allocations. | 2220 // We may want to pass singleton to avoid Literal allocations. |
2215 StrictMode strict_mode = initialization_scope->strict_mode(); | 2221 StrictMode strict_mode = initialization_scope->strict_mode(); |
2216 arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone()); | 2222 arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone()); |
2217 | 2223 |
2218 // Be careful not to assign a value to the global variable if | 2224 // Be careful not to assign a value to the global variable if |
2219 // we're in a with. The initialization value should not | 2225 // we're in a with. The initialization value should not |
2220 // necessarily be stored in the global object in that case, | 2226 // necessarily be stored in the global object in that case, |
2221 // which is why we need to generate a separate assignment node. | 2227 // which is why we need to generate a separate assignment node. |
2222 if (value != NULL && !inside_with()) { | 2228 if (value != NULL && !inside_with()) { |
2223 arguments->Add(value, zone()); | 2229 arguments->Add(value, zone()); |
2224 value = NULL; // zap the value to avoid the unnecessary assignment | 2230 value = NULL; // zap the value to avoid the unnecessary assignment |
2225 } | 2231 } |
2226 | 2232 |
2227 // Construct the call to Runtime_InitializeVarGlobal | 2233 // Construct the call to Runtime_InitializeVarGlobal |
2228 // and add it to the initialization statement block. | 2234 // and add it to the initialization statement block. |
2229 // Note that the function does different things depending on | 2235 // Note that the function does different things depending on |
2230 // the number of arguments (2 or 3). | 2236 // the number of arguments (2 or 3). |
2231 initialize = factory()->NewCallRuntime( | 2237 initialize = factory()->NewCallRuntime( |
2232 isolate()->factory()->InitializeVarGlobal_string(), | 2238 string_table_->initialize_var_global_string(), |
2233 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), | 2239 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), |
2234 arguments, pos); | 2240 arguments, pos); |
2235 } | 2241 } |
2236 | 2242 |
2237 block->AddStatement( | 2243 block->AddStatement( |
2238 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), | 2244 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), |
2239 zone()); | 2245 zone()); |
2240 } else if (needs_init) { | 2246 } else if (needs_init) { |
2241 // Constant initializations always assign to the declared constant which | 2247 // Constant initializations always assign to the declared constant which |
2242 // is always at the function scope level. This is only relevant for | 2248 // is always at the function scope level. This is only relevant for |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2278 // If there was a single non-const declaration, return it in the output | 2284 // If there was a single non-const declaration, return it in the output |
2279 // parameter for possible use by for/in. | 2285 // parameter for possible use by for/in. |
2280 if (nvars == 1 && !is_const) { | 2286 if (nvars == 1 && !is_const) { |
2281 *out = name; | 2287 *out = name; |
2282 } | 2288 } |
2283 | 2289 |
2284 return block; | 2290 return block; |
2285 } | 2291 } |
2286 | 2292 |
2287 | 2293 |
2288 static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) { | 2294 static bool ContainsLabel(ZoneList<const AstString*>* labels, |
2289 ASSERT(!label.is_null()); | 2295 const AstString* label) { |
| 2296 ASSERT(label != NULL); |
2290 if (labels != NULL) | 2297 if (labels != NULL) |
2291 for (int i = labels->length(); i-- > 0; ) | 2298 for (int i = labels->length(); i-- > 0; ) |
2292 if (labels->at(i).is_identical_to(label)) | 2299 if (labels->at(i) == label) |
2293 return true; | 2300 return true; |
2294 | 2301 |
2295 return false; | 2302 return false; |
2296 } | 2303 } |
2297 | 2304 |
2298 | 2305 |
2299 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, | 2306 Statement* Parser::ParseExpressionOrLabelledStatement( |
2300 bool* ok) { | 2307 ZoneList<const AstString*>* labels, bool* ok) { |
2301 // ExpressionStatement | LabelledStatement :: | 2308 // ExpressionStatement | LabelledStatement :: |
2302 // Expression ';' | 2309 // Expression ';' |
2303 // Identifier ':' Statement | 2310 // Identifier ':' Statement |
2304 int pos = peek_position(); | 2311 int pos = peek_position(); |
2305 bool starts_with_idenfifier = peek_any_identifier(); | 2312 bool starts_with_idenfifier = peek_any_identifier(); |
2306 Expression* expr = ParseExpression(true, CHECK_OK); | 2313 Expression* expr = ParseExpression(true, CHECK_OK); |
2307 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && | 2314 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && |
2308 expr->AsVariableProxy() != NULL && | 2315 expr->AsVariableProxy() != NULL && |
2309 !expr->AsVariableProxy()->is_this()) { | 2316 !expr->AsVariableProxy()->is_this()) { |
2310 // Expression is a single identifier, and not, e.g., a parenthesized | 2317 // Expression is a single identifier, and not, e.g., a parenthesized |
2311 // identifier. | 2318 // identifier. |
2312 VariableProxy* var = expr->AsVariableProxy(); | 2319 VariableProxy* var = expr->AsVariableProxy(); |
2313 Handle<String> label = var->name(); | 2320 const AstString* label = var->raw_name(); |
2314 // TODO(1240780): We don't check for redeclaration of labels | 2321 // TODO(1240780): We don't check for redeclaration of labels |
2315 // during preparsing since keeping track of the set of active | 2322 // during preparsing since keeping track of the set of active |
2316 // labels requires nontrivial changes to the way scopes are | 2323 // labels requires nontrivial changes to the way scopes are |
2317 // structured. However, these are probably changes we want to | 2324 // structured. However, these are probably changes we want to |
2318 // make later anyway so we should go back and fix this then. | 2325 // make later anyway so we should go back and fix this then. |
2319 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { | 2326 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { |
2320 ParserTraits::ReportMessage("label_redeclaration", label); | 2327 ParserTraits::ReportMessage("label_redeclaration", label); |
2321 *ok = false; | 2328 *ok = false; |
2322 return NULL; | 2329 return NULL; |
2323 } | 2330 } |
2324 if (labels == NULL) { | 2331 if (labels == NULL) { |
2325 labels = new(zone()) ZoneStringList(4, zone()); | 2332 labels = new(zone()) ZoneList<const AstString*>(4, zone()); |
2326 } | 2333 } |
2327 labels->Add(label, zone()); | 2334 labels->Add(label, zone()); |
2328 // Remove the "ghost" variable that turned out to be a label | 2335 // Remove the "ghost" variable that turned out to be a label |
2329 // from the top scope. This way, we don't try to resolve it | 2336 // from the top scope. This way, we don't try to resolve it |
2330 // during the scope processing. | 2337 // during the scope processing. |
2331 scope_->RemoveUnresolved(var); | 2338 scope_->RemoveUnresolved(var); |
2332 Expect(Token::COLON, CHECK_OK); | 2339 Expect(Token::COLON, CHECK_OK); |
2333 return ParseStatement(labels, ok); | 2340 return ParseStatement(labels, ok); |
2334 } | 2341 } |
2335 | 2342 |
2336 // If we have an extension, we allow a native function declaration. | 2343 // If we have an extension, we allow a native function declaration. |
2337 // A native function declaration starts with "native function" with | 2344 // A native function declaration starts with "native function" with |
2338 // no line-terminator between the two words. | 2345 // no line-terminator between the two words. |
2339 if (extension_ != NULL && | 2346 if (extension_ != NULL && |
2340 peek() == Token::FUNCTION && | 2347 peek() == Token::FUNCTION && |
2341 !scanner()->HasAnyLineTerminatorBeforeNext() && | 2348 !scanner()->HasAnyLineTerminatorBeforeNext() && |
2342 expr != NULL && | 2349 expr != NULL && |
2343 expr->AsVariableProxy() != NULL && | 2350 expr->AsVariableProxy() != NULL && |
2344 String::Equals(isolate()->factory()->native_string(), | 2351 expr->AsVariableProxy()->raw_name() == string_table_->native_string() && |
2345 expr->AsVariableProxy()->name()) && | |
2346 !scanner()->literal_contains_escapes()) { | 2352 !scanner()->literal_contains_escapes()) { |
2347 return ParseNativeDeclaration(ok); | 2353 return ParseNativeDeclaration(ok); |
2348 } | 2354 } |
2349 | 2355 |
2350 // Parsed expression statement, or the context-sensitive 'module' keyword. | 2356 // Parsed expression statement, or the context-sensitive 'module' keyword. |
2351 // Only expect semicolon in the former case. | 2357 // Only expect semicolon in the former case. |
2352 if (!FLAG_harmony_modules || | 2358 if (!FLAG_harmony_modules || |
2353 peek() != Token::IDENTIFIER || | 2359 peek() != Token::IDENTIFIER || |
2354 scanner()->HasAnyLineTerminatorBeforeNext() || | 2360 scanner()->HasAnyLineTerminatorBeforeNext() || |
2355 expr->AsVariableProxy() == NULL || | 2361 expr->AsVariableProxy() == NULL || |
2356 !String::Equals(isolate()->factory()->module_string(), | 2362 expr->AsVariableProxy()->raw_name() != string_table_->module_string() || |
2357 expr->AsVariableProxy()->name()) || | |
2358 scanner()->literal_contains_escapes()) { | 2363 scanner()->literal_contains_escapes()) { |
2359 ExpectSemicolon(CHECK_OK); | 2364 ExpectSemicolon(CHECK_OK); |
2360 } | 2365 } |
2361 return factory()->NewExpressionStatement(expr, pos); | 2366 return factory()->NewExpressionStatement(expr, pos); |
2362 } | 2367 } |
2363 | 2368 |
2364 | 2369 |
2365 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { | 2370 IfStatement* Parser::ParseIfStatement(ZoneList<const AstString*>* labels, |
| 2371 bool* ok) { |
2366 // IfStatement :: | 2372 // IfStatement :: |
2367 // 'if' '(' Expression ')' Statement ('else' Statement)? | 2373 // 'if' '(' Expression ')' Statement ('else' Statement)? |
2368 | 2374 |
2369 int pos = peek_position(); | 2375 int pos = peek_position(); |
2370 Expect(Token::IF, CHECK_OK); | 2376 Expect(Token::IF, CHECK_OK); |
2371 Expect(Token::LPAREN, CHECK_OK); | 2377 Expect(Token::LPAREN, CHECK_OK); |
2372 Expression* condition = ParseExpression(true, CHECK_OK); | 2378 Expression* condition = ParseExpression(true, CHECK_OK); |
2373 Expect(Token::RPAREN, CHECK_OK); | 2379 Expect(Token::RPAREN, CHECK_OK); |
2374 Statement* then_statement = ParseStatement(labels, CHECK_OK); | 2380 Statement* then_statement = ParseStatement(labels, CHECK_OK); |
2375 Statement* else_statement = NULL; | 2381 Statement* else_statement = NULL; |
2376 if (peek() == Token::ELSE) { | 2382 if (peek() == Token::ELSE) { |
2377 Next(); | 2383 Next(); |
2378 else_statement = ParseStatement(labels, CHECK_OK); | 2384 else_statement = ParseStatement(labels, CHECK_OK); |
2379 } else { | 2385 } else { |
2380 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 2386 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
2381 } | 2387 } |
2382 return factory()->NewIfStatement( | 2388 return factory()->NewIfStatement( |
2383 condition, then_statement, else_statement, pos); | 2389 condition, then_statement, else_statement, pos); |
2384 } | 2390 } |
2385 | 2391 |
2386 | 2392 |
2387 Statement* Parser::ParseContinueStatement(bool* ok) { | 2393 Statement* Parser::ParseContinueStatement(bool* ok) { |
2388 // ContinueStatement :: | 2394 // ContinueStatement :: |
2389 // 'continue' Identifier? ';' | 2395 // 'continue' Identifier? ';' |
2390 | 2396 |
2391 int pos = peek_position(); | 2397 int pos = peek_position(); |
2392 Expect(Token::CONTINUE, CHECK_OK); | 2398 Expect(Token::CONTINUE, CHECK_OK); |
2393 Handle<String> label = Handle<String>::null(); | 2399 const AstString* label = NULL; |
2394 Token::Value tok = peek(); | 2400 Token::Value tok = peek(); |
2395 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2401 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
2396 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2402 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
2397 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 2403 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
2398 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 2404 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
2399 } | 2405 } |
2400 IterationStatement* target = NULL; | 2406 IterationStatement* target = LookupContinueTarget(label, CHECK_OK); |
2401 target = LookupContinueTarget(label, CHECK_OK); | |
2402 if (target == NULL) { | 2407 if (target == NULL) { |
2403 // Illegal continue statement. | 2408 // Illegal continue statement. |
2404 const char* message = "illegal_continue"; | 2409 const char* message = "illegal_continue"; |
2405 if (!label.is_null()) { | 2410 if (label != NULL) { |
2406 message = "unknown_label"; | 2411 message = "unknown_label"; |
2407 } | 2412 } |
2408 ParserTraits::ReportMessageAt(scanner()->location(), message, label); | 2413 ParserTraits::ReportMessageAt(scanner()->location(), message, label); |
2409 *ok = false; | 2414 *ok = false; |
2410 return NULL; | 2415 return NULL; |
2411 } | 2416 } |
2412 ExpectSemicolon(CHECK_OK); | 2417 ExpectSemicolon(CHECK_OK); |
2413 return factory()->NewContinueStatement(target, pos); | 2418 return factory()->NewContinueStatement(target, pos); |
2414 } | 2419 } |
2415 | 2420 |
2416 | 2421 |
2417 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { | 2422 Statement* Parser::ParseBreakStatement(ZoneList<const AstString*>* labels, |
| 2423 bool* ok) { |
2418 // BreakStatement :: | 2424 // BreakStatement :: |
2419 // 'break' Identifier? ';' | 2425 // 'break' Identifier? ';' |
2420 | 2426 |
2421 int pos = peek_position(); | 2427 int pos = peek_position(); |
2422 Expect(Token::BREAK, CHECK_OK); | 2428 Expect(Token::BREAK, CHECK_OK); |
2423 Handle<String> label; | 2429 const AstString* label = NULL; |
2424 Token::Value tok = peek(); | 2430 Token::Value tok = peek(); |
2425 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2431 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
2426 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2432 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
2427 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 2433 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
2428 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 2434 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
2429 } | 2435 } |
2430 // Parse labeled break statements that target themselves into | 2436 // Parse labeled break statements that target themselves into |
2431 // empty statements, e.g. 'l1: l2: l3: break l2;' | 2437 // empty statements, e.g. 'l1: l2: l3: break l2;' |
2432 if (!label.is_null() && ContainsLabel(labels, label)) { | 2438 if (label != NULL && ContainsLabel(labels, label)) { |
2433 ExpectSemicolon(CHECK_OK); | 2439 ExpectSemicolon(CHECK_OK); |
2434 return factory()->NewEmptyStatement(pos); | 2440 return factory()->NewEmptyStatement(pos); |
2435 } | 2441 } |
2436 BreakableStatement* target = NULL; | 2442 BreakableStatement* target = NULL; |
2437 target = LookupBreakTarget(label, CHECK_OK); | 2443 target = LookupBreakTarget(label, CHECK_OK); |
2438 if (target == NULL) { | 2444 if (target == NULL) { |
2439 // Illegal break statement. | 2445 // Illegal break statement. |
2440 const char* message = "illegal_break"; | 2446 const char* message = "illegal_break"; |
2441 if (!label.is_null()) { | 2447 if (label != NULL) { |
2442 message = "unknown_label"; | 2448 message = "unknown_label"; |
2443 } | 2449 } |
2444 ParserTraits::ReportMessageAt(scanner()->location(), message, label); | 2450 ParserTraits::ReportMessageAt(scanner()->location(), message, label); |
2445 *ok = false; | 2451 *ok = false; |
2446 return NULL; | 2452 return NULL; |
2447 } | 2453 } |
2448 ExpectSemicolon(CHECK_OK); | 2454 ExpectSemicolon(CHECK_OK); |
2449 return factory()->NewBreakStatement(target, pos); | 2455 return factory()->NewBreakStatement(target, pos); |
2450 } | 2456 } |
2451 | 2457 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2485 Scope* decl_scope = scope_->DeclarationScope(); | 2491 Scope* decl_scope = scope_->DeclarationScope(); |
2486 if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) { | 2492 if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) { |
2487 ReportMessageAt(loc, "illegal_return"); | 2493 ReportMessageAt(loc, "illegal_return"); |
2488 *ok = false; | 2494 *ok = false; |
2489 return NULL; | 2495 return NULL; |
2490 } | 2496 } |
2491 return result; | 2497 return result; |
2492 } | 2498 } |
2493 | 2499 |
2494 | 2500 |
2495 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 2501 Statement* Parser::ParseWithStatement(ZoneList<const AstString*>* labels, |
| 2502 bool* ok) { |
2496 // WithStatement :: | 2503 // WithStatement :: |
2497 // 'with' '(' Expression ')' Statement | 2504 // 'with' '(' Expression ')' Statement |
2498 | 2505 |
2499 Expect(Token::WITH, CHECK_OK); | 2506 Expect(Token::WITH, CHECK_OK); |
2500 int pos = position(); | 2507 int pos = position(); |
2501 | 2508 |
2502 if (strict_mode() == STRICT) { | 2509 if (strict_mode() == STRICT) { |
2503 ReportMessage("strict_mode_with"); | 2510 ReportMessage("strict_mode_with"); |
2504 *ok = false; | 2511 *ok = false; |
2505 return NULL; | 2512 return NULL; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2547 peek() != Token::DEFAULT && | 2554 peek() != Token::DEFAULT && |
2548 peek() != Token::RBRACE) { | 2555 peek() != Token::RBRACE) { |
2549 Statement* stat = ParseStatement(NULL, CHECK_OK); | 2556 Statement* stat = ParseStatement(NULL, CHECK_OK); |
2550 statements->Add(stat, zone()); | 2557 statements->Add(stat, zone()); |
2551 } | 2558 } |
2552 | 2559 |
2553 return factory()->NewCaseClause(label, statements, pos); | 2560 return factory()->NewCaseClause(label, statements, pos); |
2554 } | 2561 } |
2555 | 2562 |
2556 | 2563 |
2557 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, | 2564 SwitchStatement* Parser::ParseSwitchStatement( |
2558 bool* ok) { | 2565 ZoneList<const AstString*>* labels, bool* ok) { |
2559 // SwitchStatement :: | 2566 // SwitchStatement :: |
2560 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 2567 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
2561 | 2568 |
2562 SwitchStatement* statement = | 2569 SwitchStatement* statement = |
2563 factory()->NewSwitchStatement(labels, peek_position()); | 2570 factory()->NewSwitchStatement(labels, peek_position()); |
2564 Target target(&this->target_stack_, statement); | 2571 Target target(&this->target_stack_, statement); |
2565 | 2572 |
2566 Expect(Token::SWITCH, CHECK_OK); | 2573 Expect(Token::SWITCH, CHECK_OK); |
2567 Expect(Token::LPAREN, CHECK_OK); | 2574 Expect(Token::LPAREN, CHECK_OK); |
2568 Expression* tag = ParseExpression(true, CHECK_OK); | 2575 Expression* tag = ParseExpression(true, CHECK_OK); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2631 } | 2638 } |
2632 | 2639 |
2633 // If we can break out from the catch block and there is a finally block, | 2640 // If we can break out from the catch block and there is a finally block, |
2634 // then we will need to collect escaping targets from the catch | 2641 // then we will need to collect escaping targets from the catch |
2635 // block. Since we don't know yet if there will be a finally block, we | 2642 // block. Since we don't know yet if there will be a finally block, we |
2636 // always collect the targets. | 2643 // always collect the targets. |
2637 TargetCollector catch_collector(zone()); | 2644 TargetCollector catch_collector(zone()); |
2638 Scope* catch_scope = NULL; | 2645 Scope* catch_scope = NULL; |
2639 Variable* catch_variable = NULL; | 2646 Variable* catch_variable = NULL; |
2640 Block* catch_block = NULL; | 2647 Block* catch_block = NULL; |
2641 Handle<String> name; | 2648 const AstString* name = NULL; |
2642 if (tok == Token::CATCH) { | 2649 if (tok == Token::CATCH) { |
2643 Consume(Token::CATCH); | 2650 Consume(Token::CATCH); |
2644 | 2651 |
2645 Expect(Token::LPAREN, CHECK_OK); | 2652 Expect(Token::LPAREN, CHECK_OK); |
2646 catch_scope = NewScope(scope_, CATCH_SCOPE); | 2653 catch_scope = NewScope(scope_, CATCH_SCOPE); |
2647 catch_scope->set_start_position(scanner()->location().beg_pos); | 2654 catch_scope->set_start_position(scanner()->location().beg_pos); |
2648 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2655 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
2649 | 2656 |
2650 Expect(Token::RPAREN, CHECK_OK); | 2657 Expect(Token::RPAREN, CHECK_OK); |
2651 | 2658 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2701 index, try_block, finally_block, pos); | 2708 index, try_block, finally_block, pos); |
2702 // Combine the jump targets of the try block and the possible catch block. | 2709 // Combine the jump targets of the try block and the possible catch block. |
2703 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); | 2710 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); |
2704 } | 2711 } |
2705 | 2712 |
2706 result->set_escaping_targets(try_collector.targets()); | 2713 result->set_escaping_targets(try_collector.targets()); |
2707 return result; | 2714 return result; |
2708 } | 2715 } |
2709 | 2716 |
2710 | 2717 |
2711 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, | 2718 DoWhileStatement* Parser::ParseDoWhileStatement( |
2712 bool* ok) { | 2719 ZoneList<const AstString*>* labels, bool* ok) { |
2713 // DoStatement :: | 2720 // DoStatement :: |
2714 // 'do' Statement 'while' '(' Expression ')' ';' | 2721 // 'do' Statement 'while' '(' Expression ')' ';' |
2715 | 2722 |
2716 DoWhileStatement* loop = | 2723 DoWhileStatement* loop = |
2717 factory()->NewDoWhileStatement(labels, peek_position()); | 2724 factory()->NewDoWhileStatement(labels, peek_position()); |
2718 Target target(&this->target_stack_, loop); | 2725 Target target(&this->target_stack_, loop); |
2719 | 2726 |
2720 Expect(Token::DO, CHECK_OK); | 2727 Expect(Token::DO, CHECK_OK); |
2721 Statement* body = ParseStatement(NULL, CHECK_OK); | 2728 Statement* body = ParseStatement(NULL, CHECK_OK); |
2722 Expect(Token::WHILE, CHECK_OK); | 2729 Expect(Token::WHILE, CHECK_OK); |
2723 Expect(Token::LPAREN, CHECK_OK); | 2730 Expect(Token::LPAREN, CHECK_OK); |
2724 | 2731 |
2725 Expression* cond = ParseExpression(true, CHECK_OK); | 2732 Expression* cond = ParseExpression(true, CHECK_OK); |
2726 Expect(Token::RPAREN, CHECK_OK); | 2733 Expect(Token::RPAREN, CHECK_OK); |
2727 | 2734 |
2728 // Allow do-statements to be terminated with and without | 2735 // Allow do-statements to be terminated with and without |
2729 // semi-colons. This allows code such as 'do;while(0)return' to | 2736 // semi-colons. This allows code such as 'do;while(0)return' to |
2730 // parse, which would not be the case if we had used the | 2737 // parse, which would not be the case if we had used the |
2731 // ExpectSemicolon() functionality here. | 2738 // ExpectSemicolon() functionality here. |
2732 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); | 2739 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); |
2733 | 2740 |
2734 if (loop != NULL) loop->Initialize(cond, body); | 2741 if (loop != NULL) loop->Initialize(cond, body); |
2735 return loop; | 2742 return loop; |
2736 } | 2743 } |
2737 | 2744 |
2738 | 2745 |
2739 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { | 2746 WhileStatement* Parser::ParseWhileStatement(ZoneList<const AstString*>* labels, |
| 2747 bool* ok) { |
2740 // WhileStatement :: | 2748 // WhileStatement :: |
2741 // 'while' '(' Expression ')' Statement | 2749 // 'while' '(' Expression ')' Statement |
2742 | 2750 |
2743 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); | 2751 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); |
2744 Target target(&this->target_stack_, loop); | 2752 Target target(&this->target_stack_, loop); |
2745 | 2753 |
2746 Expect(Token::WHILE, CHECK_OK); | 2754 Expect(Token::WHILE, CHECK_OK); |
2747 Expect(Token::LPAREN, CHECK_OK); | 2755 Expect(Token::LPAREN, CHECK_OK); |
2748 Expression* cond = ParseExpression(true, CHECK_OK); | 2756 Expression* cond = ParseExpression(true, CHECK_OK); |
2749 Expect(Token::RPAREN, CHECK_OK); | 2757 Expect(Token::RPAREN, CHECK_OK); |
(...skipping 18 matching lines...) Expand all Loading... |
2768 } | 2776 } |
2769 | 2777 |
2770 | 2778 |
2771 void Parser::InitializeForEachStatement(ForEachStatement* stmt, | 2779 void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
2772 Expression* each, | 2780 Expression* each, |
2773 Expression* subject, | 2781 Expression* subject, |
2774 Statement* body) { | 2782 Statement* body) { |
2775 ForOfStatement* for_of = stmt->AsForOfStatement(); | 2783 ForOfStatement* for_of = stmt->AsForOfStatement(); |
2776 | 2784 |
2777 if (for_of != NULL) { | 2785 if (for_of != NULL) { |
2778 Factory* heap_factory = isolate()->factory(); | |
2779 Variable* iterator = scope_->DeclarationScope()->NewTemporary( | 2786 Variable* iterator = scope_->DeclarationScope()->NewTemporary( |
2780 heap_factory->dot_iterator_string()); | 2787 string_table_->dot_iterator_string()); |
2781 Variable* result = scope_->DeclarationScope()->NewTemporary( | 2788 Variable* result = scope_->DeclarationScope()->NewTemporary( |
2782 heap_factory->dot_result_string()); | 2789 string_table_->dot_result_string()); |
2783 | 2790 |
2784 Expression* assign_iterator; | 2791 Expression* assign_iterator; |
2785 Expression* next_result; | 2792 Expression* next_result; |
2786 Expression* result_done; | 2793 Expression* result_done; |
2787 Expression* assign_each; | 2794 Expression* assign_each; |
2788 | 2795 |
2789 // var iterator = iterable; | 2796 // var iterator = iterable; |
2790 { | 2797 { |
2791 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2798 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
2792 assign_iterator = factory()->NewAssignment( | 2799 assign_iterator = factory()->NewAssignment( |
2793 Token::ASSIGN, iterator_proxy, subject, RelocInfo::kNoPosition); | 2800 Token::ASSIGN, iterator_proxy, subject, RelocInfo::kNoPosition); |
2794 } | 2801 } |
2795 | 2802 |
2796 // var result = iterator.next(); | 2803 // var result = iterator.next(); |
2797 { | 2804 { |
2798 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2805 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
2799 Expression* next_literal = factory()->NewLiteral( | 2806 Expression* next_literal = factory()->NewLiteral( |
2800 heap_factory->next_string(), RelocInfo::kNoPosition); | 2807 string_table_->next_string(), RelocInfo::kNoPosition); |
2801 Expression* next_property = factory()->NewProperty( | 2808 Expression* next_property = factory()->NewProperty( |
2802 iterator_proxy, next_literal, RelocInfo::kNoPosition); | 2809 iterator_proxy, next_literal, RelocInfo::kNoPosition); |
2803 ZoneList<Expression*>* next_arguments = | 2810 ZoneList<Expression*>* next_arguments = |
2804 new(zone()) ZoneList<Expression*>(0, zone()); | 2811 new(zone()) ZoneList<Expression*>(0, zone()); |
2805 Expression* next_call = factory()->NewCall( | 2812 Expression* next_call = factory()->NewCall( |
2806 next_property, next_arguments, RelocInfo::kNoPosition); | 2813 next_property, next_arguments, RelocInfo::kNoPosition); |
2807 Expression* result_proxy = factory()->NewVariableProxy(result); | 2814 Expression* result_proxy = factory()->NewVariableProxy(result); |
2808 next_result = factory()->NewAssignment( | 2815 next_result = factory()->NewAssignment( |
2809 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); | 2816 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); |
2810 } | 2817 } |
2811 | 2818 |
2812 // result.done | 2819 // result.done |
2813 { | 2820 { |
2814 Expression* done_literal = factory()->NewLiteral( | 2821 Expression* done_literal = factory()->NewLiteral( |
2815 heap_factory->done_string(), RelocInfo::kNoPosition); | 2822 string_table_->done_string(), RelocInfo::kNoPosition); |
2816 Expression* result_proxy = factory()->NewVariableProxy(result); | 2823 Expression* result_proxy = factory()->NewVariableProxy(result); |
2817 result_done = factory()->NewProperty( | 2824 result_done = factory()->NewProperty( |
2818 result_proxy, done_literal, RelocInfo::kNoPosition); | 2825 result_proxy, done_literal, RelocInfo::kNoPosition); |
2819 } | 2826 } |
2820 | 2827 |
2821 // each = result.value | 2828 // each = result.value |
2822 { | 2829 { |
2823 Expression* value_literal = factory()->NewLiteral( | 2830 Expression* value_literal = factory()->NewLiteral( |
2824 heap_factory->value_string(), RelocInfo::kNoPosition); | 2831 string_table_->value_string(), RelocInfo::kNoPosition); |
2825 Expression* result_proxy = factory()->NewVariableProxy(result); | 2832 Expression* result_proxy = factory()->NewVariableProxy(result); |
2826 Expression* result_value = factory()->NewProperty( | 2833 Expression* result_value = factory()->NewProperty( |
2827 result_proxy, value_literal, RelocInfo::kNoPosition); | 2834 result_proxy, value_literal, RelocInfo::kNoPosition); |
2828 assign_each = factory()->NewAssignment( | 2835 assign_each = factory()->NewAssignment( |
2829 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); | 2836 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); |
2830 } | 2837 } |
2831 | 2838 |
2832 for_of->Initialize(each, subject, body, | 2839 for_of->Initialize(each, subject, body, |
2833 assign_iterator, next_result, result_done, assign_each); | 2840 assign_iterator, next_result, result_done, assign_each); |
2834 } else { | 2841 } else { |
2835 stmt->Initialize(each, subject, body); | 2842 stmt->Initialize(each, subject, body); |
2836 } | 2843 } |
2837 } | 2844 } |
2838 | 2845 |
2839 | 2846 |
2840 Statement* Parser::DesugarLetBindingsInForStatement( | 2847 Statement* Parser::DesugarLetBindingsInForStatement( |
2841 Scope* inner_scope, ZoneStringList* names, ForStatement* loop, | 2848 Scope* inner_scope, ZoneList<const AstString*>* names, |
2842 Statement* init, Expression* cond, Statement* next, Statement* body, | 2849 ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
2843 bool* ok) { | 2850 Statement* body, bool* ok) { |
2844 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are | 2851 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are |
2845 // copied into a new environment. After copying, the "next" statement of the | 2852 // copied into a new environment. After copying, the "next" statement of the |
2846 // loop is executed to update the loop variables. The loop condition is | 2853 // loop is executed to update the loop variables. The loop condition is |
2847 // checked and the loop body is executed. | 2854 // checked and the loop body is executed. |
2848 // | 2855 // |
2849 // We rewrite a for statement of the form | 2856 // We rewrite a for statement of the form |
2850 // | 2857 // |
2851 // for (let x = i; cond; next) body | 2858 // for (let x = i; cond; next) body |
2852 // | 2859 // |
2853 // into | 2860 // into |
(...skipping 20 matching lines...) Expand all Loading... |
2874 // } | 2881 // } |
2875 | 2882 |
2876 ASSERT(names->length() > 0); | 2883 ASSERT(names->length() > 0); |
2877 Scope* for_scope = scope_; | 2884 Scope* for_scope = scope_; |
2878 ZoneList<Variable*> temps(names->length(), zone()); | 2885 ZoneList<Variable*> temps(names->length(), zone()); |
2879 | 2886 |
2880 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false, | 2887 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false, |
2881 RelocInfo::kNoPosition); | 2888 RelocInfo::kNoPosition); |
2882 outer_block->AddStatement(init, zone()); | 2889 outer_block->AddStatement(init, zone()); |
2883 | 2890 |
2884 Handle<String> temp_name = isolate()->factory()->dot_for_string(); | 2891 const AstString* temp_name = string_table_->dot_for_string(); |
2885 Handle<Smi> smi0 = handle(Smi::FromInt(0), isolate()); | |
2886 Handle<Smi> smi1 = handle(Smi::FromInt(1), isolate()); | |
2887 | |
2888 | 2892 |
2889 // For each let variable x: | 2893 // For each let variable x: |
2890 // make statement: temp_x = x. | 2894 // make statement: temp_x = x. |
2891 for (int i = 0; i < names->length(); i++) { | 2895 for (int i = 0; i < names->length(); i++) { |
2892 VariableProxy* proxy = | 2896 VariableProxy* proxy = |
2893 NewUnresolved(names->at(i), LET, Interface::NewValue()); | 2897 NewUnresolved(names->at(i), LET, Interface::NewValue()); |
2894 Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name); | 2898 Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name); |
2895 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 2899 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
2896 Assignment* assignment = factory()->NewAssignment( | 2900 Assignment* assignment = factory()->NewAssignment( |
2897 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition); | 2901 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition); |
2898 Statement* assignment_statement = factory()->NewExpressionStatement( | 2902 Statement* assignment_statement = factory()->NewExpressionStatement( |
2899 assignment, RelocInfo::kNoPosition); | 2903 assignment, RelocInfo::kNoPosition); |
2900 outer_block->AddStatement(assignment_statement, zone()); | 2904 outer_block->AddStatement(assignment_statement, zone()); |
2901 temps.Add(temp, zone()); | 2905 temps.Add(temp, zone()); |
2902 } | 2906 } |
2903 | 2907 |
2904 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name); | 2908 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name); |
2905 // Make statement: flag = 1. | 2909 // Make statement: flag = 1. |
2906 { | 2910 { |
2907 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); | 2911 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); |
2908 Expression* const1 = factory()->NewLiteral(smi1, RelocInfo::kNoPosition); | 2912 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); |
2909 Assignment* assignment = factory()->NewAssignment( | 2913 Assignment* assignment = factory()->NewAssignment( |
2910 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition); | 2914 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition); |
2911 Statement* assignment_statement = factory()->NewExpressionStatement( | 2915 Statement* assignment_statement = factory()->NewExpressionStatement( |
2912 assignment, RelocInfo::kNoPosition); | 2916 assignment, RelocInfo::kNoPosition); |
2913 outer_block->AddStatement(assignment_statement, zone()); | 2917 outer_block->AddStatement(assignment_statement, zone()); |
2914 } | 2918 } |
2915 | 2919 |
2916 outer_block->AddStatement(loop, zone()); | 2920 outer_block->AddStatement(loop, zone()); |
2917 outer_block->set_scope(for_scope); | 2921 outer_block->set_scope(for_scope); |
2918 scope_ = inner_scope; | 2922 scope_ = inner_scope; |
(...skipping 19 matching lines...) Expand all Loading... |
2938 assignment, pos); | 2942 assignment, pos); |
2939 proxy->var()->set_initializer_position(pos); | 2943 proxy->var()->set_initializer_position(pos); |
2940 inner_block->AddStatement(assignment_statement, zone()); | 2944 inner_block->AddStatement(assignment_statement, zone()); |
2941 } | 2945 } |
2942 | 2946 |
2943 // Make statement: if (flag == 1) { flag = 0; } else { next; }. | 2947 // Make statement: if (flag == 1) { flag = 0; } else { next; }. |
2944 { | 2948 { |
2945 Expression* compare = NULL; | 2949 Expression* compare = NULL; |
2946 // Make compare expresion: flag == 1. | 2950 // Make compare expresion: flag == 1. |
2947 { | 2951 { |
2948 Expression* const1 = factory()->NewLiteral(smi1, RelocInfo::kNoPosition); | 2952 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); |
2949 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); | 2953 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); |
2950 compare = factory()->NewCompareOperation( | 2954 compare = factory()->NewCompareOperation( |
2951 Token::EQ, flag_proxy, const1, RelocInfo::kNoPosition); | 2955 Token::EQ, flag_proxy, const1, RelocInfo::kNoPosition); |
2952 } | 2956 } |
2953 Statement* clear_flag = NULL; | 2957 Statement* clear_flag = NULL; |
2954 // Make statement: flag = 0. | 2958 // Make statement: flag = 0. |
2955 { | 2959 { |
2956 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); | 2960 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); |
2957 Expression* const0 = factory()->NewLiteral(smi0, RelocInfo::kNoPosition); | 2961 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition); |
2958 Assignment* assignment = factory()->NewAssignment( | 2962 Assignment* assignment = factory()->NewAssignment( |
2959 Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition); | 2963 Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition); |
2960 clear_flag = factory()->NewExpressionStatement(assignment, pos); | 2964 clear_flag = factory()->NewExpressionStatement(assignment, pos); |
2961 } | 2965 } |
2962 Statement* clear_flag_or_next = factory()->NewIfStatement( | 2966 Statement* clear_flag_or_next = factory()->NewIfStatement( |
2963 compare, clear_flag, next, RelocInfo::kNoPosition); | 2967 compare, clear_flag, next, RelocInfo::kNoPosition); |
2964 inner_block->AddStatement(clear_flag_or_next, zone()); | 2968 inner_block->AddStatement(clear_flag_or_next, zone()); |
2965 } | 2969 } |
2966 | 2970 |
2967 | 2971 |
2968 // Make statement: if (cond) { } else { break; }. | 2972 // Make statement: if (cond) { } else { break; }. |
2969 { | 2973 { |
2970 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 2974 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
2971 BreakableStatement* t = LookupBreakTarget(Handle<String>(), CHECK_OK); | 2975 BreakableStatement* t = LookupBreakTarget(NULL, CHECK_OK); |
2972 Statement* stop = factory()->NewBreakStatement(t, RelocInfo::kNoPosition); | 2976 Statement* stop = factory()->NewBreakStatement(t, RelocInfo::kNoPosition); |
2973 Statement* if_not_cond_break = factory()->NewIfStatement( | 2977 Statement* if_not_cond_break = factory()->NewIfStatement( |
2974 cond, empty, stop, RelocInfo::kNoPosition); | 2978 cond, empty, stop, RelocInfo::kNoPosition); |
2975 inner_block->AddStatement(if_not_cond_break, zone()); | 2979 inner_block->AddStatement(if_not_cond_break, zone()); |
2976 } | 2980 } |
2977 | 2981 |
2978 inner_block->AddStatement(body, zone()); | 2982 inner_block->AddStatement(body, zone()); |
2979 | 2983 |
2980 // For each let variable x: | 2984 // For each let variable x: |
2981 // make statement: temp_x = x; | 2985 // make statement: temp_x = x; |
(...skipping 10 matching lines...) Expand all Loading... |
2992 | 2996 |
2993 inner_scope->set_end_position(scanner()->location().end_pos); | 2997 inner_scope->set_end_position(scanner()->location().end_pos); |
2994 inner_block->set_scope(inner_scope); | 2998 inner_block->set_scope(inner_scope); |
2995 scope_ = for_scope; | 2999 scope_ = for_scope; |
2996 | 3000 |
2997 loop->Initialize(NULL, NULL, NULL, inner_block); | 3001 loop->Initialize(NULL, NULL, NULL, inner_block); |
2998 return outer_block; | 3002 return outer_block; |
2999 } | 3003 } |
3000 | 3004 |
3001 | 3005 |
3002 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 3006 Statement* Parser::ParseForStatement(ZoneList<const AstString*>* labels, |
| 3007 bool* ok) { |
3003 // ForStatement :: | 3008 // ForStatement :: |
3004 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 3009 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
3005 | 3010 |
3006 int pos = peek_position(); | 3011 int pos = peek_position(); |
3007 Statement* init = NULL; | 3012 Statement* init = NULL; |
3008 ZoneStringList let_bindings(1, zone()); | 3013 ZoneList<const AstString*> let_bindings(1, zone()); |
3009 | 3014 |
3010 // Create an in-between scope for let-bound iteration variables. | 3015 // Create an in-between scope for let-bound iteration variables. |
3011 Scope* saved_scope = scope_; | 3016 Scope* saved_scope = scope_; |
3012 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); | 3017 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); |
3013 scope_ = for_scope; | 3018 scope_ = for_scope; |
3014 | 3019 |
3015 Expect(Token::FOR, CHECK_OK); | 3020 Expect(Token::FOR, CHECK_OK); |
3016 Expect(Token::LPAREN, CHECK_OK); | 3021 Expect(Token::LPAREN, CHECK_OK); |
3017 for_scope->set_start_position(scanner()->location().beg_pos); | 3022 for_scope->set_start_position(scanner()->location().beg_pos); |
3018 if (peek() != Token::SEMICOLON) { | 3023 if (peek() != Token::SEMICOLON) { |
3019 if (peek() == Token::VAR || peek() == Token::CONST) { | 3024 if (peek() == Token::VAR || peek() == Token::CONST) { |
3020 bool is_const = peek() == Token::CONST; | 3025 bool is_const = peek() == Token::CONST; |
3021 Handle<String> name; | 3026 const AstString* name = NULL; |
3022 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3027 VariableDeclarationProperties decl_props = kHasNoInitializers; |
3023 Block* variable_statement = | 3028 Block* variable_statement = |
3024 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 3029 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
3025 CHECK_OK); | 3030 CHECK_OK); |
3026 bool accept_OF = decl_props == kHasNoInitializers; | 3031 bool accept_OF = decl_props == kHasNoInitializers; |
3027 ForEachStatement::VisitMode mode; | 3032 ForEachStatement::VisitMode mode; |
3028 | 3033 |
3029 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { | 3034 if (name != NULL && CheckInOrOf(accept_OF, &mode)) { |
3030 Interface* interface = | 3035 Interface* interface = |
3031 is_const ? Interface::NewConst() : Interface::NewValue(); | 3036 is_const ? Interface::NewConst() : Interface::NewValue(); |
3032 ForEachStatement* loop = | 3037 ForEachStatement* loop = |
3033 factory()->NewForEachStatement(mode, labels, pos); | 3038 factory()->NewForEachStatement(mode, labels, pos); |
3034 Target target(&this->target_stack_, loop); | 3039 Target target(&this->target_stack_, loop); |
3035 | 3040 |
3036 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3041 Expression* enumerable = ParseExpression(true, CHECK_OK); |
3037 Expect(Token::RPAREN, CHECK_OK); | 3042 Expect(Token::RPAREN, CHECK_OK); |
3038 | 3043 |
3039 VariableProxy* each = | 3044 VariableProxy* each = |
3040 scope_->NewUnresolved(factory(), name, interface); | 3045 scope_->NewUnresolved(factory(), name, interface); |
3041 Statement* body = ParseStatement(NULL, CHECK_OK); | 3046 Statement* body = ParseStatement(NULL, CHECK_OK); |
3042 InitializeForEachStatement(loop, each, enumerable, body); | 3047 InitializeForEachStatement(loop, each, enumerable, body); |
3043 Block* result = | 3048 Block* result = |
3044 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 3049 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
3045 result->AddStatement(variable_statement, zone()); | 3050 result->AddStatement(variable_statement, zone()); |
3046 result->AddStatement(loop, zone()); | 3051 result->AddStatement(loop, zone()); |
3047 scope_ = saved_scope; | 3052 scope_ = saved_scope; |
3048 for_scope->set_end_position(scanner()->location().end_pos); | 3053 for_scope->set_end_position(scanner()->location().end_pos); |
3049 for_scope = for_scope->FinalizeBlockScope(); | 3054 for_scope = for_scope->FinalizeBlockScope(); |
3050 ASSERT(for_scope == NULL); | 3055 ASSERT(for_scope == NULL); |
3051 // Parsed for-in loop w/ variable/const declaration. | 3056 // Parsed for-in loop w/ variable/const declaration. |
3052 return result; | 3057 return result; |
3053 } else { | 3058 } else { |
3054 init = variable_statement; | 3059 init = variable_statement; |
3055 } | 3060 } |
3056 } else if (peek() == Token::LET) { | 3061 } else if (peek() == Token::LET) { |
3057 Handle<String> name; | 3062 const AstString* name = NULL; |
3058 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3063 VariableDeclarationProperties decl_props = kHasNoInitializers; |
3059 Block* variable_statement = | 3064 Block* variable_statement = |
3060 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, | 3065 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, |
3061 &name, CHECK_OK); | 3066 &name, CHECK_OK); |
3062 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; | 3067 bool accept_IN = name != NULL && decl_props != kHasInitializers; |
3063 bool accept_OF = decl_props == kHasNoInitializers; | 3068 bool accept_OF = decl_props == kHasNoInitializers; |
3064 ForEachStatement::VisitMode mode; | 3069 ForEachStatement::VisitMode mode; |
3065 | 3070 |
3066 if (accept_IN && CheckInOrOf(accept_OF, &mode)) { | 3071 if (accept_IN && CheckInOrOf(accept_OF, &mode)) { |
3067 // Rewrite a for-in statement of the form | 3072 // Rewrite a for-in statement of the form |
3068 // | 3073 // |
3069 // for (let x in e) b | 3074 // for (let x in e) b |
3070 // | 3075 // |
3071 // into | 3076 // into |
3072 // | 3077 // |
3073 // <let x' be a temporary variable> | 3078 // <let x' be a temporary variable> |
3074 // for (x' in e) { | 3079 // for (x' in e) { |
3075 // let x; | 3080 // let x; |
3076 // x = x'; | 3081 // x = x'; |
3077 // b; | 3082 // b; |
3078 // } | 3083 // } |
3079 | 3084 |
3080 // TODO(keuchel): Move the temporary variable to the block scope, after | 3085 // TODO(keuchel): Move the temporary variable to the block scope, after |
3081 // implementing stack allocated block scoped variables. | 3086 // implementing stack allocated block scoped variables. |
3082 Factory* heap_factory = isolate()->factory(); | 3087 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
3083 Handle<String> tempstr; | 3088 string_table_->dot_for_string()); |
3084 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
3085 isolate(), tempstr, | |
3086 heap_factory->NewConsString(heap_factory->dot_for_string(), name), | |
3087 0); | |
3088 Handle<String> tempname = heap_factory->InternalizeString(tempstr); | |
3089 Variable* temp = scope_->DeclarationScope()->NewTemporary(tempname); | |
3090 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 3089 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
3091 ForEachStatement* loop = | 3090 ForEachStatement* loop = |
3092 factory()->NewForEachStatement(mode, labels, pos); | 3091 factory()->NewForEachStatement(mode, labels, pos); |
3093 Target target(&this->target_stack_, loop); | 3092 Target target(&this->target_stack_, loop); |
3094 | 3093 |
3095 // The expression does not see the loop variable. | 3094 // The expression does not see the loop variable. |
3096 scope_ = saved_scope; | 3095 scope_ = saved_scope; |
3097 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3096 Expression* enumerable = ParseExpression(true, CHECK_OK); |
3098 scope_ = for_scope; | 3097 scope_ = for_scope; |
3099 Expect(Token::RPAREN, CHECK_OK); | 3098 Expect(Token::RPAREN, CHECK_OK); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3210 // DebuggerStatement :: | 3209 // DebuggerStatement :: |
3211 // 'debugger' ';' | 3210 // 'debugger' ';' |
3212 | 3211 |
3213 int pos = peek_position(); | 3212 int pos = peek_position(); |
3214 Expect(Token::DEBUGGER, CHECK_OK); | 3213 Expect(Token::DEBUGGER, CHECK_OK); |
3215 ExpectSemicolon(CHECK_OK); | 3214 ExpectSemicolon(CHECK_OK); |
3216 return factory()->NewDebuggerStatement(pos); | 3215 return factory()->NewDebuggerStatement(pos); |
3217 } | 3216 } |
3218 | 3217 |
3219 | 3218 |
3220 void Parser::ReportInvalidCachedData(Handle<String> name, bool* ok) { | 3219 void Parser::ReportInvalidCachedData(const AstString* name, bool* ok) { |
3221 ParserTraits::ReportMessage("invalid_cached_data_function", name); | 3220 ParserTraits::ReportMessage("invalid_cached_data_function", name); |
3222 *ok = false; | 3221 *ok = false; |
3223 } | 3222 } |
3224 | 3223 |
3225 | 3224 |
3226 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { | 3225 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { |
3227 if (expression->IsLiteral()) return true; | 3226 if (expression->IsLiteral()) return true; |
3228 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); | 3227 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); |
3229 return lit != NULL && lit->is_simple(); | 3228 return lit != NULL && lit->is_simple(); |
3230 } | 3229 } |
(...skipping 29 matching lines...) Expand all Loading... |
3260 return static_cast<LiteralType>(literal_type->value()); | 3259 return static_cast<LiteralType>(literal_type->value()); |
3261 } | 3260 } |
3262 | 3261 |
3263 | 3262 |
3264 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { | 3263 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { |
3265 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); | 3264 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); |
3266 } | 3265 } |
3267 | 3266 |
3268 | 3267 |
3269 FunctionLiteral* Parser::ParseFunctionLiteral( | 3268 FunctionLiteral* Parser::ParseFunctionLiteral( |
3270 Handle<String> function_name, | 3269 const AstString* function_name, |
3271 Scanner::Location function_name_location, | 3270 Scanner::Location function_name_location, |
3272 bool name_is_strict_reserved, | 3271 bool name_is_strict_reserved, |
3273 bool is_generator, | 3272 bool is_generator, |
3274 int function_token_pos, | 3273 int function_token_pos, |
3275 FunctionLiteral::FunctionType function_type, | 3274 FunctionLiteral::FunctionType function_type, |
3276 bool* ok) { | 3275 bool* ok) { |
3277 // Function :: | 3276 // Function :: |
3278 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 3277 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
3279 | 3278 |
3280 int pos = function_token_pos == RelocInfo::kNoPosition | 3279 int pos = function_token_pos == RelocInfo::kNoPosition |
3281 ? peek_position() : function_token_pos; | 3280 ? peek_position() : function_token_pos; |
3282 | 3281 |
3283 // Anonymous functions were passed either the empty symbol or a null | 3282 // Anonymous functions were passed either the empty symbol or a null |
3284 // handle as the function name. Remember if we were passed a non-empty | 3283 // handle as the function name. Remember if we were passed a non-empty |
3285 // handle to decide whether to invoke function name inference. | 3284 // handle to decide whether to invoke function name inference. |
3286 bool should_infer_name = function_name.is_null(); | 3285 bool should_infer_name = function_name == NULL; |
3287 | 3286 |
3288 // We want a non-null handle as the function name. | 3287 // We want a non-null handle as the function name. |
3289 if (should_infer_name) { | 3288 if (should_infer_name) { |
3290 function_name = isolate()->factory()->empty_string(); | 3289 function_name = string_table_->empty_string(); |
3291 } | 3290 } |
3292 | 3291 |
3293 int num_parameters = 0; | 3292 int num_parameters = 0; |
3294 // Function declarations are function scoped in normal mode, so they are | 3293 // Function declarations are function scoped in normal mode, so they are |
3295 // hoisted. In harmony block scoping mode they are block scoped, so they | 3294 // hoisted. In harmony block scoping mode they are block scoped, so they |
3296 // are not hoisted. | 3295 // are not hoisted. |
3297 // | 3296 // |
3298 // One tricky case are function declarations in a local sloppy-mode eval: | 3297 // One tricky case are function declarations in a local sloppy-mode eval: |
3299 // their declaration is hoisted, but they still see the local scope. E.g., | 3298 // their declaration is hoisted, but they still see the local scope. E.g., |
3300 // | 3299 // |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3332 int expected_property_count = -1; | 3331 int expected_property_count = -1; |
3333 int handler_count = 0; | 3332 int handler_count = 0; |
3334 FunctionLiteral::ParameterFlag duplicate_parameters = | 3333 FunctionLiteral::ParameterFlag duplicate_parameters = |
3335 FunctionLiteral::kNoDuplicateParameters; | 3334 FunctionLiteral::kNoDuplicateParameters; |
3336 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ | 3335 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ |
3337 ? FunctionLiteral::kIsParenthesized | 3336 ? FunctionLiteral::kIsParenthesized |
3338 : FunctionLiteral::kNotParenthesized; | 3337 : FunctionLiteral::kNotParenthesized; |
3339 AstProperties ast_properties; | 3338 AstProperties ast_properties; |
3340 BailoutReason dont_optimize_reason = kNoReason; | 3339 BailoutReason dont_optimize_reason = kNoReason; |
3341 // Parse function body. | 3340 // Parse function body. |
3342 { FunctionState function_state(&function_state_, &scope_, scope, zone()); | 3341 { |
| 3342 FunctionState function_state(&function_state_, &scope_, scope, zone(), |
| 3343 string_table_); |
3343 scope_->SetScopeName(function_name); | 3344 scope_->SetScopeName(function_name); |
3344 | 3345 |
3345 if (is_generator) { | 3346 if (is_generator) { |
3346 // For generators, allocating variables in contexts is currently a win | 3347 // For generators, allocating variables in contexts is currently a win |
3347 // because it minimizes the work needed to suspend and resume an | 3348 // because it minimizes the work needed to suspend and resume an |
3348 // activation. | 3349 // activation. |
3349 scope_->ForceContextAllocation(); | 3350 scope_->ForceContextAllocation(); |
3350 | 3351 |
3351 // Calling a generator returns a generator object. That object is stored | 3352 // Calling a generator returns a generator object. That object is stored |
3352 // in a temporary variable, a definition that is used by "yield" | 3353 // in a temporary variable, a definition that is used by "yield" |
3353 // expressions. This also marks the FunctionState as a generator. | 3354 // expressions. This also marks the FunctionState as a generator. |
3354 Variable* temp = scope_->DeclarationScope()->NewTemporary( | 3355 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
3355 isolate()->factory()->dot_generator_object_string()); | 3356 string_table_->dot_generator_object_string()); |
3356 function_state.set_generator_object_variable(temp); | 3357 function_state.set_generator_object_variable(temp); |
3357 } | 3358 } |
3358 | 3359 |
3359 // FormalParameterList :: | 3360 // FormalParameterList :: |
3360 // '(' (Identifier)*[','] ')' | 3361 // '(' (Identifier)*[','] ')' |
3361 Expect(Token::LPAREN, CHECK_OK); | 3362 Expect(Token::LPAREN, CHECK_OK); |
3362 scope->set_start_position(scanner()->location().beg_pos); | 3363 scope->set_start_position(scanner()->location().beg_pos); |
3363 | 3364 |
3364 // We don't yet know if the function will be strict, so we cannot yet | 3365 // We don't yet know if the function will be strict, so we cannot yet |
3365 // produce errors for parameter names or duplicates. However, we remember | 3366 // produce errors for parameter names or duplicates. However, we remember |
3366 // the locations of these errors if they occur and produce the errors later. | 3367 // the locations of these errors if they occur and produce the errors later. |
3367 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); | 3368 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); |
3368 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | 3369 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); |
3369 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 3370 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
3370 | 3371 |
3371 bool done = (peek() == Token::RPAREN); | 3372 bool done = (peek() == Token::RPAREN); |
3372 while (!done) { | 3373 while (!done) { |
3373 bool is_strict_reserved = false; | 3374 bool is_strict_reserved = false; |
3374 Handle<String> param_name = | 3375 const AstString* param_name = |
3375 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 3376 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
3376 | 3377 |
3377 // Store locations for possible future error reports. | 3378 // Store locations for possible future error reports. |
3378 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { | 3379 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { |
3379 eval_args_error_log = scanner()->location(); | 3380 eval_args_error_log = scanner()->location(); |
3380 } | 3381 } |
3381 if (!reserved_loc.IsValid() && is_strict_reserved) { | 3382 if (!reserved_loc.IsValid() && is_strict_reserved) { |
3382 reserved_loc = scanner()->location(); | 3383 reserved_loc = scanner()->location(); |
3383 } | 3384 } |
3384 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { | 3385 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { |
(...skipping 23 matching lines...) Expand all Loading... |
3408 // instead of Variables and Proxis as is the case now. | 3409 // instead of Variables and Proxis as is the case now. |
3409 Variable* fvar = NULL; | 3410 Variable* fvar = NULL; |
3410 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; | 3411 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; |
3411 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 3412 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
3412 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 3413 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
3413 fvar_init_op = Token::INIT_CONST; | 3414 fvar_init_op = Token::INIT_CONST; |
3414 } | 3415 } |
3415 VariableMode fvar_mode = | 3416 VariableMode fvar_mode = |
3416 allow_harmony_scoping() && strict_mode() == STRICT ? CONST | 3417 allow_harmony_scoping() && strict_mode() == STRICT ? CONST |
3417 : CONST_LEGACY; | 3418 : CONST_LEGACY; |
| 3419 ASSERT(function_name != NULL); |
3418 fvar = new(zone()) Variable(scope_, | 3420 fvar = new(zone()) Variable(scope_, |
3419 function_name, fvar_mode, true /* is valid LHS */, | 3421 function_name, fvar_mode, true /* is valid LHS */, |
3420 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); | 3422 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); |
3421 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 3423 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
3422 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( | 3424 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
3423 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); | 3425 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); |
3424 scope_->DeclareFunctionVar(fvar_declaration); | 3426 scope_->DeclareFunctionVar(fvar_declaration); |
3425 } | 3427 } |
3426 | 3428 |
3427 // Determine if the function can be parsed lazily. Lazy parsing is different | 3429 // Determine if the function can be parsed lazily. Lazy parsing is different |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3511 | 3513 |
3512 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 3514 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
3513 CheckConflictingVarDeclarations(scope, CHECK_OK); | 3515 CheckConflictingVarDeclarations(scope, CHECK_OK); |
3514 } | 3516 } |
3515 | 3517 |
3516 FunctionLiteral::IsGeneratorFlag generator = is_generator | 3518 FunctionLiteral::IsGeneratorFlag generator = is_generator |
3517 ? FunctionLiteral::kIsGenerator | 3519 ? FunctionLiteral::kIsGenerator |
3518 : FunctionLiteral::kNotGenerator; | 3520 : FunctionLiteral::kNotGenerator; |
3519 FunctionLiteral* function_literal = | 3521 FunctionLiteral* function_literal = |
3520 factory()->NewFunctionLiteral(function_name, | 3522 factory()->NewFunctionLiteral(function_name, |
| 3523 string_table_, |
3521 scope, | 3524 scope, |
3522 body, | 3525 body, |
3523 materialized_literal_count, | 3526 materialized_literal_count, |
3524 expected_property_count, | 3527 expected_property_count, |
3525 handler_count, | 3528 handler_count, |
3526 num_parameters, | 3529 num_parameters, |
3527 duplicate_parameters, | 3530 duplicate_parameters, |
3528 function_type, | 3531 function_type, |
3529 FunctionLiteral::kIsFunction, | 3532 FunctionLiteral::kIsFunction, |
3530 parenthesized, | 3533 parenthesized, |
3531 generator, | 3534 generator, |
3532 pos); | 3535 pos); |
3533 function_literal->set_function_token_position(function_token_pos); | 3536 function_literal->set_function_token_position(function_token_pos); |
3534 function_literal->set_ast_properties(&ast_properties); | 3537 function_literal->set_ast_properties(&ast_properties); |
3535 function_literal->set_dont_optimize_reason(dont_optimize_reason); | 3538 function_literal->set_dont_optimize_reason(dont_optimize_reason); |
3536 | 3539 |
3537 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 3540 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
3538 return function_literal; | 3541 return function_literal; |
3539 } | 3542 } |
3540 | 3543 |
3541 | 3544 |
3542 void Parser::SkipLazyFunctionBody(Handle<String> function_name, | 3545 void Parser::SkipLazyFunctionBody(const AstString* function_name, |
3543 int* materialized_literal_count, | 3546 int* materialized_literal_count, |
3544 int* expected_property_count, | 3547 int* expected_property_count, |
3545 bool* ok) { | 3548 bool* ok) { |
3546 int function_block_pos = position(); | 3549 int function_block_pos = position(); |
3547 if (cached_data_mode_ == CONSUME_CACHED_DATA) { | 3550 if (cached_data_mode_ == CONSUME_CACHED_DATA) { |
3548 // If we have cached data, we use it to skip parsing the function body. The | 3551 // If we have cached data, we use it to skip parsing the function body. The |
3549 // data contains the information we need to construct the lazy function. | 3552 // data contains the information we need to construct the lazy function. |
3550 FunctionEntry entry = | 3553 FunctionEntry entry = |
3551 (*cached_data())->GetFunctionEntry(function_block_pos); | 3554 (*cached_data())->GetFunctionEntry(function_block_pos); |
3552 if (entry.is_valid()) { | 3555 if (entry.is_valid()) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3611 log_->LogFunction(function_block_pos, body_end, | 3614 log_->LogFunction(function_block_pos, body_end, |
3612 *materialized_literal_count, | 3615 *materialized_literal_count, |
3613 *expected_property_count, | 3616 *expected_property_count, |
3614 scope_->strict_mode()); | 3617 scope_->strict_mode()); |
3615 } | 3618 } |
3616 } | 3619 } |
3617 } | 3620 } |
3618 | 3621 |
3619 | 3622 |
3620 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( | 3623 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
3621 Handle<String> function_name, int pos, Variable* fvar, | 3624 const AstString* function_name, int pos, Variable* fvar, |
3622 Token::Value fvar_init_op, bool is_generator, bool* ok) { | 3625 Token::Value fvar_init_op, bool is_generator, bool* ok) { |
3623 // Everything inside an eagerly parsed function will be parsed eagerly | 3626 // Everything inside an eagerly parsed function will be parsed eagerly |
3624 // (see comment above). | 3627 // (see comment above). |
3625 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 3628 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
3626 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone()); | 3629 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone()); |
3627 if (fvar != NULL) { | 3630 if (fvar != NULL) { |
3628 VariableProxy* fproxy = scope_->NewUnresolved( | 3631 VariableProxy* fproxy = scope_->NewUnresolved( |
3629 factory(), function_name, Interface::NewConst()); | 3632 factory(), function_name, Interface::NewConst()); |
3630 fproxy->BindTo(fvar); | 3633 fproxy->BindTo(fvar); |
3631 body->Add(factory()->NewExpressionStatement( | 3634 body->Add(factory()->NewExpressionStatement( |
3632 factory()->NewAssignment(fvar_init_op, | 3635 factory()->NewAssignment(fvar_init_op, |
3633 fproxy, | 3636 fproxy, |
3634 factory()->NewThisFunction(pos), | 3637 factory()->NewThisFunction(pos), |
3635 RelocInfo::kNoPosition), | 3638 RelocInfo::kNoPosition), |
3636 RelocInfo::kNoPosition), zone()); | 3639 RelocInfo::kNoPosition), zone()); |
3637 } | 3640 } |
3638 | 3641 |
3639 // For generators, allocate and yield an iterator on function entry. | 3642 // For generators, allocate and yield an iterator on function entry. |
3640 if (is_generator) { | 3643 if (is_generator) { |
3641 ZoneList<Expression*>* arguments = | 3644 ZoneList<Expression*>* arguments = |
3642 new(zone()) ZoneList<Expression*>(0, zone()); | 3645 new(zone()) ZoneList<Expression*>(0, zone()); |
3643 CallRuntime* allocation = factory()->NewCallRuntime( | 3646 CallRuntime* allocation = factory()->NewCallRuntime( |
3644 isolate()->factory()->empty_string(), | 3647 string_table_->empty_string(), |
3645 Runtime::FunctionForId(Runtime::kHiddenCreateJSGeneratorObject), | 3648 Runtime::FunctionForId(Runtime::kHiddenCreateJSGeneratorObject), |
3646 arguments, pos); | 3649 arguments, pos); |
3647 VariableProxy* init_proxy = factory()->NewVariableProxy( | 3650 VariableProxy* init_proxy = factory()->NewVariableProxy( |
3648 function_state_->generator_object_variable()); | 3651 function_state_->generator_object_variable()); |
3649 Assignment* assignment = factory()->NewAssignment( | 3652 Assignment* assignment = factory()->NewAssignment( |
3650 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); | 3653 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); |
3651 VariableProxy* get_proxy = factory()->NewVariableProxy( | 3654 VariableProxy* get_proxy = factory()->NewVariableProxy( |
3652 function_state_->generator_object_variable()); | 3655 function_state_->generator_object_variable()); |
3653 Yield* yield = factory()->NewYield( | 3656 Yield* yield = factory()->NewYield( |
3654 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); | 3657 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); |
3655 body->Add(factory()->NewExpressionStatement( | 3658 body->Add(factory()->NewExpressionStatement( |
3656 yield, RelocInfo::kNoPosition), zone()); | 3659 yield, RelocInfo::kNoPosition), zone()); |
3657 } | 3660 } |
3658 | 3661 |
3659 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); | 3662 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); |
3660 | 3663 |
3661 if (is_generator) { | 3664 if (is_generator) { |
3662 VariableProxy* get_proxy = factory()->NewVariableProxy( | 3665 VariableProxy* get_proxy = factory()->NewVariableProxy( |
3663 function_state_->generator_object_variable()); | 3666 function_state_->generator_object_variable()); |
3664 Expression *undefined = factory()->NewLiteral( | 3667 Expression* undefined = factory()->NewLiteral( |
3665 isolate()->factory()->undefined_value(), RelocInfo::kNoPosition); | 3668 string_table_->NewValue(AstValue::UNDEFINED), |
| 3669 RelocInfo::kNoPosition); |
3666 Yield* yield = factory()->NewYield( | 3670 Yield* yield = factory()->NewYield( |
3667 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); | 3671 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); |
3668 body->Add(factory()->NewExpressionStatement( | 3672 body->Add(factory()->NewExpressionStatement( |
3669 yield, RelocInfo::kNoPosition), zone()); | 3673 yield, RelocInfo::kNoPosition), zone()); |
3670 } | 3674 } |
3671 | 3675 |
3672 Expect(Token::RBRACE, CHECK_OK); | 3676 Expect(Token::RBRACE, CHECK_OK); |
3673 scope_->set_end_position(scanner()->location().end_pos); | 3677 scope_->set_end_position(scanner()->location().end_pos); |
3674 | 3678 |
3675 return body; | 3679 return body; |
(...skipping 25 matching lines...) Expand all Loading... |
3701 } | 3705 } |
3702 | 3706 |
3703 | 3707 |
3704 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3708 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
3705 // CallRuntime :: | 3709 // CallRuntime :: |
3706 // '%' Identifier Arguments | 3710 // '%' Identifier Arguments |
3707 | 3711 |
3708 int pos = peek_position(); | 3712 int pos = peek_position(); |
3709 Expect(Token::MOD, CHECK_OK); | 3713 Expect(Token::MOD, CHECK_OK); |
3710 // Allow "eval" or "arguments" for backward compatibility. | 3714 // Allow "eval" or "arguments" for backward compatibility. |
3711 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 3715 const AstString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
3712 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 3716 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
3713 | 3717 |
3714 if (extension_ != NULL) { | 3718 if (extension_ != NULL) { |
3715 // The extension structures are only accessible while parsing the | 3719 // The extension structures are only accessible while parsing the |
3716 // very first time not when reparsing because of lazy compilation. | 3720 // very first time not when reparsing because of lazy compilation. |
3717 scope_->DeclarationScope()->ForceEagerCompilation(); | 3721 scope_->DeclarationScope()->ForceEagerCompilation(); |
3718 } | 3722 } |
3719 | 3723 |
3720 const Runtime::Function* function = Runtime::FunctionForName(name); | 3724 const Runtime::Function* function = Runtime::FunctionForName(name->string()); |
3721 | 3725 |
3722 // Check for built-in IS_VAR macro. | 3726 // Check for built-in IS_VAR macro. |
3723 if (function != NULL && | 3727 if (function != NULL && |
3724 function->intrinsic_type == Runtime::RUNTIME && | 3728 function->intrinsic_type == Runtime::RUNTIME && |
3725 function->function_id == Runtime::kIS_VAR) { | 3729 function->function_id == Runtime::kIS_VAR) { |
3726 // %IS_VAR(x) evaluates to x if x is a variable, | 3730 // %IS_VAR(x) evaluates to x if x is a variable, |
3727 // leads to a parse error otherwise. Could be implemented as an | 3731 // leads to a parse error otherwise. Could be implemented as an |
3728 // inline function %_IS_VAR(x) to eliminate this special case. | 3732 // inline function %_IS_VAR(x) to eliminate this special case. |
3729 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { | 3733 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { |
3730 return args->at(0); | 3734 return args->at(0); |
3731 } else { | 3735 } else { |
3732 ReportMessage("not_isvar"); | 3736 ReportMessage("not_isvar"); |
3733 *ok = false; | 3737 *ok = false; |
3734 return NULL; | 3738 return NULL; |
3735 } | 3739 } |
3736 } | 3740 } |
3737 | 3741 |
3738 // Check that the expected number of arguments are being passed. | 3742 // Check that the expected number of arguments are being passed. |
3739 if (function != NULL && | 3743 if (function != NULL && |
3740 function->nargs != -1 && | 3744 function->nargs != -1 && |
3741 function->nargs != args->length()) { | 3745 function->nargs != args->length()) { |
3742 ReportMessage("illegal_access"); | 3746 ReportMessage("illegal_access"); |
3743 *ok = false; | 3747 *ok = false; |
3744 return NULL; | 3748 return NULL; |
3745 } | 3749 } |
3746 | 3750 |
3747 // Check that the function is defined if it's an inline runtime call. | 3751 // Check that the function is defined if it's an inline runtime call. |
3748 if (function == NULL && name->Get(0) == '_') { | 3752 if (function == NULL && name->raw_data()[0] == '_') { |
3749 ParserTraits::ReportMessage("not_defined", name); | 3753 ParserTraits::ReportMessage("not_defined", name); |
3750 *ok = false; | 3754 *ok = false; |
3751 return NULL; | 3755 return NULL; |
3752 } | 3756 } |
3753 | 3757 |
3754 // We have a valid intrinsics call or a call to a builtin. | 3758 // We have a valid intrinsics call or a call to a builtin. |
3755 return factory()->NewCallRuntime(name, function, args, pos); | 3759 return factory()->NewCallRuntime(name, function, args, pos); |
3756 } | 3760 } |
3757 | 3761 |
3758 | 3762 |
3759 Literal* Parser::GetLiteralUndefined(int position) { | 3763 Literal* Parser::GetLiteralUndefined(int position) { |
3760 return factory()->NewLiteral( | 3764 return factory()->NewLiteral(string_table_->NewValue(AstValue::UNDEFINED), |
3761 isolate()->factory()->undefined_value(), position); | 3765 position); |
3762 } | 3766 } |
3763 | 3767 |
3764 | 3768 |
3765 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 3769 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
3766 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 3770 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
3767 if (decl != NULL) { | 3771 if (decl != NULL) { |
3768 // In harmony mode we treat conflicting variable bindinds as early | 3772 // In harmony mode we treat conflicting variable bindinds as early |
3769 // errors. See ES5 16 for a definition of early errors. | 3773 // errors. See ES5 16 for a definition of early errors. |
3770 Handle<String> name = decl->proxy()->name(); | 3774 const AstString* name = decl->proxy()->raw_name(); |
3771 int position = decl->proxy()->position(); | 3775 int position = decl->proxy()->position(); |
3772 Scanner::Location location = position == RelocInfo::kNoPosition | 3776 Scanner::Location location = position == RelocInfo::kNoPosition |
3773 ? Scanner::Location::invalid() | 3777 ? Scanner::Location::invalid() |
3774 : Scanner::Location(position, position + 1); | 3778 : Scanner::Location(position, position + 1); |
3775 ParserTraits::ReportMessageAt(location, "var_redeclaration", name); | 3779 ParserTraits::ReportMessageAt(location, "var_redeclaration", name); |
3776 *ok = false; | 3780 *ok = false; |
3777 } | 3781 } |
3778 } | 3782 } |
3779 | 3783 |
3780 | 3784 |
3781 // ---------------------------------------------------------------------------- | 3785 // ---------------------------------------------------------------------------- |
3782 // Parser support | 3786 // Parser support |
3783 | 3787 |
3784 | 3788 |
3785 bool Parser::TargetStackContainsLabel(Handle<String> label) { | 3789 bool Parser::TargetStackContainsLabel(const AstString* label) { |
3786 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 3790 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
3787 BreakableStatement* stat = t->node()->AsBreakableStatement(); | 3791 BreakableStatement* stat = t->node()->AsBreakableStatement(); |
3788 if (stat != NULL && ContainsLabel(stat->labels(), label)) | 3792 if (stat != NULL && ContainsLabel(stat->labels(), label)) |
3789 return true; | 3793 return true; |
3790 } | 3794 } |
3791 return false; | 3795 return false; |
3792 } | 3796 } |
3793 | 3797 |
3794 | 3798 |
3795 BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) { | 3799 BreakableStatement* Parser::LookupBreakTarget(const AstString* label, |
3796 bool anonymous = label.is_null(); | 3800 bool* ok) { |
| 3801 bool anonymous = label == NULL; |
3797 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 3802 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
3798 BreakableStatement* stat = t->node()->AsBreakableStatement(); | 3803 BreakableStatement* stat = t->node()->AsBreakableStatement(); |
3799 if (stat == NULL) continue; | 3804 if (stat == NULL) continue; |
3800 if ((anonymous && stat->is_target_for_anonymous()) || | 3805 if ((anonymous && stat->is_target_for_anonymous()) || |
3801 (!anonymous && ContainsLabel(stat->labels(), label))) { | 3806 (!anonymous && ContainsLabel(stat->labels(), label))) { |
3802 RegisterTargetUse(stat->break_target(), t->previous()); | 3807 RegisterTargetUse(stat->break_target(), t->previous()); |
3803 return stat; | 3808 return stat; |
3804 } | 3809 } |
3805 } | 3810 } |
3806 return NULL; | 3811 return NULL; |
3807 } | 3812 } |
3808 | 3813 |
3809 | 3814 |
3810 IterationStatement* Parser::LookupContinueTarget(Handle<String> label, | 3815 IterationStatement* Parser::LookupContinueTarget(const AstString* label, |
3811 bool* ok) { | 3816 bool* ok) { |
3812 bool anonymous = label.is_null(); | 3817 bool anonymous = label == NULL; |
3813 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 3818 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
3814 IterationStatement* stat = t->node()->AsIterationStatement(); | 3819 IterationStatement* stat = t->node()->AsIterationStatement(); |
3815 if (stat == NULL) continue; | 3820 if (stat == NULL) continue; |
3816 | 3821 |
3817 ASSERT(stat->is_target_for_anonymous()); | 3822 ASSERT(stat->is_target_for_anonymous()); |
3818 if (anonymous || ContainsLabel(stat->labels(), label)) { | 3823 if (anonymous || ContainsLabel(stat->labels(), label)) { |
3819 RegisterTargetUse(stat->continue_target(), t->previous()); | 3824 RegisterTargetUse(stat->continue_target(), t->previous()); |
3820 return stat; | 3825 return stat; |
3821 } | 3826 } |
3822 } | 3827 } |
(...skipping 12 matching lines...) Expand all Loading... |
3835 } | 3840 } |
3836 | 3841 |
3837 | 3842 |
3838 void Parser::ThrowPendingError() { | 3843 void Parser::ThrowPendingError() { |
3839 if (has_pending_error_) { | 3844 if (has_pending_error_) { |
3840 MessageLocation location(script_, | 3845 MessageLocation location(script_, |
3841 pending_error_location_.beg_pos, | 3846 pending_error_location_.beg_pos, |
3842 pending_error_location_.end_pos); | 3847 pending_error_location_.end_pos); |
3843 Factory* factory = isolate()->factory(); | 3848 Factory* factory = isolate()->factory(); |
3844 bool has_arg = | 3849 bool has_arg = |
3845 !pending_error_arg_.is_null() || pending_error_char_arg_ != NULL; | 3850 pending_error_arg_ != NULL || pending_error_char_arg_ != NULL; |
3846 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0); | 3851 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0); |
3847 if (!pending_error_arg_.is_null()) { | 3852 if (pending_error_arg_ != NULL) { |
3848 elements->set(0, *(pending_error_arg_.ToHandleChecked())); | 3853 Handle<String> arg_string = pending_error_arg_->string(); |
| 3854 elements->set(0, *arg_string); |
3849 } else if (pending_error_char_arg_ != NULL) { | 3855 } else if (pending_error_char_arg_ != NULL) { |
3850 Handle<String> arg_string = | 3856 Handle<String> arg_string = |
3851 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_)) | 3857 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_)) |
3852 .ToHandleChecked(); | 3858 .ToHandleChecked(); |
3853 elements->set(0, *arg_string); | 3859 elements->set(0, *arg_string); |
3854 } | 3860 } |
3855 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | 3861 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
3856 Handle<Object> result = pending_error_is_reference_error_ | 3862 Handle<Object> result = pending_error_is_reference_error_ |
3857 ? factory->NewReferenceError(pending_error_message_, array) | 3863 ? factory->NewReferenceError(pending_error_message_, array) |
3858 : factory->NewSyntaxError(pending_error_message_, array); | 3864 : factory->NewSyntaxError(pending_error_message_, array); |
(...skipping 892 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4751 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; | 4757 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; |
4752 result->contains_anchor = parser.contains_anchor(); | 4758 result->contains_anchor = parser.contains_anchor(); |
4753 result->capture_count = capture_count; | 4759 result->capture_count = capture_count; |
4754 } | 4760 } |
4755 return !parser.failed(); | 4761 return !parser.failed(); |
4756 } | 4762 } |
4757 | 4763 |
4758 | 4764 |
4759 bool Parser::Parse() { | 4765 bool Parser::Parse() { |
4760 ASSERT(info()->function() == NULL); | 4766 ASSERT(info()->function() == NULL); |
| 4767 ASSERT(info()->string_table() == NULL); |
4761 FunctionLiteral* result = NULL; | 4768 FunctionLiteral* result = NULL; |
| 4769 string_table_ = new AstStringTable(zone()); |
| 4770 if (allow_natives_syntax() || extension_ != NULL) { |
| 4771 // If intrinsics are allowed, the Parser cannot operate independent of the |
| 4772 // V8 heap because of Rumtime. Tell the string table to internalize strings |
| 4773 // and values right after they're created. |
| 4774 string_table_->Internalize(isolate()); |
| 4775 } |
| 4776 |
4762 if (info()->is_lazy()) { | 4777 if (info()->is_lazy()) { |
4763 ASSERT(!info()->is_eval()); | 4778 ASSERT(!info()->is_eval()); |
4764 if (info()->shared_info()->is_function()) { | 4779 if (info()->shared_info()->is_function()) { |
4765 result = ParseLazy(); | 4780 result = ParseLazy(); |
4766 } else { | 4781 } else { |
4767 result = ParseProgram(); | 4782 result = ParseProgram(); |
4768 } | 4783 } |
4769 } else { | 4784 } else { |
4770 SetCachedData(info()->cached_data(), info()->cached_data_mode()); | 4785 SetCachedData(info()->cached_data(), info()->cached_data_mode()); |
4771 if (info()->cached_data_mode() == CONSUME_CACHED_DATA && | 4786 if (info()->cached_data_mode() == CONSUME_CACHED_DATA && |
4772 (*info()->cached_data())->has_error()) { | 4787 (*info()->cached_data())->has_error()) { |
4773 ScriptData* cached_data = *(info()->cached_data()); | 4788 ScriptData* cached_data = *(info()->cached_data()); |
4774 Scanner::Location loc = cached_data->MessageLocation(); | 4789 Scanner::Location loc = cached_data->MessageLocation(); |
4775 const char* message = cached_data->BuildMessage(); | 4790 const char* message = cached_data->BuildMessage(); |
4776 const char* arg = cached_data->BuildArg(); | 4791 const char* arg = cached_data->BuildArg(); |
4777 ParserTraits::ReportMessageAt(loc, message, arg, | 4792 ParserTraits::ReportMessageAt(loc, message, arg, |
4778 cached_data->IsReferenceError()); | 4793 cached_data->IsReferenceError()); |
4779 DeleteArray(message); | 4794 DeleteArray(message); |
4780 DeleteArray(arg); | 4795 DeleteArray(arg); |
4781 ASSERT(info()->isolate()->has_pending_exception()); | 4796 ASSERT(info()->isolate()->has_pending_exception()); |
4782 } else { | 4797 } else { |
4783 result = ParseProgram(); | 4798 result = ParseProgram(); |
4784 } | 4799 } |
4785 } | 4800 } |
4786 info()->SetFunction(result); | 4801 info()->SetFunction(result); |
| 4802 string_table_->Internalize(isolate()); |
| 4803 // info takes ownership of string_table_. |
| 4804 info()->SetStringTable(string_table_); |
| 4805 string_table_ = NULL; |
4787 return (result != NULL); | 4806 return (result != NULL); |
4788 } | 4807 } |
4789 | 4808 |
4790 } } // namespace v8::internal | 4809 } } // namespace v8::internal |
OLD | NEW |