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 "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast.h" | 8 #include "src/ast.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/char-predicates-inl.h" | 10 #include "src/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(ast_value_factory_); |
| 330 Scope* result = |
| 331 new (zone()) Scope(parent, scope_type, ast_value_factory_, zone()); |
330 result->Initialize(); | 332 result->Initialize(); |
331 return result; | 333 return result; |
332 } | 334 } |
333 | 335 |
334 | 336 |
335 // ---------------------------------------------------------------------------- | 337 // ---------------------------------------------------------------------------- |
336 // Target is a support class to facilitate manipulation of the | 338 // Target is a support class to facilitate manipulation of the |
337 // Parser's target_stack_ (the stack of potential 'break' and | 339 // Parser's target_stack_ (the stack of potential 'break' and |
338 // 'continue' statement targets). Upon construction, a new target is | 340 // 'continue' statement targets). Upon construction, a new target is |
339 // added; it is removed upon destruction. | 341 // added; it is removed upon destruction. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 | 394 |
393 #define CHECK_FAILED /**/); \ | 395 #define CHECK_FAILED /**/); \ |
394 if (failed_) return NULL; \ | 396 if (failed_) return NULL; \ |
395 ((void)0 | 397 ((void)0 |
396 #define DUMMY ) // to make indentation work | 398 #define DUMMY ) // to make indentation work |
397 #undef DUMMY | 399 #undef DUMMY |
398 | 400 |
399 // ---------------------------------------------------------------------------- | 401 // ---------------------------------------------------------------------------- |
400 // Implementation of Parser | 402 // Implementation of Parser |
401 | 403 |
402 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { | 404 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const { |
403 Factory* factory = parser_->isolate()->factory(); | 405 return identifier == parser_->ast_value_factory_->eval_string() || |
404 return identifier.is_identical_to(factory->eval_string()) | 406 identifier == parser_->ast_value_factory_->arguments_string(); |
405 || identifier.is_identical_to(factory->arguments_string()); | |
406 } | 407 } |
407 | 408 |
408 | 409 |
409 bool ParserTraits::IsThisProperty(Expression* expression) { | 410 bool ParserTraits::IsThisProperty(Expression* expression) { |
410 ASSERT(expression != NULL); | 411 ASSERT(expression != NULL); |
411 Property* property = expression->AsProperty(); | 412 Property* property = expression->AsProperty(); |
412 return property != NULL && | 413 return property != NULL && |
413 property->obj()->AsVariableProxy() != NULL && | 414 property->obj()->AsVariableProxy() != NULL && |
414 property->obj()->AsVariableProxy()->is_this(); | 415 property->obj()->AsVariableProxy()->is_this(); |
415 } | 416 } |
416 | 417 |
417 | 418 |
418 bool ParserTraits::IsIdentifier(Expression* expression) { | 419 bool ParserTraits::IsIdentifier(Expression* expression) { |
419 VariableProxy* operand = expression->AsVariableProxy(); | 420 VariableProxy* operand = expression->AsVariableProxy(); |
420 return operand != NULL && !operand->is_this(); | 421 return operand != NULL && !operand->is_this(); |
421 } | 422 } |
422 | 423 |
423 | 424 |
424 void ParserTraits::PushPropertyName(FuncNameInferrer* fni, | 425 void ParserTraits::PushPropertyName(FuncNameInferrer* fni, |
425 Expression* expression) { | 426 Expression* expression) { |
426 if (expression->IsPropertyName()) { | 427 if (expression->IsPropertyName()) { |
427 fni->PushLiteralName(expression->AsLiteral()->AsPropertyName()); | 428 fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName()); |
428 } else { | 429 } else { |
429 fni->PushLiteralName( | 430 fni->PushLiteralName( |
430 parser_->isolate()->factory()->anonymous_function_string()); | 431 parser_->ast_value_factory_->anonymous_function_string()); |
431 } | 432 } |
432 } | 433 } |
433 | 434 |
434 | 435 |
435 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, | 436 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, |
436 Expression* right) { | 437 Expression* right) { |
437 ASSERT(left != NULL); | 438 ASSERT(left != NULL); |
438 if (left->AsProperty() != NULL && | 439 if (left->AsProperty() != NULL && |
439 right->AsFunctionLiteral() != NULL) { | 440 right->AsFunctionLiteral() != NULL) { |
440 right->AsFunctionLiteral()->set_pretenure(); | 441 right->AsFunctionLiteral()->set_pretenure(); |
441 } | 442 } |
442 } | 443 } |
443 | 444 |
444 | 445 |
445 void ParserTraits::CheckPossibleEvalCall(Expression* expression, | 446 void ParserTraits::CheckPossibleEvalCall(Expression* expression, |
446 Scope* scope) { | 447 Scope* scope) { |
447 VariableProxy* callee = expression->AsVariableProxy(); | 448 VariableProxy* callee = expression->AsVariableProxy(); |
448 if (callee != NULL && | 449 if (callee != NULL && |
449 callee->IsVariable(parser_->isolate()->factory()->eval_string())) { | 450 callee->raw_name() == parser_->ast_value_factory_->eval_string()) { |
450 scope->DeclarationScope()->RecordEvalCall(); | 451 scope->DeclarationScope()->RecordEvalCall(); |
451 } | 452 } |
452 } | 453 } |
453 | 454 |
454 | 455 |
455 Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) { | 456 Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) { |
456 VariableProxy* proxy = expression != NULL | 457 VariableProxy* proxy = expression != NULL |
457 ? expression->AsVariableProxy() | 458 ? expression->AsVariableProxy() |
458 : NULL; | 459 : NULL; |
459 if (proxy != NULL) proxy->MarkAsLValue(); | 460 if (proxy != NULL) proxy->MarkAsLValue(); |
460 return expression; | 461 return expression; |
461 } | 462 } |
462 | 463 |
463 | 464 |
464 bool ParserTraits::ShortcutNumericLiteralBinaryExpression( | 465 bool ParserTraits::ShortcutNumericLiteralBinaryExpression( |
465 Expression** x, Expression* y, Token::Value op, int pos, | 466 Expression** x, Expression* y, Token::Value op, int pos, |
466 AstNodeFactory<AstConstructionVisitor>* factory) { | 467 AstNodeFactory<AstConstructionVisitor>* factory) { |
467 if ((*x)->AsLiteral() && (*x)->AsLiteral()->value()->IsNumber() && | 468 if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() && |
468 y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) { | 469 y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) { |
469 double x_val = (*x)->AsLiteral()->value()->Number(); | 470 double x_val = (*x)->AsLiteral()->raw_value()->AsNumber(); |
470 double y_val = y->AsLiteral()->value()->Number(); | 471 double y_val = y->AsLiteral()->raw_value()->AsNumber(); |
471 switch (op) { | 472 switch (op) { |
472 case Token::ADD: | 473 case Token::ADD: |
473 *x = factory->NewNumberLiteral(x_val + y_val, pos); | 474 *x = factory->NewNumberLiteral(x_val + y_val, pos); |
474 return true; | 475 return true; |
475 case Token::SUB: | 476 case Token::SUB: |
476 *x = factory->NewNumberLiteral(x_val - y_val, pos); | 477 *x = factory->NewNumberLiteral(x_val - y_val, pos); |
477 return true; | 478 return true; |
478 case Token::MUL: | 479 case Token::MUL: |
479 *x = factory->NewNumberLiteral(x_val * y_val, pos); | 480 *x = factory->NewNumberLiteral(x_val * y_val, pos); |
480 return true; | 481 return true; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 } | 520 } |
520 return false; | 521 return false; |
521 } | 522 } |
522 | 523 |
523 | 524 |
524 Expression* ParserTraits::BuildUnaryExpression( | 525 Expression* ParserTraits::BuildUnaryExpression( |
525 Expression* expression, Token::Value op, int pos, | 526 Expression* expression, Token::Value op, int pos, |
526 AstNodeFactory<AstConstructionVisitor>* factory) { | 527 AstNodeFactory<AstConstructionVisitor>* factory) { |
527 ASSERT(expression != NULL); | 528 ASSERT(expression != NULL); |
528 if (expression->IsLiteral()) { | 529 if (expression->IsLiteral()) { |
529 Handle<Object> literal = expression->AsLiteral()->value(); | 530 const AstValue* literal = expression->AsLiteral()->raw_value(); |
530 if (op == Token::NOT) { | 531 if (op == Token::NOT) { |
531 // Convert the literal to a boolean condition and negate it. | 532 // Convert the literal to a boolean condition and negate it. |
532 bool condition = literal->BooleanValue(); | 533 bool condition = literal->BooleanValue(); |
533 Handle<Object> result = | 534 return factory->NewBooleanLiteral(!condition, pos); |
534 parser_->isolate()->factory()->ToBoolean(!condition); | |
535 return factory->NewLiteral(result, pos); | |
536 } else if (literal->IsNumber()) { | 535 } else if (literal->IsNumber()) { |
537 // Compute some expressions involving only number literals. | 536 // Compute some expressions involving only number literals. |
538 double value = literal->Number(); | 537 double value = literal->AsNumber(); |
539 switch (op) { | 538 switch (op) { |
540 case Token::ADD: | 539 case Token::ADD: |
541 return expression; | 540 return expression; |
542 case Token::SUB: | 541 case Token::SUB: |
543 return factory->NewNumberLiteral(-value, pos); | 542 return factory->NewNumberLiteral(-value, pos); |
544 case Token::BIT_NOT: | 543 case Token::BIT_NOT: |
545 return factory->NewNumberLiteral(~DoubleToInt32(value), pos); | 544 return factory->NewNumberLiteral(~DoubleToInt32(value), pos); |
546 default: | 545 default: |
547 break; | 546 break; |
548 } | 547 } |
(...skipping 13 matching lines...) Expand all Loading... |
562 if (op == Token::BIT_NOT) { | 561 if (op == Token::BIT_NOT) { |
563 return factory->NewBinaryOperation( | 562 return factory->NewBinaryOperation( |
564 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); | 563 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); |
565 } | 564 } |
566 return factory->NewUnaryOperation(op, expression, pos); | 565 return factory->NewUnaryOperation(op, expression, pos); |
567 } | 566 } |
568 | 567 |
569 | 568 |
570 Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) { | 569 Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) { |
571 return NewThrowError( | 570 return NewThrowError( |
572 parser_->isolate()->factory()->MakeReferenceError_string(), | 571 parser_->ast_value_factory_->make_reference_error_string(), message, NULL, |
573 message, HandleVector<Object>(NULL, 0), pos); | 572 pos); |
574 } | 573 } |
575 | 574 |
576 | 575 |
577 Expression* ParserTraits::NewThrowSyntaxError( | 576 Expression* ParserTraits::NewThrowSyntaxError( |
578 const char* message, Handle<Object> arg, int pos) { | 577 const char* message, const AstRawString* arg, int pos) { |
579 int argc = arg.is_null() ? 0 : 1; | 578 return NewThrowError(parser_->ast_value_factory_->make_syntax_error_string(), |
580 Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc); | 579 message, arg, pos); |
581 return NewThrowError( | |
582 parser_->isolate()->factory()->MakeSyntaxError_string(), | |
583 message, arguments, pos); | |
584 } | 580 } |
585 | 581 |
586 | 582 |
587 Expression* ParserTraits::NewThrowTypeError( | 583 Expression* ParserTraits::NewThrowTypeError( |
588 const char* message, Handle<Object> arg, int pos) { | 584 const char* message, const AstRawString* arg, int pos) { |
589 int argc = arg.is_null() ? 0 : 1; | 585 return NewThrowError(parser_->ast_value_factory_->make_type_error_string(), |
590 Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc); | 586 message, arg, pos); |
591 return NewThrowError( | |
592 parser_->isolate()->factory()->MakeTypeError_string(), | |
593 message, arguments, pos); | |
594 } | 587 } |
595 | 588 |
596 | 589 |
597 Expression* ParserTraits::NewThrowError( | 590 Expression* ParserTraits::NewThrowError( |
598 Handle<String> constructor, const char* message, | 591 const AstRawString* constructor, const char* message, |
599 Vector<Handle<Object> > arguments, int pos) { | 592 const AstRawString* arg, int pos) { |
600 Zone* zone = parser_->zone(); | 593 Zone* zone = parser_->zone(); |
601 Factory* factory = parser_->isolate()->factory(); | 594 int argc = arg != NULL ? 1 : 0; |
602 int argc = arguments.length(); | 595 const AstRawString* type = |
603 Handle<FixedArray> elements = factory->NewFixedArray(argc, TENURED); | 596 parser_->ast_value_factory_->GetOneByteString(Vector<const uint8_t>( |
604 for (int i = 0; i < argc; i++) { | 597 reinterpret_cast<const uint8_t*>(message), StrLength(message))); |
605 Handle<Object> element = arguments[i]; | 598 ZoneList<const AstRawString*>* array = |
606 if (!element.is_null()) { | 599 new (zone) ZoneList<const AstRawString*>(argc, zone); |
607 elements->set(i, *element); | 600 if (arg != NULL) { |
608 } | 601 array->Add(arg, zone); |
609 } | 602 } |
610 Handle<JSArray> array = | 603 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone); |
611 factory->NewJSArrayWithElements(elements, FAST_ELEMENTS, TENURED); | 604 args->Add(parser_->factory()->NewStringLiteral(type, pos), zone); |
612 | 605 args->Add(parser_->factory()->NewStringListLiteral(array, pos), zone); |
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); | |
616 args->Add(parser_->factory()->NewLiteral(array, pos), zone); | |
617 CallRuntime* call_constructor = | 606 CallRuntime* call_constructor = |
618 parser_->factory()->NewCallRuntime(constructor, NULL, args, pos); | 607 parser_->factory()->NewCallRuntime(constructor, NULL, args, pos); |
619 return parser_->factory()->NewThrow(call_constructor, pos); | 608 return parser_->factory()->NewThrow(call_constructor, pos); |
620 } | 609 } |
621 | 610 |
622 | 611 |
623 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 612 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
624 const char* message, | 613 const char* message, |
625 const char* arg, | 614 const char* arg, |
626 bool is_reference_error) { | 615 bool is_reference_error) { |
627 if (parser_->stack_overflow()) { | 616 if (parser_->stack_overflow()) { |
628 // Suppress the error message (syntax error or such) in the presence of a | 617 // 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 | 618 // stack overflow. The isolate allows only one pending exception at at time |
630 // and we want to report the stack overflow later. | 619 // and we want to report the stack overflow later. |
631 return; | 620 return; |
632 } | 621 } |
633 parser_->has_pending_error_ = true; | 622 parser_->has_pending_error_ = true; |
634 parser_->pending_error_location_ = source_location; | 623 parser_->pending_error_location_ = source_location; |
635 parser_->pending_error_message_ = message; | 624 parser_->pending_error_message_ = message; |
636 parser_->pending_error_char_arg_ = arg; | 625 parser_->pending_error_char_arg_ = arg; |
637 parser_->pending_error_arg_ = Handle<String>(); | 626 parser_->pending_error_arg_ = NULL; |
638 parser_->pending_error_is_reference_error_ = is_reference_error; | 627 parser_->pending_error_is_reference_error_ = is_reference_error; |
639 } | 628 } |
640 | 629 |
641 | 630 |
642 void ParserTraits::ReportMessage(const char* message, | 631 void ParserTraits::ReportMessage(const char* message, |
643 MaybeHandle<String> arg, | 632 const char* arg, |
644 bool is_reference_error) { | 633 bool is_reference_error) { |
645 Scanner::Location source_location = parser_->scanner()->location(); | 634 Scanner::Location source_location = parser_->scanner()->location(); |
646 ReportMessageAt(source_location, message, arg, is_reference_error); | 635 ReportMessageAt(source_location, message, arg, is_reference_error); |
| 636 } |
| 637 |
| 638 |
| 639 void ParserTraits::ReportMessage(const char* message, |
| 640 const AstRawString* arg, |
| 641 bool is_reference_error) { |
| 642 Scanner::Location source_location = parser_->scanner()->location(); |
| 643 ReportMessageAt(source_location, message, arg, is_reference_error); |
647 } | 644 } |
648 | 645 |
649 | 646 |
650 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 647 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
651 const char* message, | 648 const char* message, |
652 MaybeHandle<String> arg, | 649 const AstRawString* arg, |
653 bool is_reference_error) { | 650 bool is_reference_error) { |
654 if (parser_->stack_overflow()) { | 651 if (parser_->stack_overflow()) { |
655 // Suppress the error message (syntax error or such) in the presence of a | 652 // 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 | 653 // stack overflow. The isolate allows only one pending exception at at time |
657 // and we want to report the stack overflow later. | 654 // and we want to report the stack overflow later. |
658 return; | 655 return; |
659 } | 656 } |
660 parser_->has_pending_error_ = true; | 657 parser_->has_pending_error_ = true; |
661 parser_->pending_error_location_ = source_location; | 658 parser_->pending_error_location_ = source_location; |
662 parser_->pending_error_message_ = message; | 659 parser_->pending_error_message_ = message; |
663 parser_->pending_error_char_arg_ = NULL; | 660 parser_->pending_error_char_arg_ = NULL; |
664 parser_->pending_error_arg_ = arg; | 661 parser_->pending_error_arg_ = arg; |
665 parser_->pending_error_is_reference_error_ = is_reference_error; | 662 parser_->pending_error_is_reference_error_ = is_reference_error; |
666 } | 663 } |
667 | 664 |
668 | 665 |
669 Handle<String> ParserTraits::GetSymbol(Scanner* scanner) { | 666 const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) { |
670 Handle<String> result = | 667 const AstRawString* result = |
671 parser_->scanner()->AllocateInternalizedString(parser_->isolate()); | 668 parser_->scanner()->CurrentSymbol(parser_->ast_value_factory_); |
672 ASSERT(!result.is_null()); | 669 ASSERT(result != NULL); |
673 return result; | 670 return result; |
674 } | 671 } |
675 | 672 |
676 | 673 |
677 Handle<String> ParserTraits::NextLiteralString(Scanner* scanner, | 674 const AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) { |
678 PretenureFlag tenured) { | 675 return parser_->scanner()->NextSymbol(parser_->ast_value_factory_); |
679 return scanner->AllocateNextLiteralString(parser_->isolate(), tenured); | |
680 } | 676 } |
681 | 677 |
682 | 678 |
683 Expression* ParserTraits::ThisExpression( | 679 Expression* ParserTraits::ThisExpression( |
684 Scope* scope, | 680 Scope* scope, |
685 AstNodeFactory<AstConstructionVisitor>* factory) { | 681 AstNodeFactory<AstConstructionVisitor>* factory) { |
686 return factory->NewVariableProxy(scope->receiver()); | 682 return factory->NewVariableProxy(scope->receiver()); |
687 } | 683 } |
688 | 684 |
689 | 685 |
690 Literal* ParserTraits::ExpressionFromLiteral( | 686 Literal* ParserTraits::ExpressionFromLiteral( |
691 Token::Value token, int pos, | 687 Token::Value token, int pos, |
692 Scanner* scanner, | 688 Scanner* scanner, |
693 AstNodeFactory<AstConstructionVisitor>* factory) { | 689 AstNodeFactory<AstConstructionVisitor>* factory) { |
694 Factory* isolate_factory = parser_->isolate()->factory(); | |
695 switch (token) { | 690 switch (token) { |
696 case Token::NULL_LITERAL: | 691 case Token::NULL_LITERAL: |
697 return factory->NewLiteral(isolate_factory->null_value(), pos); | 692 return factory->NewNullLiteral(pos); |
698 case Token::TRUE_LITERAL: | 693 case Token::TRUE_LITERAL: |
699 return factory->NewLiteral(isolate_factory->true_value(), pos); | 694 return factory->NewBooleanLiteral(true, pos); |
700 case Token::FALSE_LITERAL: | 695 case Token::FALSE_LITERAL: |
701 return factory->NewLiteral(isolate_factory->false_value(), pos); | 696 return factory->NewBooleanLiteral(false, pos); |
702 case Token::NUMBER: { | 697 case Token::NUMBER: { |
703 double value = scanner->DoubleValue(); | 698 double value = scanner->DoubleValue(); |
704 return factory->NewNumberLiteral(value, pos); | 699 return factory->NewNumberLiteral(value, pos); |
705 } | 700 } |
706 default: | 701 default: |
707 ASSERT(false); | 702 ASSERT(false); |
708 } | 703 } |
709 return NULL; | 704 return NULL; |
710 } | 705 } |
711 | 706 |
712 | 707 |
713 Expression* ParserTraits::ExpressionFromIdentifier( | 708 Expression* ParserTraits::ExpressionFromIdentifier( |
714 Handle<String> name, int pos, Scope* scope, | 709 const AstRawString* name, int pos, Scope* scope, |
715 AstNodeFactory<AstConstructionVisitor>* factory) { | 710 AstNodeFactory<AstConstructionVisitor>* factory) { |
716 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); | 711 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); |
717 // The name may refer to a module instance object, so its type is unknown. | 712 // The name may refer to a module instance object, so its type is unknown. |
718 #ifdef DEBUG | 713 #ifdef DEBUG |
719 if (FLAG_print_interface_details) | 714 if (FLAG_print_interface_details) |
720 PrintF("# Variable %s ", name->ToAsciiArray()); | 715 PrintF("# Variable %.*s ", name->length(), name->raw_data()); |
721 #endif | 716 #endif |
722 Interface* interface = Interface::NewUnknown(parser_->zone()); | 717 Interface* interface = Interface::NewUnknown(parser_->zone()); |
723 return scope->NewUnresolved(factory, name, interface, pos); | 718 return scope->NewUnresolved(factory, name, interface, pos); |
724 } | 719 } |
725 | 720 |
726 | 721 |
727 Expression* ParserTraits::ExpressionFromString( | 722 Expression* ParserTraits::ExpressionFromString( |
728 int pos, Scanner* scanner, | 723 int pos, Scanner* scanner, |
729 AstNodeFactory<AstConstructionVisitor>* factory) { | 724 AstNodeFactory<AstConstructionVisitor>* factory) { |
730 Handle<String> symbol = GetSymbol(scanner); | 725 const AstRawString* symbol = GetSymbol(scanner); |
731 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); | 726 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); |
732 return factory->NewLiteral(symbol, pos); | 727 return factory->NewStringLiteral(symbol, pos); |
733 } | 728 } |
734 | 729 |
735 | 730 |
736 Literal* ParserTraits::GetLiteralTheHole( | 731 Literal* ParserTraits::GetLiteralTheHole( |
737 int position, AstNodeFactory<AstConstructionVisitor>* factory) { | 732 int position, AstNodeFactory<AstConstructionVisitor>* factory) { |
738 return factory->NewLiteral(parser_->isolate()->factory()->the_hole_value(), | 733 return factory->NewTheHoleLiteral(RelocInfo::kNoPosition); |
739 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 AstRawString* 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 FunctionLiteral::ArityRestriction arity_restriction, | 749 FunctionLiteral::ArityRestriction arity_restriction, |
756 bool* ok) { | 750 bool* ok) { |
757 return parser_->ParseFunctionLiteral(name, function_name_location, | 751 return parser_->ParseFunctionLiteral(name, function_name_location, |
758 name_is_strict_reserved, is_generator, | 752 name_is_strict_reserved, is_generator, |
759 function_token_position, type, | 753 function_token_position, type, |
760 arity_restriction, ok); | 754 arity_restriction, ok); |
761 } | 755 } |
762 | 756 |
763 | 757 |
764 Parser::Parser(CompilationInfo* info) | 758 Parser::Parser(CompilationInfo* info) |
765 : ParserBase<ParserTraits>(&scanner_, | 759 : ParserBase<ParserTraits>(&scanner_, |
766 info->isolate()->stack_guard()->real_climit(), | 760 info->isolate()->stack_guard()->real_climit(), |
767 info->extension(), | 761 info->extension(), |
768 NULL, | 762 NULL, |
769 info->zone(), | 763 info->zone(), |
770 this), | 764 this), |
771 isolate_(info->isolate()), | 765 isolate_(info->isolate()), |
772 script_(info->script()), | 766 script_(info->script()), |
773 scanner_(isolate_->unicode_cache()), | 767 scanner_(isolate_->unicode_cache()), |
774 reusable_preparser_(NULL), | 768 reusable_preparser_(NULL), |
775 original_scope_(NULL), | 769 original_scope_(NULL), |
776 target_stack_(NULL), | 770 target_stack_(NULL), |
777 cached_data_(NULL), | 771 cached_data_(NULL), |
778 cached_data_mode_(NO_CACHED_DATA), | 772 cached_data_mode_(NO_CACHED_DATA), |
| 773 ast_value_factory_(NULL), |
779 info_(info), | 774 info_(info), |
780 has_pending_error_(false), | 775 has_pending_error_(false), |
781 pending_error_message_(NULL), | 776 pending_error_message_(NULL), |
| 777 pending_error_arg_(NULL), |
782 pending_error_char_arg_(NULL) { | 778 pending_error_char_arg_(NULL) { |
783 ASSERT(!script_.is_null()); | 779 ASSERT(!script_.is_null()); |
784 isolate_->set_ast_node_id(0); | 780 isolate_->set_ast_node_id(0); |
785 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 781 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
786 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 782 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
787 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 783 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
788 set_allow_lazy(false); // Must be explicitly enabled. | 784 set_allow_lazy(false); // Must be explicitly enabled. |
789 set_allow_generators(FLAG_harmony_generators); | 785 set_allow_generators(FLAG_harmony_generators); |
790 set_allow_for_of(FLAG_harmony_iteration); | 786 set_allow_for_of(FLAG_harmony_iteration); |
791 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 787 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
792 } | 788 } |
793 | 789 |
794 | 790 |
795 FunctionLiteral* Parser::ParseProgram() { | 791 FunctionLiteral* Parser::ParseProgram() { |
796 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, | 792 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
797 // see comment for HistogramTimerScope class. | 793 // see comment for HistogramTimerScope class. |
798 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); | 794 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); |
799 Handle<String> source(String::cast(script_->source())); | 795 Handle<String> source(String::cast(script_->source())); |
800 isolate()->counters()->total_parse_size()->Increment(source->length()); | 796 isolate()->counters()->total_parse_size()->Increment(source->length()); |
801 ElapsedTimer timer; | 797 ElapsedTimer timer; |
802 if (FLAG_trace_parse) { | 798 if (FLAG_trace_parse) { |
803 timer.Start(); | 799 timer.Start(); |
804 } | 800 } |
805 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 801 fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone()); |
806 | 802 |
807 // Initialize parser state. | 803 // Initialize parser state. |
808 CompleteParserRecorder recorder; | 804 CompleteParserRecorder recorder; |
809 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { | 805 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { |
810 log_ = &recorder; | 806 log_ = &recorder; |
811 } else if (cached_data_mode_ == CONSUME_CACHED_DATA) { | 807 } else if (cached_data_mode_ == CONSUME_CACHED_DATA) { |
812 (*cached_data_)->Initialize(); | 808 (*cached_data_)->Initialize(); |
813 } | 809 } |
814 | 810 |
815 source = String::Flatten(source); | 811 source = String::Flatten(source); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
850 } | 846 } |
851 return result; | 847 return result; |
852 } | 848 } |
853 | 849 |
854 | 850 |
855 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, | 851 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
856 Handle<String> source) { | 852 Handle<String> source) { |
857 ASSERT(scope_ == NULL); | 853 ASSERT(scope_ == NULL); |
858 ASSERT(target_stack_ == NULL); | 854 ASSERT(target_stack_ == NULL); |
859 | 855 |
860 Handle<String> no_name = isolate()->factory()->empty_string(); | |
861 | |
862 FunctionLiteral* result = NULL; | 856 FunctionLiteral* result = NULL; |
863 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); | 857 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
864 info->SetGlobalScope(scope); | 858 info->SetGlobalScope(scope); |
865 if (!info->context().is_null()) { | 859 if (!info->context().is_null()) { |
866 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); | 860 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); |
| 861 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this |
| 862 // means the Parser cannot operate independent of the V8 heap. Tell the |
| 863 // string table to internalize strings and values right after they're |
| 864 // created. |
| 865 ast_value_factory_->Internalize(isolate()); |
867 } | 866 } |
868 original_scope_ = scope; | 867 original_scope_ = scope; |
869 if (info->is_eval()) { | 868 if (info->is_eval()) { |
870 if (!scope->is_global_scope() || info->strict_mode() == STRICT) { | 869 if (!scope->is_global_scope() || info->strict_mode() == STRICT) { |
871 scope = NewScope(scope, EVAL_SCOPE); | 870 scope = NewScope(scope, EVAL_SCOPE); |
872 } | 871 } |
873 } else if (info->is_global()) { | 872 } else if (info->is_global()) { |
874 scope = NewScope(scope, GLOBAL_SCOPE); | 873 scope = NewScope(scope, GLOBAL_SCOPE); |
875 } | 874 } |
876 scope->set_start_position(0); | 875 scope->set_start_position(0); |
877 scope->set_end_position(source->length()); | 876 scope->set_end_position(source->length()); |
878 | 877 |
879 // Compute the parsing mode. | 878 // Compute the parsing mode. |
880 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; | 879 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; |
881 if (allow_natives_syntax() || | 880 if (allow_natives_syntax() || |
882 extension_ != NULL || | 881 extension_ != NULL || |
883 scope->is_eval_scope()) { | 882 scope->is_eval_scope()) { |
884 mode = PARSE_EAGERLY; | 883 mode = PARSE_EAGERLY; |
885 } | 884 } |
886 ParsingModeScope parsing_mode(this, mode); | 885 ParsingModeScope parsing_mode(this, mode); |
887 | 886 |
888 // Enters 'scope'. | 887 // Enters 'scope'. |
889 FunctionState function_state(&function_state_, &scope_, scope, zone()); | 888 FunctionState function_state(&function_state_, &scope_, scope, zone(), |
| 889 ast_value_factory_); |
890 | 890 |
891 scope_->SetStrictMode(info->strict_mode()); | 891 scope_->SetStrictMode(info->strict_mode()); |
892 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 892 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
893 bool ok = true; | 893 bool ok = true; |
894 int beg_pos = scanner()->location().beg_pos; | 894 int beg_pos = scanner()->location().beg_pos; |
895 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); | 895 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); |
896 if (ok && strict_mode() == STRICT) { | 896 if (ok && strict_mode() == STRICT) { |
897 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); | 897 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); |
898 } | 898 } |
899 | 899 |
900 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { | 900 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { |
901 CheckConflictingVarDeclarations(scope_, &ok); | 901 CheckConflictingVarDeclarations(scope_, &ok); |
902 } | 902 } |
903 | 903 |
904 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 904 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
905 if (body->length() != 1 || | 905 if (body->length() != 1 || |
906 !body->at(0)->IsExpressionStatement() || | 906 !body->at(0)->IsExpressionStatement() || |
907 !body->at(0)->AsExpressionStatement()-> | 907 !body->at(0)->AsExpressionStatement()-> |
908 expression()->IsFunctionLiteral()) { | 908 expression()->IsFunctionLiteral()) { |
909 ReportMessage("single_function_literal"); | 909 ReportMessage("single_function_literal"); |
910 ok = false; | 910 ok = false; |
911 } | 911 } |
912 } | 912 } |
913 | 913 |
| 914 ast_value_factory_->Internalize(isolate()); |
914 if (ok) { | 915 if (ok) { |
915 result = factory()->NewFunctionLiteral( | 916 result = factory()->NewFunctionLiteral( |
916 no_name, | 917 ast_value_factory_->empty_string(), |
| 918 ast_value_factory_, |
917 scope_, | 919 scope_, |
918 body, | 920 body, |
919 function_state.materialized_literal_count(), | 921 function_state.materialized_literal_count(), |
920 function_state.expected_property_count(), | 922 function_state.expected_property_count(), |
921 function_state.handler_count(), | 923 function_state.handler_count(), |
922 0, | 924 0, |
923 FunctionLiteral::kNoDuplicateParameters, | 925 FunctionLiteral::kNoDuplicateParameters, |
924 FunctionLiteral::ANONYMOUS_EXPRESSION, | 926 FunctionLiteral::ANONYMOUS_EXPRESSION, |
925 FunctionLiteral::kGlobalOrEval, | 927 FunctionLiteral::kGlobalOrEval, |
926 FunctionLiteral::kNotParenthesized, | 928 FunctionLiteral::kNotParenthesized, |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 } | 980 } |
979 | 981 |
980 | 982 |
981 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { | 983 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { |
982 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 984 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); |
983 scanner_.Initialize(source); | 985 scanner_.Initialize(source); |
984 ASSERT(scope_ == NULL); | 986 ASSERT(scope_ == NULL); |
985 ASSERT(target_stack_ == NULL); | 987 ASSERT(target_stack_ == NULL); |
986 | 988 |
987 Handle<String> name(String::cast(shared_info->name())); | 989 Handle<String> name(String::cast(shared_info->name())); |
988 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 990 ASSERT(ast_value_factory_); |
989 fni_->PushEnclosingName(name); | 991 fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone()); |
| 992 const AstRawString* raw_name = ast_value_factory_->GetString(name); |
| 993 fni_->PushEnclosingName(raw_name); |
990 | 994 |
991 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 995 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
992 | 996 |
993 // Place holder for the result. | 997 // Place holder for the result. |
994 FunctionLiteral* result = NULL; | 998 FunctionLiteral* result = NULL; |
995 | 999 |
996 { | 1000 { |
997 // Parse the function literal. | 1001 // Parse the function literal. |
998 Scope* scope = NewScope(scope_, GLOBAL_SCOPE); | 1002 Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
999 info()->SetGlobalScope(scope); | 1003 info()->SetGlobalScope(scope); |
1000 if (!info()->closure().is_null()) { | 1004 if (!info()->closure().is_null()) { |
1001 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, | 1005 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, |
1002 zone()); | 1006 zone()); |
1003 } | 1007 } |
1004 original_scope_ = scope; | 1008 original_scope_ = scope; |
1005 FunctionState function_state(&function_state_, &scope_, scope, zone()); | 1009 FunctionState function_state(&function_state_, &scope_, scope, zone(), |
| 1010 ast_value_factory_); |
1006 ASSERT(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT); | 1011 ASSERT(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT); |
1007 ASSERT(info()->strict_mode() == shared_info->strict_mode()); | 1012 ASSERT(info()->strict_mode() == shared_info->strict_mode()); |
1008 scope->SetStrictMode(shared_info->strict_mode()); | 1013 scope->SetStrictMode(shared_info->strict_mode()); |
1009 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 1014 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
1010 ? (shared_info->is_anonymous() | 1015 ? (shared_info->is_anonymous() |
1011 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 1016 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
1012 : FunctionLiteral::NAMED_EXPRESSION) | 1017 : FunctionLiteral::NAMED_EXPRESSION) |
1013 : FunctionLiteral::DECLARATION; | 1018 : FunctionLiteral::DECLARATION; |
1014 bool ok = true; | 1019 bool ok = true; |
1015 result = ParseFunctionLiteral(name, | 1020 result = ParseFunctionLiteral(raw_name, |
1016 Scanner::Location::invalid(), | 1021 Scanner::Location::invalid(), |
1017 false, // Strict mode name already checked. | 1022 false, // Strict mode name already checked. |
1018 shared_info->is_generator(), | 1023 shared_info->is_generator(), |
1019 RelocInfo::kNoPosition, | 1024 RelocInfo::kNoPosition, |
1020 function_type, | 1025 function_type, |
1021 FunctionLiteral::NORMAL_ARITY, | 1026 FunctionLiteral::NORMAL_ARITY, |
1022 &ok); | 1027 &ok); |
1023 // Make sure the results agree. | 1028 // Make sure the results agree. |
1024 ASSERT(ok == (result != NULL)); | 1029 ASSERT(ok == (result != NULL)); |
1025 } | 1030 } |
1026 | 1031 |
1027 // Make sure the target stack is empty. | 1032 // Make sure the target stack is empty. |
1028 ASSERT(target_stack_ == NULL); | 1033 ASSERT(target_stack_ == NULL); |
1029 | 1034 |
| 1035 ast_value_factory_->Internalize(isolate()); |
1030 if (result == NULL) { | 1036 if (result == NULL) { |
1031 if (stack_overflow()) { | 1037 if (stack_overflow()) { |
1032 isolate()->StackOverflow(); | 1038 isolate()->StackOverflow(); |
1033 } else { | 1039 } else { |
1034 ThrowPendingError(); | 1040 ThrowPendingError(); |
1035 } | 1041 } |
1036 } else { | 1042 } else { |
1037 Handle<String> inferred_name(shared_info->inferred_name()); | 1043 Handle<String> inferred_name(shared_info->inferred_name()); |
1038 result->set_inferred_name(inferred_name); | 1044 result->set_inferred_name(inferred_name); |
1039 } | 1045 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1075 continue; | 1081 continue; |
1076 } | 1082 } |
1077 | 1083 |
1078 if (directive_prologue) { | 1084 if (directive_prologue) { |
1079 // A shot at a directive. | 1085 // A shot at a directive. |
1080 ExpressionStatement* e_stat; | 1086 ExpressionStatement* e_stat; |
1081 Literal* literal; | 1087 Literal* literal; |
1082 // Still processing directive prologue? | 1088 // Still processing directive prologue? |
1083 if ((e_stat = stat->AsExpressionStatement()) != NULL && | 1089 if ((e_stat = stat->AsExpressionStatement()) != NULL && |
1084 (literal = e_stat->expression()->AsLiteral()) != NULL && | 1090 (literal = e_stat->expression()->AsLiteral()) != NULL && |
1085 literal->value()->IsString()) { | 1091 literal->raw_value()->IsString()) { |
1086 Handle<String> directive = Handle<String>::cast(literal->value()); | |
1087 | |
1088 // Check "use strict" directive (ES5 14.1). | 1092 // Check "use strict" directive (ES5 14.1). |
1089 if (strict_mode() == SLOPPY && | 1093 if (strict_mode() == SLOPPY && |
1090 String::Equals(isolate()->factory()->use_strict_string(), | 1094 literal->raw_value()->AsString() == |
1091 directive) && | 1095 ast_value_factory_->use_strict_string() && |
1092 token_loc.end_pos - token_loc.beg_pos == | 1096 token_loc.end_pos - token_loc.beg_pos == 12) { |
1093 isolate()->heap()->use_strict_string()->length() + 2) { | |
1094 // TODO(mstarzinger): Global strict eval calls, need their own scope | 1097 // TODO(mstarzinger): Global strict eval calls, need their own scope |
1095 // as specified in ES5 10.4.2(3). The correct fix would be to always | 1098 // as specified in ES5 10.4.2(3). The correct fix would be to always |
1096 // add this scope in DoParseProgram(), but that requires adaptations | 1099 // add this scope in DoParseProgram(), but that requires adaptations |
1097 // all over the code base, so we go with a quick-fix for now. | 1100 // all over the code base, so we go with a quick-fix for now. |
1098 // In the same manner, we have to patch the parsing mode. | 1101 // In the same manner, we have to patch the parsing mode. |
1099 if (is_eval && !scope_->is_eval_scope()) { | 1102 if (is_eval && !scope_->is_eval_scope()) { |
1100 ASSERT(scope_->is_global_scope()); | 1103 ASSERT(scope_->is_global_scope()); |
1101 Scope* scope = NewScope(scope_, EVAL_SCOPE); | 1104 Scope* scope = NewScope(scope_, EVAL_SCOPE); |
1102 scope->set_start_position(scope_->start_position()); | 1105 scope->set_start_position(scope_->start_position()); |
1103 scope->set_end_position(scope_->end_position()); | 1106 scope->set_end_position(scope_->end_position()); |
(...skipping 10 matching lines...) Expand all Loading... |
1114 } | 1117 } |
1115 } | 1118 } |
1116 | 1119 |
1117 processor->Add(stat, zone()); | 1120 processor->Add(stat, zone()); |
1118 } | 1121 } |
1119 | 1122 |
1120 return 0; | 1123 return 0; |
1121 } | 1124 } |
1122 | 1125 |
1123 | 1126 |
1124 Statement* Parser::ParseModuleElement(ZoneStringList* labels, | 1127 Statement* Parser::ParseModuleElement(ZoneList<const AstRawString*>* labels, |
1125 bool* ok) { | 1128 bool* ok) { |
1126 // (Ecma 262 5th Edition, clause 14): | 1129 // (Ecma 262 5th Edition, clause 14): |
1127 // SourceElement: | 1130 // SourceElement: |
1128 // Statement | 1131 // Statement |
1129 // FunctionDeclaration | 1132 // FunctionDeclaration |
1130 // | 1133 // |
1131 // In harmony mode we allow additionally the following productions | 1134 // In harmony mode we allow additionally the following productions |
1132 // ModuleElement: | 1135 // ModuleElement: |
1133 // LetDeclaration | 1136 // LetDeclaration |
1134 // ConstDeclaration | 1137 // ConstDeclaration |
(...skipping 13 matching lines...) Expand all Loading... |
1148 case Token::EXPORT: | 1151 case Token::EXPORT: |
1149 return ParseExportDeclaration(ok); | 1152 return ParseExportDeclaration(ok); |
1150 default: { | 1153 default: { |
1151 Statement* stmt = ParseStatement(labels, CHECK_OK); | 1154 Statement* stmt = ParseStatement(labels, CHECK_OK); |
1152 // Handle 'module' as a context-sensitive keyword. | 1155 // Handle 'module' as a context-sensitive keyword. |
1153 if (FLAG_harmony_modules && | 1156 if (FLAG_harmony_modules && |
1154 peek() == Token::IDENTIFIER && | 1157 peek() == Token::IDENTIFIER && |
1155 !scanner()->HasAnyLineTerminatorBeforeNext() && | 1158 !scanner()->HasAnyLineTerminatorBeforeNext() && |
1156 stmt != NULL) { | 1159 stmt != NULL) { |
1157 ExpressionStatement* estmt = stmt->AsExpressionStatement(); | 1160 ExpressionStatement* estmt = stmt->AsExpressionStatement(); |
1158 if (estmt != NULL && | 1161 if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL && |
1159 estmt->expression()->AsVariableProxy() != NULL && | 1162 estmt->expression()->AsVariableProxy()->raw_name() == |
1160 String::Equals(isolate()->factory()->module_string(), | 1163 ast_value_factory_->module_string() && |
1161 estmt->expression()->AsVariableProxy()->name()) && | |
1162 !scanner()->literal_contains_escapes()) { | 1164 !scanner()->literal_contains_escapes()) { |
1163 return ParseModuleDeclaration(NULL, ok); | 1165 return ParseModuleDeclaration(NULL, ok); |
1164 } | 1166 } |
1165 } | 1167 } |
1166 return stmt; | 1168 return stmt; |
1167 } | 1169 } |
1168 } | 1170 } |
1169 } | 1171 } |
1170 | 1172 |
1171 | 1173 |
1172 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { | 1174 Statement* Parser::ParseModuleDeclaration(ZoneList<const AstRawString*>* names, |
| 1175 bool* ok) { |
1173 // ModuleDeclaration: | 1176 // ModuleDeclaration: |
1174 // 'module' Identifier Module | 1177 // 'module' Identifier Module |
1175 | 1178 |
1176 int pos = peek_position(); | 1179 int pos = peek_position(); |
1177 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1180 const AstRawString* name = |
| 1181 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
1178 | 1182 |
1179 #ifdef DEBUG | 1183 #ifdef DEBUG |
1180 if (FLAG_print_interface_details) | 1184 if (FLAG_print_interface_details) |
1181 PrintF("# Module %s...\n", name->ToAsciiArray()); | 1185 PrintF("# Module %.*s ", name->length(), name->raw_data()); |
1182 #endif | 1186 #endif |
1183 | 1187 |
1184 Module* module = ParseModule(CHECK_OK); | 1188 Module* module = ParseModule(CHECK_OK); |
1185 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); | 1189 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); |
1186 Declaration* declaration = | 1190 Declaration* declaration = |
1187 factory()->NewModuleDeclaration(proxy, module, scope_, pos); | 1191 factory()->NewModuleDeclaration(proxy, module, scope_, pos); |
1188 Declare(declaration, true, CHECK_OK); | 1192 Declare(declaration, true, CHECK_OK); |
1189 | 1193 |
1190 #ifdef DEBUG | 1194 #ifdef DEBUG |
1191 if (FLAG_print_interface_details) | 1195 if (FLAG_print_interface_details) |
1192 PrintF("# Module %s.\n", name->ToAsciiArray()); | 1196 PrintF("# Module %.*s ", name->length(), name->raw_data()); |
1193 | |
1194 if (FLAG_print_interfaces) { | 1197 if (FLAG_print_interfaces) { |
1195 PrintF("module %s : ", name->ToAsciiArray()); | 1198 PrintF("module %.*s: ", name->length(), name->raw_data()); |
1196 module->interface()->Print(); | 1199 module->interface()->Print(); |
1197 } | 1200 } |
1198 #endif | 1201 #endif |
1199 | 1202 |
1200 if (names) names->Add(name, zone()); | 1203 if (names) names->Add(name, zone()); |
1201 if (module->body() == NULL) | 1204 if (module->body() == NULL) |
1202 return factory()->NewEmptyStatement(pos); | 1205 return factory()->NewEmptyStatement(pos); |
1203 else | 1206 else |
1204 return factory()->NewModuleStatement(proxy, module->body(), pos); | 1207 return factory()->NewModuleStatement(proxy, module->body(), pos); |
1205 } | 1208 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1286 | 1289 |
1287 | 1290 |
1288 Module* Parser::ParseModulePath(bool* ok) { | 1291 Module* Parser::ParseModulePath(bool* ok) { |
1289 // ModulePath: | 1292 // ModulePath: |
1290 // Identifier | 1293 // Identifier |
1291 // ModulePath '.' Identifier | 1294 // ModulePath '.' Identifier |
1292 | 1295 |
1293 int pos = peek_position(); | 1296 int pos = peek_position(); |
1294 Module* result = ParseModuleVariable(CHECK_OK); | 1297 Module* result = ParseModuleVariable(CHECK_OK); |
1295 while (Check(Token::PERIOD)) { | 1298 while (Check(Token::PERIOD)) { |
1296 Handle<String> name = ParseIdentifierName(CHECK_OK); | 1299 const AstRawString* name = ParseIdentifierName(CHECK_OK); |
1297 #ifdef DEBUG | 1300 #ifdef DEBUG |
1298 if (FLAG_print_interface_details) | 1301 if (FLAG_print_interface_details) |
1299 PrintF("# Path .%s ", name->ToAsciiArray()); | 1302 PrintF("# Path .%.*s ", name->length(), name->raw_data()); |
1300 #endif | 1303 #endif |
1301 Module* member = factory()->NewModulePath(result, name, pos); | 1304 Module* member = factory()->NewModulePath(result, name, pos); |
1302 result->interface()->Add(name, member->interface(), zone(), ok); | 1305 result->interface()->Add(name, member->interface(), zone(), ok); |
1303 if (!*ok) { | 1306 if (!*ok) { |
1304 #ifdef DEBUG | 1307 #ifdef DEBUG |
1305 if (FLAG_print_interfaces) { | 1308 if (FLAG_print_interfaces) { |
1306 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); | 1309 PrintF("PATH TYPE ERROR at '%.*s'\n", name->length(), name->raw_data()); |
1307 PrintF("result: "); | 1310 PrintF("result: "); |
1308 result->interface()->Print(); | 1311 result->interface()->Print(); |
1309 PrintF("member: "); | 1312 PrintF("member: "); |
1310 member->interface()->Print(); | 1313 member->interface()->Print(); |
1311 } | 1314 } |
1312 #endif | 1315 #endif |
1313 ParserTraits::ReportMessage("invalid_module_path", name); | 1316 ParserTraits::ReportMessage("invalid_module_path", name); |
1314 return NULL; | 1317 return NULL; |
1315 } | 1318 } |
1316 result = member; | 1319 result = member; |
1317 } | 1320 } |
1318 | 1321 |
1319 return result; | 1322 return result; |
1320 } | 1323 } |
1321 | 1324 |
1322 | 1325 |
1323 Module* Parser::ParseModuleVariable(bool* ok) { | 1326 Module* Parser::ParseModuleVariable(bool* ok) { |
1324 // ModulePath: | 1327 // ModulePath: |
1325 // Identifier | 1328 // Identifier |
1326 | 1329 |
1327 int pos = peek_position(); | 1330 int pos = peek_position(); |
1328 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1331 const AstRawString* name = |
| 1332 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
1329 #ifdef DEBUG | 1333 #ifdef DEBUG |
1330 if (FLAG_print_interface_details) | 1334 if (FLAG_print_interface_details) |
1331 PrintF("# Module variable %s ", name->ToAsciiArray()); | 1335 PrintF("# Module variable %.*s ", name->length(), name->raw_data()); |
1332 #endif | 1336 #endif |
1333 VariableProxy* proxy = scope_->NewUnresolved( | 1337 VariableProxy* proxy = scope_->NewUnresolved( |
1334 factory(), name, Interface::NewModule(zone()), | 1338 factory(), name, Interface::NewModule(zone()), |
1335 scanner()->location().beg_pos); | 1339 scanner()->location().beg_pos); |
1336 | 1340 |
1337 return factory()->NewModuleVariable(proxy, pos); | 1341 return factory()->NewModuleVariable(proxy, pos); |
1338 } | 1342 } |
1339 | 1343 |
1340 | 1344 |
1341 Module* Parser::ParseModuleUrl(bool* ok) { | 1345 Module* Parser::ParseModuleUrl(bool* ok) { |
1342 // Module: | 1346 // Module: |
1343 // String | 1347 // String |
1344 | 1348 |
1345 int pos = peek_position(); | 1349 int pos = peek_position(); |
1346 Expect(Token::STRING, CHECK_OK); | 1350 Expect(Token::STRING, CHECK_OK); |
1347 Handle<String> symbol = GetSymbol(); | 1351 const AstRawString* symbol = GetSymbol(scanner()); |
1348 | 1352 |
1349 // TODO(ES6): Request JS resource from environment... | 1353 // TODO(ES6): Request JS resource from environment... |
1350 | 1354 |
1351 #ifdef DEBUG | 1355 #ifdef DEBUG |
1352 if (FLAG_print_interface_details) PrintF("# Url "); | 1356 if (FLAG_print_interface_details) PrintF("# Url "); |
1353 #endif | 1357 #endif |
1354 | 1358 |
1355 // Create an empty literal as long as the feature isn't finished. | 1359 // Create an empty literal as long as the feature isn't finished. |
1356 USE(symbol); | 1360 USE(symbol); |
1357 Scope* scope = NewScope(scope_, MODULE_SCOPE); | 1361 Scope* scope = NewScope(scope_, MODULE_SCOPE); |
(...skipping 23 matching lines...) Expand all Loading... |
1381 | 1385 |
1382 | 1386 |
1383 Block* Parser::ParseImportDeclaration(bool* ok) { | 1387 Block* Parser::ParseImportDeclaration(bool* ok) { |
1384 // ImportDeclaration: | 1388 // ImportDeclaration: |
1385 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' | 1389 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' |
1386 // | 1390 // |
1387 // TODO(ES6): implement destructuring ImportSpecifiers | 1391 // TODO(ES6): implement destructuring ImportSpecifiers |
1388 | 1392 |
1389 int pos = peek_position(); | 1393 int pos = peek_position(); |
1390 Expect(Token::IMPORT, CHECK_OK); | 1394 Expect(Token::IMPORT, CHECK_OK); |
1391 ZoneStringList names(1, zone()); | 1395 ZoneList<const AstRawString*> names(1, zone()); |
1392 | 1396 |
1393 Handle<String> name = ParseIdentifierName(CHECK_OK); | 1397 const AstRawString* name = ParseIdentifierName(CHECK_OK); |
1394 names.Add(name, zone()); | 1398 names.Add(name, zone()); |
1395 while (peek() == Token::COMMA) { | 1399 while (peek() == Token::COMMA) { |
1396 Consume(Token::COMMA); | 1400 Consume(Token::COMMA); |
1397 name = ParseIdentifierName(CHECK_OK); | 1401 name = ParseIdentifierName(CHECK_OK); |
1398 names.Add(name, zone()); | 1402 names.Add(name, zone()); |
1399 } | 1403 } |
1400 | 1404 |
1401 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); | 1405 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
1402 Module* module = ParseModuleSpecifier(CHECK_OK); | 1406 Module* module = ParseModuleSpecifier(CHECK_OK); |
1403 ExpectSemicolon(CHECK_OK); | 1407 ExpectSemicolon(CHECK_OK); |
1404 | 1408 |
1405 // Generate a separate declaration for each identifier. | 1409 // Generate a separate declaration for each identifier. |
1406 // TODO(ES6): once we implement destructuring, make that one declaration. | 1410 // TODO(ES6): once we implement destructuring, make that one declaration. |
1407 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); | 1411 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); |
1408 for (int i = 0; i < names.length(); ++i) { | 1412 for (int i = 0; i < names.length(); ++i) { |
1409 #ifdef DEBUG | 1413 #ifdef DEBUG |
1410 if (FLAG_print_interface_details) | 1414 if (FLAG_print_interface_details) |
1411 PrintF("# Import %s ", names[i]->ToAsciiArray()); | 1415 PrintF("# Import %.*s ", name->length(), name->raw_data()); |
1412 #endif | 1416 #endif |
1413 Interface* interface = Interface::NewUnknown(zone()); | 1417 Interface* interface = Interface::NewUnknown(zone()); |
1414 module->interface()->Add(names[i], interface, zone(), ok); | 1418 module->interface()->Add(names[i], interface, zone(), ok); |
1415 if (!*ok) { | 1419 if (!*ok) { |
1416 #ifdef DEBUG | 1420 #ifdef DEBUG |
1417 if (FLAG_print_interfaces) { | 1421 if (FLAG_print_interfaces) { |
1418 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); | 1422 PrintF("IMPORT TYPE ERROR at '%.*s'\n", name->length(), |
| 1423 name->raw_data()); |
1419 PrintF("module: "); | 1424 PrintF("module: "); |
1420 module->interface()->Print(); | 1425 module->interface()->Print(); |
1421 } | 1426 } |
1422 #endif | 1427 #endif |
1423 ParserTraits::ReportMessage("invalid_module_path", name); | 1428 ParserTraits::ReportMessage("invalid_module_path", name); |
1424 return NULL; | 1429 return NULL; |
1425 } | 1430 } |
1426 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); | 1431 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); |
1427 Declaration* declaration = | 1432 Declaration* declaration = |
1428 factory()->NewImportDeclaration(proxy, module, scope_, pos); | 1433 factory()->NewImportDeclaration(proxy, module, scope_, pos); |
(...skipping 10 matching lines...) Expand all Loading... |
1439 // 'export' VariableDeclaration | 1444 // 'export' VariableDeclaration |
1440 // 'export' FunctionDeclaration | 1445 // 'export' FunctionDeclaration |
1441 // 'export' GeneratorDeclaration | 1446 // 'export' GeneratorDeclaration |
1442 // 'export' ModuleDeclaration | 1447 // 'export' ModuleDeclaration |
1443 // | 1448 // |
1444 // TODO(ES6): implement structuring ExportSpecifiers | 1449 // TODO(ES6): implement structuring ExportSpecifiers |
1445 | 1450 |
1446 Expect(Token::EXPORT, CHECK_OK); | 1451 Expect(Token::EXPORT, CHECK_OK); |
1447 | 1452 |
1448 Statement* result = NULL; | 1453 Statement* result = NULL; |
1449 ZoneStringList names(1, zone()); | 1454 ZoneList<const AstRawString*> names(1, zone()); |
1450 switch (peek()) { | 1455 switch (peek()) { |
1451 case Token::IDENTIFIER: { | 1456 case Token::IDENTIFIER: { |
1452 int pos = position(); | 1457 int pos = position(); |
1453 Handle<String> name = | 1458 const AstRawString* name = |
1454 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1459 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
1455 // Handle 'module' as a context-sensitive keyword. | 1460 // Handle 'module' as a context-sensitive keyword. |
1456 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { | 1461 if (name != ast_value_factory_->module_string()) { |
1457 names.Add(name, zone()); | 1462 names.Add(name, zone()); |
1458 while (peek() == Token::COMMA) { | 1463 while (peek() == Token::COMMA) { |
1459 Consume(Token::COMMA); | 1464 Consume(Token::COMMA); |
1460 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1465 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
1461 names.Add(name, zone()); | 1466 names.Add(name, zone()); |
1462 } | 1467 } |
1463 ExpectSemicolon(CHECK_OK); | 1468 ExpectSemicolon(CHECK_OK); |
1464 result = factory()->NewEmptyStatement(pos); | 1469 result = factory()->NewEmptyStatement(pos); |
1465 } else { | 1470 } else { |
1466 result = ParseModuleDeclaration(&names, CHECK_OK); | 1471 result = ParseModuleDeclaration(&names, CHECK_OK); |
(...skipping 15 matching lines...) Expand all Loading... |
1482 *ok = false; | 1487 *ok = false; |
1483 ReportUnexpectedToken(scanner()->current_token()); | 1488 ReportUnexpectedToken(scanner()->current_token()); |
1484 return NULL; | 1489 return NULL; |
1485 } | 1490 } |
1486 | 1491 |
1487 // Extract declared names into export declarations and interface. | 1492 // Extract declared names into export declarations and interface. |
1488 Interface* interface = scope_->interface(); | 1493 Interface* interface = scope_->interface(); |
1489 for (int i = 0; i < names.length(); ++i) { | 1494 for (int i = 0; i < names.length(); ++i) { |
1490 #ifdef DEBUG | 1495 #ifdef DEBUG |
1491 if (FLAG_print_interface_details) | 1496 if (FLAG_print_interface_details) |
1492 PrintF("# Export %s ", names[i]->ToAsciiArray()); | 1497 PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data()); |
1493 #endif | 1498 #endif |
1494 Interface* inner = Interface::NewUnknown(zone()); | 1499 Interface* inner = Interface::NewUnknown(zone()); |
1495 interface->Add(names[i], inner, zone(), CHECK_OK); | 1500 interface->Add(names[i], inner, zone(), CHECK_OK); |
1496 if (!*ok) | 1501 if (!*ok) |
1497 return NULL; | 1502 return NULL; |
1498 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); | 1503 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); |
1499 USE(proxy); | 1504 USE(proxy); |
1500 // TODO(rossberg): Rethink whether we actually need to store export | 1505 // TODO(rossberg): Rethink whether we actually need to store export |
1501 // declarations (for compilation?). | 1506 // declarations (for compilation?). |
1502 // ExportDeclaration* declaration = | 1507 // ExportDeclaration* declaration = |
1503 // factory()->NewExportDeclaration(proxy, scope_, position); | 1508 // factory()->NewExportDeclaration(proxy, scope_, position); |
1504 // scope_->AddDeclaration(declaration); | 1509 // scope_->AddDeclaration(declaration); |
1505 } | 1510 } |
1506 | 1511 |
1507 ASSERT(result != NULL); | 1512 ASSERT(result != NULL); |
1508 return result; | 1513 return result; |
1509 } | 1514 } |
1510 | 1515 |
1511 | 1516 |
1512 Statement* Parser::ParseBlockElement(ZoneStringList* labels, | 1517 Statement* Parser::ParseBlockElement(ZoneList<const AstRawString*>* labels, |
1513 bool* ok) { | 1518 bool* ok) { |
1514 // (Ecma 262 5th Edition, clause 14): | 1519 // (Ecma 262 5th Edition, clause 14): |
1515 // SourceElement: | 1520 // SourceElement: |
1516 // Statement | 1521 // Statement |
1517 // FunctionDeclaration | 1522 // FunctionDeclaration |
1518 // | 1523 // |
1519 // In harmony mode we allow additionally the following productions | 1524 // In harmony mode we allow additionally the following productions |
1520 // BlockElement (aka SourceElement): | 1525 // BlockElement (aka SourceElement): |
1521 // LetDeclaration | 1526 // LetDeclaration |
1522 // ConstDeclaration | 1527 // ConstDeclaration |
1523 // GeneratorDeclaration | 1528 // GeneratorDeclaration |
1524 | 1529 |
1525 switch (peek()) { | 1530 switch (peek()) { |
1526 case Token::FUNCTION: | 1531 case Token::FUNCTION: |
1527 return ParseFunctionDeclaration(NULL, ok); | 1532 return ParseFunctionDeclaration(NULL, ok); |
1528 case Token::LET: | 1533 case Token::LET: |
1529 case Token::CONST: | 1534 case Token::CONST: |
1530 return ParseVariableStatement(kModuleElement, NULL, ok); | 1535 return ParseVariableStatement(kModuleElement, NULL, ok); |
1531 default: | 1536 default: |
1532 return ParseStatement(labels, ok); | 1537 return ParseStatement(labels, ok); |
1533 } | 1538 } |
1534 } | 1539 } |
1535 | 1540 |
1536 | 1541 |
1537 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { | 1542 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, |
| 1543 bool* ok) { |
1538 // Statement :: | 1544 // Statement :: |
1539 // Block | 1545 // Block |
1540 // VariableStatement | 1546 // VariableStatement |
1541 // EmptyStatement | 1547 // EmptyStatement |
1542 // ExpressionStatement | 1548 // ExpressionStatement |
1543 // IfStatement | 1549 // IfStatement |
1544 // IterationStatement | 1550 // IterationStatement |
1545 // ContinueStatement | 1551 // ContinueStatement |
1546 // BreakStatement | 1552 // BreakStatement |
1547 // ReturnStatement | 1553 // ReturnStatement |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1637 | 1643 |
1638 case Token::DEBUGGER: | 1644 case Token::DEBUGGER: |
1639 return ParseDebuggerStatement(ok); | 1645 return ParseDebuggerStatement(ok); |
1640 | 1646 |
1641 default: | 1647 default: |
1642 return ParseExpressionOrLabelledStatement(labels, ok); | 1648 return ParseExpressionOrLabelledStatement(labels, ok); |
1643 } | 1649 } |
1644 } | 1650 } |
1645 | 1651 |
1646 | 1652 |
1647 VariableProxy* Parser::NewUnresolved( | 1653 VariableProxy* Parser::NewUnresolved(const AstRawString* name, |
1648 Handle<String> name, VariableMode mode, Interface* interface) { | 1654 VariableMode mode, Interface* interface) { |
1649 // If we are inside a function, a declaration of a var/const variable is a | 1655 // If we are inside a function, a declaration of a var/const variable is a |
1650 // truly local variable, and the scope of the variable is always the function | 1656 // truly local variable, and the scope of the variable is always the function |
1651 // scope. | 1657 // scope. |
1652 // Let/const variables in harmony mode are always added to the immediately | 1658 // Let/const variables in harmony mode are always added to the immediately |
1653 // enclosing scope. | 1659 // enclosing scope. |
1654 return DeclarationScope(mode)->NewUnresolved( | 1660 return DeclarationScope(mode)->NewUnresolved( |
1655 factory(), name, interface, position()); | 1661 factory(), name, interface, position()); |
1656 } | 1662 } |
1657 | 1663 |
1658 | 1664 |
1659 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { | 1665 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { |
1660 VariableProxy* proxy = declaration->proxy(); | 1666 VariableProxy* proxy = declaration->proxy(); |
1661 Handle<String> name = proxy->name(); | 1667 ASSERT(proxy->raw_name() != NULL); |
| 1668 const AstRawString* name = proxy->raw_name(); |
1662 VariableMode mode = declaration->mode(); | 1669 VariableMode mode = declaration->mode(); |
1663 Scope* declaration_scope = DeclarationScope(mode); | 1670 Scope* declaration_scope = DeclarationScope(mode); |
1664 Variable* var = NULL; | 1671 Variable* var = NULL; |
1665 | 1672 |
1666 // If a suitable scope exists, then we can statically declare this | 1673 // If a suitable scope exists, then we can statically declare this |
1667 // variable and also set its mode. In any case, a Declaration node | 1674 // variable and also set its mode. In any case, a Declaration node |
1668 // will be added to the scope so that the declaration can be added | 1675 // will be added to the scope so that the declaration can be added |
1669 // to the corresponding activation frame at runtime if necessary. | 1676 // to the corresponding activation frame at runtime if necessary. |
1670 // For instance declarations inside an eval scope need to be added | 1677 // For instance declarations inside an eval scope need to be added |
1671 // to the calling function context. | 1678 // to the calling function context. |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1779 // with a context slot index and a context chain length for this | 1786 // with a context slot index and a context chain length for this |
1780 // initialization code. Thus, inside the 'with' statement, we need | 1787 // initialization code. Thus, inside the 'with' statement, we need |
1781 // both access to the static and the dynamic context chain; the | 1788 // both access to the static and the dynamic context chain; the |
1782 // runtime needs to provide both. | 1789 // runtime needs to provide both. |
1783 if (resolve && var != NULL) { | 1790 if (resolve && var != NULL) { |
1784 proxy->BindTo(var); | 1791 proxy->BindTo(var); |
1785 | 1792 |
1786 if (FLAG_harmony_modules) { | 1793 if (FLAG_harmony_modules) { |
1787 bool ok; | 1794 bool ok; |
1788 #ifdef DEBUG | 1795 #ifdef DEBUG |
1789 if (FLAG_print_interface_details) | 1796 if (FLAG_print_interface_details) { |
1790 PrintF("# Declare %s\n", var->name()->ToAsciiArray()); | 1797 PrintF("# Declare %.*s ", var->raw_name()->length(), |
| 1798 var->raw_name()->raw_data()); |
| 1799 } |
1791 #endif | 1800 #endif |
1792 proxy->interface()->Unify(var->interface(), zone(), &ok); | 1801 proxy->interface()->Unify(var->interface(), zone(), &ok); |
1793 if (!ok) { | 1802 if (!ok) { |
1794 #ifdef DEBUG | 1803 #ifdef DEBUG |
1795 if (FLAG_print_interfaces) { | 1804 if (FLAG_print_interfaces) { |
1796 PrintF("DECLARE TYPE ERROR\n"); | 1805 PrintF("DECLARE TYPE ERROR\n"); |
1797 PrintF("proxy: "); | 1806 PrintF("proxy: "); |
1798 proxy->interface()->Print(); | 1807 proxy->interface()->Print(); |
1799 PrintF("var: "); | 1808 PrintF("var: "); |
1800 var->interface()->Print(); | 1809 var->interface()->Print(); |
1801 } | 1810 } |
1802 #endif | 1811 #endif |
1803 ParserTraits::ReportMessage("module_type_error", name); | 1812 ParserTraits::ReportMessage("module_type_error", name); |
1804 } | 1813 } |
1805 } | 1814 } |
1806 } | 1815 } |
1807 } | 1816 } |
1808 | 1817 |
1809 | 1818 |
1810 // Language extension which is only enabled for source files loaded | 1819 // Language extension which is only enabled for source files loaded |
1811 // through the API's extension mechanism. A native function | 1820 // through the API's extension mechanism. A native function |
1812 // declaration is resolved by looking up the function through a | 1821 // declaration is resolved by looking up the function through a |
1813 // callback provided by the extension. | 1822 // callback provided by the extension. |
1814 Statement* Parser::ParseNativeDeclaration(bool* ok) { | 1823 Statement* Parser::ParseNativeDeclaration(bool* ok) { |
1815 int pos = peek_position(); | 1824 int pos = peek_position(); |
1816 Expect(Token::FUNCTION, CHECK_OK); | 1825 Expect(Token::FUNCTION, CHECK_OK); |
1817 // Allow "eval" or "arguments" for backward compatibility. | 1826 // Allow "eval" or "arguments" for backward compatibility. |
1818 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1827 const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
1819 Expect(Token::LPAREN, CHECK_OK); | 1828 Expect(Token::LPAREN, CHECK_OK); |
1820 bool done = (peek() == Token::RPAREN); | 1829 bool done = (peek() == Token::RPAREN); |
1821 while (!done) { | 1830 while (!done) { |
1822 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1831 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
1823 done = (peek() == Token::RPAREN); | 1832 done = (peek() == Token::RPAREN); |
1824 if (!done) { | 1833 if (!done) { |
1825 Expect(Token::COMMA, CHECK_OK); | 1834 Expect(Token::COMMA, CHECK_OK); |
1826 } | 1835 } |
1827 } | 1836 } |
1828 Expect(Token::RPAREN, CHECK_OK); | 1837 Expect(Token::RPAREN, CHECK_OK); |
(...skipping 14 matching lines...) Expand all Loading... |
1843 Declare(declaration, true, CHECK_OK); | 1852 Declare(declaration, true, CHECK_OK); |
1844 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( | 1853 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( |
1845 name, extension_, RelocInfo::kNoPosition); | 1854 name, extension_, RelocInfo::kNoPosition); |
1846 return factory()->NewExpressionStatement( | 1855 return factory()->NewExpressionStatement( |
1847 factory()->NewAssignment( | 1856 factory()->NewAssignment( |
1848 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), | 1857 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), |
1849 pos); | 1858 pos); |
1850 } | 1859 } |
1851 | 1860 |
1852 | 1861 |
1853 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { | 1862 Statement* Parser::ParseFunctionDeclaration( |
| 1863 ZoneList<const AstRawString*>* names, bool* ok) { |
1854 // FunctionDeclaration :: | 1864 // FunctionDeclaration :: |
1855 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 1865 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
1856 // GeneratorDeclaration :: | 1866 // GeneratorDeclaration :: |
1857 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 1867 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
1858 // '{' FunctionBody '}' | 1868 // '{' FunctionBody '}' |
1859 Expect(Token::FUNCTION, CHECK_OK); | 1869 Expect(Token::FUNCTION, CHECK_OK); |
1860 int pos = position(); | 1870 int pos = position(); |
1861 bool is_generator = allow_generators() && Check(Token::MUL); | 1871 bool is_generator = allow_generators() && Check(Token::MUL); |
1862 bool is_strict_reserved = false; | 1872 bool is_strict_reserved = false; |
1863 Handle<String> name = ParseIdentifierOrStrictReservedWord( | 1873 const AstRawString* name = ParseIdentifierOrStrictReservedWord( |
1864 &is_strict_reserved, CHECK_OK); | 1874 &is_strict_reserved, CHECK_OK); |
1865 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1875 FunctionLiteral* fun = ParseFunctionLiteral(name, |
1866 scanner()->location(), | 1876 scanner()->location(), |
1867 is_strict_reserved, | 1877 is_strict_reserved, |
1868 is_generator, | 1878 is_generator, |
1869 pos, | 1879 pos, |
1870 FunctionLiteral::DECLARATION, | 1880 FunctionLiteral::DECLARATION, |
1871 FunctionLiteral::NORMAL_ARITY, | 1881 FunctionLiteral::NORMAL_ARITY, |
1872 CHECK_OK); | 1882 CHECK_OK); |
1873 // Even if we're not at the top-level of the global or a function | 1883 // Even if we're not at the top-level of the global or a function |
1874 // scope, we treat it as such and introduce the function with its | 1884 // scope, we treat it as such and introduce the function with its |
1875 // initial value upon entering the corresponding scope. | 1885 // initial value upon entering the corresponding scope. |
1876 // In extended mode, a function behaves as a lexical binding, except in the | 1886 // In extended mode, a function behaves as a lexical binding, except in the |
1877 // global scope. | 1887 // global scope. |
1878 VariableMode mode = | 1888 VariableMode mode = |
1879 allow_harmony_scoping() && | 1889 allow_harmony_scoping() && |
1880 strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR; | 1890 strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR; |
1881 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); | 1891 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); |
1882 Declaration* declaration = | 1892 Declaration* declaration = |
1883 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); | 1893 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); |
1884 Declare(declaration, true, CHECK_OK); | 1894 Declare(declaration, true, CHECK_OK); |
1885 if (names) names->Add(name, zone()); | 1895 if (names) names->Add(name, zone()); |
1886 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 1896 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
1887 } | 1897 } |
1888 | 1898 |
1889 | 1899 |
1890 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1900 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) { |
1891 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 1901 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
1892 return ParseScopedBlock(labels, ok); | 1902 return ParseScopedBlock(labels, ok); |
1893 } | 1903 } |
1894 | 1904 |
1895 // Block :: | 1905 // Block :: |
1896 // '{' Statement* '}' | 1906 // '{' Statement* '}' |
1897 | 1907 |
1898 // Note that a Block does not introduce a new execution scope! | 1908 // Note that a Block does not introduce a new execution scope! |
1899 // (ECMA-262, 3rd, 12.2) | 1909 // (ECMA-262, 3rd, 12.2) |
1900 // | 1910 // |
1901 // Construct block expecting 16 statements. | 1911 // Construct block expecting 16 statements. |
1902 Block* result = | 1912 Block* result = |
1903 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1913 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
1904 Target target(&this->target_stack_, result); | 1914 Target target(&this->target_stack_, result); |
1905 Expect(Token::LBRACE, CHECK_OK); | 1915 Expect(Token::LBRACE, CHECK_OK); |
1906 while (peek() != Token::RBRACE) { | 1916 while (peek() != Token::RBRACE) { |
1907 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1917 Statement* stat = ParseStatement(NULL, CHECK_OK); |
1908 if (stat && !stat->IsEmpty()) { | 1918 if (stat && !stat->IsEmpty()) { |
1909 result->AddStatement(stat, zone()); | 1919 result->AddStatement(stat, zone()); |
1910 } | 1920 } |
1911 } | 1921 } |
1912 Expect(Token::RBRACE, CHECK_OK); | 1922 Expect(Token::RBRACE, CHECK_OK); |
1913 return result; | 1923 return result; |
1914 } | 1924 } |
1915 | 1925 |
1916 | 1926 |
1917 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { | 1927 Block* Parser::ParseScopedBlock(ZoneList<const AstRawString*>* labels, |
| 1928 bool* ok) { |
1918 // The harmony mode uses block elements instead of statements. | 1929 // The harmony mode uses block elements instead of statements. |
1919 // | 1930 // |
1920 // Block :: | 1931 // Block :: |
1921 // '{' BlockElement* '}' | 1932 // '{' BlockElement* '}' |
1922 | 1933 |
1923 // Construct block expecting 16 statements. | 1934 // Construct block expecting 16 statements. |
1924 Block* body = | 1935 Block* body = |
1925 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1936 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
1926 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); | 1937 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); |
1927 | 1938 |
(...skipping 14 matching lines...) Expand all Loading... |
1942 } | 1953 } |
1943 Expect(Token::RBRACE, CHECK_OK); | 1954 Expect(Token::RBRACE, CHECK_OK); |
1944 block_scope->set_end_position(scanner()->location().end_pos); | 1955 block_scope->set_end_position(scanner()->location().end_pos); |
1945 block_scope = block_scope->FinalizeBlockScope(); | 1956 block_scope = block_scope->FinalizeBlockScope(); |
1946 body->set_scope(block_scope); | 1957 body->set_scope(block_scope); |
1947 return body; | 1958 return body; |
1948 } | 1959 } |
1949 | 1960 |
1950 | 1961 |
1951 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, | 1962 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
1952 ZoneStringList* names, | 1963 ZoneList<const AstRawString*>* names, |
1953 bool* ok) { | 1964 bool* ok) { |
1954 // VariableStatement :: | 1965 // VariableStatement :: |
1955 // VariableDeclarations ';' | 1966 // VariableDeclarations ';' |
1956 | 1967 |
1957 Handle<String> ignore; | 1968 const AstRawString* ignore; |
1958 Block* result = | 1969 Block* result = |
1959 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); | 1970 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); |
1960 ExpectSemicolon(CHECK_OK); | 1971 ExpectSemicolon(CHECK_OK); |
1961 return result; | 1972 return result; |
1962 } | 1973 } |
1963 | 1974 |
1964 | 1975 |
1965 // If the variable declaration declares exactly one non-const | 1976 // If the variable declaration declares exactly one non-const |
1966 // variable, then *out is set to that variable. In all other cases, | 1977 // variable, then *out is set to that variable. In all other cases, |
1967 // *out is untouched; in particular, it is the caller's responsibility | 1978 // *out is untouched; in particular, it is the caller's responsibility |
1968 // to initialize it properly. This mechanism is used for the parsing | 1979 // to initialize it properly. This mechanism is used for the parsing |
1969 // of 'for-in' loops. | 1980 // of 'for-in' loops. |
1970 Block* Parser::ParseVariableDeclarations( | 1981 Block* Parser::ParseVariableDeclarations( |
1971 VariableDeclarationContext var_context, | 1982 VariableDeclarationContext var_context, |
1972 VariableDeclarationProperties* decl_props, | 1983 VariableDeclarationProperties* decl_props, |
1973 ZoneStringList* names, | 1984 ZoneList<const AstRawString*>* names, |
1974 Handle<String>* out, | 1985 const AstRawString** out, |
1975 bool* ok) { | 1986 bool* ok) { |
1976 // VariableDeclarations :: | 1987 // VariableDeclarations :: |
1977 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] | 1988 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] |
1978 // | 1989 // |
1979 // The ES6 Draft Rev3 specifies the following grammar for const declarations | 1990 // The ES6 Draft Rev3 specifies the following grammar for const declarations |
1980 // | 1991 // |
1981 // ConstDeclaration :: | 1992 // ConstDeclaration :: |
1982 // const ConstBinding (',' ConstBinding)* ';' | 1993 // const ConstBinding (',' ConstBinding)* ';' |
1983 // ConstBinding :: | 1994 // ConstBinding :: |
1984 // Identifier '=' AssignmentExpression | 1995 // Identifier '=' AssignmentExpression |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2072 // | 2083 // |
2073 // We mark the block as initializer block because we don't want the | 2084 // We mark the block as initializer block because we don't want the |
2074 // rewriter to add a '.result' assignment to such a block (to get compliant | 2085 // rewriter to add a '.result' assignment to such a block (to get compliant |
2075 // behavior for code such as print(eval('var x = 7')), and for cosmetic | 2086 // behavior for code such as print(eval('var x = 7')), and for cosmetic |
2076 // reasons when pretty-printing. Also, unless an assignment (initialization) | 2087 // reasons when pretty-printing. Also, unless an assignment (initialization) |
2077 // is inside an initializer block, it is ignored. | 2088 // is inside an initializer block, it is ignored. |
2078 // | 2089 // |
2079 // Create new block with one expected declaration. | 2090 // Create new block with one expected declaration. |
2080 Block* block = factory()->NewBlock(NULL, 1, true, pos); | 2091 Block* block = factory()->NewBlock(NULL, 1, true, pos); |
2081 int nvars = 0; // the number of variables declared | 2092 int nvars = 0; // the number of variables declared |
2082 Handle<String> name; | 2093 const AstRawString* name = NULL; |
2083 do { | 2094 do { |
2084 if (fni_ != NULL) fni_->Enter(); | 2095 if (fni_ != NULL) fni_->Enter(); |
2085 | 2096 |
2086 // Parse variable name. | 2097 // Parse variable name. |
2087 if (nvars > 0) Consume(Token::COMMA); | 2098 if (nvars > 0) Consume(Token::COMMA); |
2088 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2099 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
2089 if (fni_ != NULL) fni_->PushVariableName(name); | 2100 if (fni_ != NULL) fni_->PushVariableName(name); |
2090 | 2101 |
2091 // Declare variable. | 2102 // Declare variable. |
2092 // Note that we *always* must treat the initial value via a separate init | 2103 // Note that we *always* must treat the initial value via a separate init |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2191 // properties in the prototype chain, but only after the variable | 2202 // properties in the prototype chain, but only after the variable |
2192 // declaration statement has been executed. This is important in | 2203 // declaration statement has been executed. This is important in |
2193 // browsers where the global object (window) has lots of | 2204 // browsers where the global object (window) has lots of |
2194 // properties defined in prototype objects. | 2205 // properties defined in prototype objects. |
2195 if (initialization_scope->is_global_scope() && | 2206 if (initialization_scope->is_global_scope() && |
2196 !IsLexicalVariableMode(mode)) { | 2207 !IsLexicalVariableMode(mode)) { |
2197 // Compute the arguments for the runtime call. | 2208 // Compute the arguments for the runtime call. |
2198 ZoneList<Expression*>* arguments = | 2209 ZoneList<Expression*>* arguments = |
2199 new(zone()) ZoneList<Expression*>(3, zone()); | 2210 new(zone()) ZoneList<Expression*>(3, zone()); |
2200 // We have at least 1 parameter. | 2211 // We have at least 1 parameter. |
2201 arguments->Add(factory()->NewLiteral(name, pos), zone()); | 2212 arguments->Add(factory()->NewStringLiteral(name, pos), zone()); |
2202 CallRuntime* initialize; | 2213 CallRuntime* initialize; |
2203 | 2214 |
2204 if (is_const) { | 2215 if (is_const) { |
2205 arguments->Add(value, zone()); | 2216 arguments->Add(value, zone()); |
2206 value = NULL; // zap the value to avoid the unnecessary assignment | 2217 value = NULL; // zap the value to avoid the unnecessary assignment |
2207 | 2218 |
2208 // Construct the call to Runtime_InitializeConstGlobal | 2219 // Construct the call to Runtime_InitializeConstGlobal |
2209 // and add it to the initialization statement block. | 2220 // and add it to the initialization statement block. |
2210 // Note that the function does different things depending on | 2221 // Note that the function does different things depending on |
2211 // the number of arguments (1 or 2). | 2222 // the number of arguments (1 or 2). |
2212 initialize = factory()->NewCallRuntime( | 2223 initialize = factory()->NewCallRuntime( |
2213 isolate()->factory()->InitializeConstGlobal_string(), | 2224 ast_value_factory_->initialize_const_global_string(), |
2214 Runtime::FunctionForId(Runtime::kHiddenInitializeConstGlobal), | 2225 Runtime::FunctionForId(Runtime::kHiddenInitializeConstGlobal), |
2215 arguments, pos); | 2226 arguments, pos); |
2216 } else { | 2227 } else { |
2217 // Add strict mode. | 2228 // Add strict mode. |
2218 // We may want to pass singleton to avoid Literal allocations. | 2229 // We may want to pass singleton to avoid Literal allocations. |
2219 StrictMode strict_mode = initialization_scope->strict_mode(); | 2230 StrictMode strict_mode = initialization_scope->strict_mode(); |
2220 arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone()); | 2231 arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone()); |
2221 | 2232 |
2222 // Be careful not to assign a value to the global variable if | 2233 // Be careful not to assign a value to the global variable if |
2223 // we're in a with. The initialization value should not | 2234 // we're in a with. The initialization value should not |
2224 // necessarily be stored in the global object in that case, | 2235 // necessarily be stored in the global object in that case, |
2225 // which is why we need to generate a separate assignment node. | 2236 // which is why we need to generate a separate assignment node. |
2226 if (value != NULL && !inside_with()) { | 2237 if (value != NULL && !inside_with()) { |
2227 arguments->Add(value, zone()); | 2238 arguments->Add(value, zone()); |
2228 value = NULL; // zap the value to avoid the unnecessary assignment | 2239 value = NULL; // zap the value to avoid the unnecessary assignment |
2229 } | 2240 } |
2230 | 2241 |
2231 // Construct the call to Runtime_InitializeVarGlobal | 2242 // Construct the call to Runtime_InitializeVarGlobal |
2232 // and add it to the initialization statement block. | 2243 // and add it to the initialization statement block. |
2233 // Note that the function does different things depending on | 2244 // Note that the function does different things depending on |
2234 // the number of arguments (2 or 3). | 2245 // the number of arguments (2 or 3). |
2235 initialize = factory()->NewCallRuntime( | 2246 initialize = factory()->NewCallRuntime( |
2236 isolate()->factory()->InitializeVarGlobal_string(), | 2247 ast_value_factory_->initialize_var_global_string(), |
2237 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), | 2248 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), |
2238 arguments, pos); | 2249 arguments, pos); |
2239 } | 2250 } |
2240 | 2251 |
2241 block->AddStatement( | 2252 block->AddStatement( |
2242 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), | 2253 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), |
2243 zone()); | 2254 zone()); |
2244 } else if (needs_init) { | 2255 } else if (needs_init) { |
2245 // Constant initializations always assign to the declared constant which | 2256 // Constant initializations always assign to the declared constant which |
2246 // is always at the function scope level. This is only relevant for | 2257 // 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... |
2282 // If there was a single non-const declaration, return it in the output | 2293 // If there was a single non-const declaration, return it in the output |
2283 // parameter for possible use by for/in. | 2294 // parameter for possible use by for/in. |
2284 if (nvars == 1 && !is_const) { | 2295 if (nvars == 1 && !is_const) { |
2285 *out = name; | 2296 *out = name; |
2286 } | 2297 } |
2287 | 2298 |
2288 return block; | 2299 return block; |
2289 } | 2300 } |
2290 | 2301 |
2291 | 2302 |
2292 static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) { | 2303 static bool ContainsLabel(ZoneList<const AstRawString*>* labels, |
2293 ASSERT(!label.is_null()); | 2304 const AstRawString* label) { |
| 2305 ASSERT(label != NULL); |
2294 if (labels != NULL) { | 2306 if (labels != NULL) { |
2295 for (int i = labels->length(); i-- > 0; ) { | 2307 for (int i = labels->length(); i-- > 0; ) { |
2296 if (labels->at(i).is_identical_to(label)) { | 2308 if (labels->at(i) == label) { |
2297 return true; | 2309 return true; |
2298 } | 2310 } |
2299 } | 2311 } |
2300 } | 2312 } |
2301 return false; | 2313 return false; |
2302 } | 2314 } |
2303 | 2315 |
2304 | 2316 |
2305 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, | 2317 Statement* Parser::ParseExpressionOrLabelledStatement( |
2306 bool* ok) { | 2318 ZoneList<const AstRawString*>* labels, bool* ok) { |
2307 // ExpressionStatement | LabelledStatement :: | 2319 // ExpressionStatement | LabelledStatement :: |
2308 // Expression ';' | 2320 // Expression ';' |
2309 // Identifier ':' Statement | 2321 // Identifier ':' Statement |
2310 int pos = peek_position(); | 2322 int pos = peek_position(); |
2311 bool starts_with_idenfifier = peek_any_identifier(); | 2323 bool starts_with_idenfifier = peek_any_identifier(); |
2312 Expression* expr = ParseExpression(true, CHECK_OK); | 2324 Expression* expr = ParseExpression(true, CHECK_OK); |
2313 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && | 2325 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && |
2314 expr->AsVariableProxy() != NULL && | 2326 expr->AsVariableProxy() != NULL && |
2315 !expr->AsVariableProxy()->is_this()) { | 2327 !expr->AsVariableProxy()->is_this()) { |
2316 // Expression is a single identifier, and not, e.g., a parenthesized | 2328 // Expression is a single identifier, and not, e.g., a parenthesized |
2317 // identifier. | 2329 // identifier. |
2318 VariableProxy* var = expr->AsVariableProxy(); | 2330 VariableProxy* var = expr->AsVariableProxy(); |
2319 Handle<String> label = var->name(); | 2331 const AstRawString* label = var->raw_name(); |
2320 // TODO(1240780): We don't check for redeclaration of labels | 2332 // TODO(1240780): We don't check for redeclaration of labels |
2321 // during preparsing since keeping track of the set of active | 2333 // during preparsing since keeping track of the set of active |
2322 // labels requires nontrivial changes to the way scopes are | 2334 // labels requires nontrivial changes to the way scopes are |
2323 // structured. However, these are probably changes we want to | 2335 // structured. However, these are probably changes we want to |
2324 // make later anyway so we should go back and fix this then. | 2336 // make later anyway so we should go back and fix this then. |
2325 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { | 2337 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { |
2326 ParserTraits::ReportMessage("label_redeclaration", label); | 2338 ParserTraits::ReportMessage("label_redeclaration", label); |
2327 *ok = false; | 2339 *ok = false; |
2328 return NULL; | 2340 return NULL; |
2329 } | 2341 } |
2330 if (labels == NULL) { | 2342 if (labels == NULL) { |
2331 labels = new(zone()) ZoneStringList(4, zone()); | 2343 labels = new(zone()) ZoneList<const AstRawString*>(4, zone()); |
2332 } | 2344 } |
2333 labels->Add(label, zone()); | 2345 labels->Add(label, zone()); |
2334 // Remove the "ghost" variable that turned out to be a label | 2346 // Remove the "ghost" variable that turned out to be a label |
2335 // from the top scope. This way, we don't try to resolve it | 2347 // from the top scope. This way, we don't try to resolve it |
2336 // during the scope processing. | 2348 // during the scope processing. |
2337 scope_->RemoveUnresolved(var); | 2349 scope_->RemoveUnresolved(var); |
2338 Expect(Token::COLON, CHECK_OK); | 2350 Expect(Token::COLON, CHECK_OK); |
2339 return ParseStatement(labels, ok); | 2351 return ParseStatement(labels, ok); |
2340 } | 2352 } |
2341 | 2353 |
2342 // If we have an extension, we allow a native function declaration. | 2354 // If we have an extension, we allow a native function declaration. |
2343 // A native function declaration starts with "native function" with | 2355 // A native function declaration starts with "native function" with |
2344 // no line-terminator between the two words. | 2356 // no line-terminator between the two words. |
2345 if (extension_ != NULL && | 2357 if (extension_ != NULL && |
2346 peek() == Token::FUNCTION && | 2358 peek() == Token::FUNCTION && |
2347 !scanner()->HasAnyLineTerminatorBeforeNext() && | 2359 !scanner()->HasAnyLineTerminatorBeforeNext() && |
2348 expr != NULL && | 2360 expr != NULL && |
2349 expr->AsVariableProxy() != NULL && | 2361 expr->AsVariableProxy() != NULL && |
2350 String::Equals(isolate()->factory()->native_string(), | 2362 expr->AsVariableProxy()->raw_name() == |
2351 expr->AsVariableProxy()->name()) && | 2363 ast_value_factory_->native_string() && |
2352 !scanner()->literal_contains_escapes()) { | 2364 !scanner()->literal_contains_escapes()) { |
2353 return ParseNativeDeclaration(ok); | 2365 return ParseNativeDeclaration(ok); |
2354 } | 2366 } |
2355 | 2367 |
2356 // Parsed expression statement, or the context-sensitive 'module' keyword. | 2368 // Parsed expression statement, or the context-sensitive 'module' keyword. |
2357 // Only expect semicolon in the former case. | 2369 // Only expect semicolon in the former case. |
2358 if (!FLAG_harmony_modules || | 2370 if (!FLAG_harmony_modules || |
2359 peek() != Token::IDENTIFIER || | 2371 peek() != Token::IDENTIFIER || |
2360 scanner()->HasAnyLineTerminatorBeforeNext() || | 2372 scanner()->HasAnyLineTerminatorBeforeNext() || |
2361 expr->AsVariableProxy() == NULL || | 2373 expr->AsVariableProxy() == NULL || |
2362 !String::Equals(isolate()->factory()->module_string(), | 2374 expr->AsVariableProxy()->raw_name() != |
2363 expr->AsVariableProxy()->name()) || | 2375 ast_value_factory_->module_string() || |
2364 scanner()->literal_contains_escapes()) { | 2376 scanner()->literal_contains_escapes()) { |
2365 ExpectSemicolon(CHECK_OK); | 2377 ExpectSemicolon(CHECK_OK); |
2366 } | 2378 } |
2367 return factory()->NewExpressionStatement(expr, pos); | 2379 return factory()->NewExpressionStatement(expr, pos); |
2368 } | 2380 } |
2369 | 2381 |
2370 | 2382 |
2371 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { | 2383 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels, |
| 2384 bool* ok) { |
2372 // IfStatement :: | 2385 // IfStatement :: |
2373 // 'if' '(' Expression ')' Statement ('else' Statement)? | 2386 // 'if' '(' Expression ')' Statement ('else' Statement)? |
2374 | 2387 |
2375 int pos = peek_position(); | 2388 int pos = peek_position(); |
2376 Expect(Token::IF, CHECK_OK); | 2389 Expect(Token::IF, CHECK_OK); |
2377 Expect(Token::LPAREN, CHECK_OK); | 2390 Expect(Token::LPAREN, CHECK_OK); |
2378 Expression* condition = ParseExpression(true, CHECK_OK); | 2391 Expression* condition = ParseExpression(true, CHECK_OK); |
2379 Expect(Token::RPAREN, CHECK_OK); | 2392 Expect(Token::RPAREN, CHECK_OK); |
2380 Statement* then_statement = ParseStatement(labels, CHECK_OK); | 2393 Statement* then_statement = ParseStatement(labels, CHECK_OK); |
2381 Statement* else_statement = NULL; | 2394 Statement* else_statement = NULL; |
2382 if (peek() == Token::ELSE) { | 2395 if (peek() == Token::ELSE) { |
2383 Next(); | 2396 Next(); |
2384 else_statement = ParseStatement(labels, CHECK_OK); | 2397 else_statement = ParseStatement(labels, CHECK_OK); |
2385 } else { | 2398 } else { |
2386 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 2399 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
2387 } | 2400 } |
2388 return factory()->NewIfStatement( | 2401 return factory()->NewIfStatement( |
2389 condition, then_statement, else_statement, pos); | 2402 condition, then_statement, else_statement, pos); |
2390 } | 2403 } |
2391 | 2404 |
2392 | 2405 |
2393 Statement* Parser::ParseContinueStatement(bool* ok) { | 2406 Statement* Parser::ParseContinueStatement(bool* ok) { |
2394 // ContinueStatement :: | 2407 // ContinueStatement :: |
2395 // 'continue' Identifier? ';' | 2408 // 'continue' Identifier? ';' |
2396 | 2409 |
2397 int pos = peek_position(); | 2410 int pos = peek_position(); |
2398 Expect(Token::CONTINUE, CHECK_OK); | 2411 Expect(Token::CONTINUE, CHECK_OK); |
2399 Handle<String> label = Handle<String>::null(); | 2412 const AstRawString* label = NULL; |
2400 Token::Value tok = peek(); | 2413 Token::Value tok = peek(); |
2401 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2414 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
2402 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2415 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
2403 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 2416 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
2404 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 2417 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
2405 } | 2418 } |
2406 IterationStatement* target = NULL; | 2419 IterationStatement* target = LookupContinueTarget(label, CHECK_OK); |
2407 target = LookupContinueTarget(label, CHECK_OK); | |
2408 if (target == NULL) { | 2420 if (target == NULL) { |
2409 // Illegal continue statement. | 2421 // Illegal continue statement. |
2410 const char* message = "illegal_continue"; | 2422 const char* message = "illegal_continue"; |
2411 if (!label.is_null()) { | 2423 if (label != NULL) { |
2412 message = "unknown_label"; | 2424 message = "unknown_label"; |
2413 } | 2425 } |
2414 ParserTraits::ReportMessage(message, label); | 2426 ParserTraits::ReportMessage(message, label); |
2415 *ok = false; | 2427 *ok = false; |
2416 return NULL; | 2428 return NULL; |
2417 } | 2429 } |
2418 ExpectSemicolon(CHECK_OK); | 2430 ExpectSemicolon(CHECK_OK); |
2419 return factory()->NewContinueStatement(target, pos); | 2431 return factory()->NewContinueStatement(target, pos); |
2420 } | 2432 } |
2421 | 2433 |
2422 | 2434 |
2423 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { | 2435 Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels, |
| 2436 bool* ok) { |
2424 // BreakStatement :: | 2437 // BreakStatement :: |
2425 // 'break' Identifier? ';' | 2438 // 'break' Identifier? ';' |
2426 | 2439 |
2427 int pos = peek_position(); | 2440 int pos = peek_position(); |
2428 Expect(Token::BREAK, CHECK_OK); | 2441 Expect(Token::BREAK, CHECK_OK); |
2429 Handle<String> label; | 2442 const AstRawString* label = NULL; |
2430 Token::Value tok = peek(); | 2443 Token::Value tok = peek(); |
2431 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2444 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
2432 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2445 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
2433 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 2446 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
2434 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 2447 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
2435 } | 2448 } |
2436 // Parse labeled break statements that target themselves into | 2449 // Parse labeled break statements that target themselves into |
2437 // empty statements, e.g. 'l1: l2: l3: break l2;' | 2450 // empty statements, e.g. 'l1: l2: l3: break l2;' |
2438 if (!label.is_null() && ContainsLabel(labels, label)) { | 2451 if (label != NULL && ContainsLabel(labels, label)) { |
2439 ExpectSemicolon(CHECK_OK); | 2452 ExpectSemicolon(CHECK_OK); |
2440 return factory()->NewEmptyStatement(pos); | 2453 return factory()->NewEmptyStatement(pos); |
2441 } | 2454 } |
2442 BreakableStatement* target = NULL; | 2455 BreakableStatement* target = NULL; |
2443 target = LookupBreakTarget(label, CHECK_OK); | 2456 target = LookupBreakTarget(label, CHECK_OK); |
2444 if (target == NULL) { | 2457 if (target == NULL) { |
2445 // Illegal break statement. | 2458 // Illegal break statement. |
2446 const char* message = "illegal_break"; | 2459 const char* message = "illegal_break"; |
2447 if (!label.is_null()) { | 2460 if (label != NULL) { |
2448 message = "unknown_label"; | 2461 message = "unknown_label"; |
2449 } | 2462 } |
2450 ParserTraits::ReportMessage(message, label); | 2463 ParserTraits::ReportMessage(message, label); |
2451 *ok = false; | 2464 *ok = false; |
2452 return NULL; | 2465 return NULL; |
2453 } | 2466 } |
2454 ExpectSemicolon(CHECK_OK); | 2467 ExpectSemicolon(CHECK_OK); |
2455 return factory()->NewBreakStatement(target, pos); | 2468 return factory()->NewBreakStatement(target, pos); |
2456 } | 2469 } |
2457 | 2470 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2491 Scope* decl_scope = scope_->DeclarationScope(); | 2504 Scope* decl_scope = scope_->DeclarationScope(); |
2492 if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) { | 2505 if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) { |
2493 ReportMessageAt(loc, "illegal_return"); | 2506 ReportMessageAt(loc, "illegal_return"); |
2494 *ok = false; | 2507 *ok = false; |
2495 return NULL; | 2508 return NULL; |
2496 } | 2509 } |
2497 return result; | 2510 return result; |
2498 } | 2511 } |
2499 | 2512 |
2500 | 2513 |
2501 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 2514 Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels, |
| 2515 bool* ok) { |
2502 // WithStatement :: | 2516 // WithStatement :: |
2503 // 'with' '(' Expression ')' Statement | 2517 // 'with' '(' Expression ')' Statement |
2504 | 2518 |
2505 Expect(Token::WITH, CHECK_OK); | 2519 Expect(Token::WITH, CHECK_OK); |
2506 int pos = position(); | 2520 int pos = position(); |
2507 | 2521 |
2508 if (strict_mode() == STRICT) { | 2522 if (strict_mode() == STRICT) { |
2509 ReportMessage("strict_mode_with"); | 2523 ReportMessage("strict_mode_with"); |
2510 *ok = false; | 2524 *ok = false; |
2511 return NULL; | 2525 return NULL; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2553 peek() != Token::DEFAULT && | 2567 peek() != Token::DEFAULT && |
2554 peek() != Token::RBRACE) { | 2568 peek() != Token::RBRACE) { |
2555 Statement* stat = ParseStatement(NULL, CHECK_OK); | 2569 Statement* stat = ParseStatement(NULL, CHECK_OK); |
2556 statements->Add(stat, zone()); | 2570 statements->Add(stat, zone()); |
2557 } | 2571 } |
2558 | 2572 |
2559 return factory()->NewCaseClause(label, statements, pos); | 2573 return factory()->NewCaseClause(label, statements, pos); |
2560 } | 2574 } |
2561 | 2575 |
2562 | 2576 |
2563 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, | 2577 SwitchStatement* Parser::ParseSwitchStatement( |
2564 bool* ok) { | 2578 ZoneList<const AstRawString*>* labels, bool* ok) { |
2565 // SwitchStatement :: | 2579 // SwitchStatement :: |
2566 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 2580 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
2567 | 2581 |
2568 SwitchStatement* statement = | 2582 SwitchStatement* statement = |
2569 factory()->NewSwitchStatement(labels, peek_position()); | 2583 factory()->NewSwitchStatement(labels, peek_position()); |
2570 Target target(&this->target_stack_, statement); | 2584 Target target(&this->target_stack_, statement); |
2571 | 2585 |
2572 Expect(Token::SWITCH, CHECK_OK); | 2586 Expect(Token::SWITCH, CHECK_OK); |
2573 Expect(Token::LPAREN, CHECK_OK); | 2587 Expect(Token::LPAREN, CHECK_OK); |
2574 Expression* tag = ParseExpression(true, CHECK_OK); | 2588 Expression* tag = ParseExpression(true, CHECK_OK); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2637 } | 2651 } |
2638 | 2652 |
2639 // If we can break out from the catch block and there is a finally block, | 2653 // If we can break out from the catch block and there is a finally block, |
2640 // then we will need to collect escaping targets from the catch | 2654 // then we will need to collect escaping targets from the catch |
2641 // block. Since we don't know yet if there will be a finally block, we | 2655 // block. Since we don't know yet if there will be a finally block, we |
2642 // always collect the targets. | 2656 // always collect the targets. |
2643 TargetCollector catch_collector(zone()); | 2657 TargetCollector catch_collector(zone()); |
2644 Scope* catch_scope = NULL; | 2658 Scope* catch_scope = NULL; |
2645 Variable* catch_variable = NULL; | 2659 Variable* catch_variable = NULL; |
2646 Block* catch_block = NULL; | 2660 Block* catch_block = NULL; |
2647 Handle<String> name; | 2661 const AstRawString* name = NULL; |
2648 if (tok == Token::CATCH) { | 2662 if (tok == Token::CATCH) { |
2649 Consume(Token::CATCH); | 2663 Consume(Token::CATCH); |
2650 | 2664 |
2651 Expect(Token::LPAREN, CHECK_OK); | 2665 Expect(Token::LPAREN, CHECK_OK); |
2652 catch_scope = NewScope(scope_, CATCH_SCOPE); | 2666 catch_scope = NewScope(scope_, CATCH_SCOPE); |
2653 catch_scope->set_start_position(scanner()->location().beg_pos); | 2667 catch_scope->set_start_position(scanner()->location().beg_pos); |
2654 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2668 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
2655 | 2669 |
2656 Expect(Token::RPAREN, CHECK_OK); | 2670 Expect(Token::RPAREN, CHECK_OK); |
2657 | 2671 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2707 index, try_block, finally_block, pos); | 2721 index, try_block, finally_block, pos); |
2708 // Combine the jump targets of the try block and the possible catch block. | 2722 // Combine the jump targets of the try block and the possible catch block. |
2709 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); | 2723 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); |
2710 } | 2724 } |
2711 | 2725 |
2712 result->set_escaping_targets(try_collector.targets()); | 2726 result->set_escaping_targets(try_collector.targets()); |
2713 return result; | 2727 return result; |
2714 } | 2728 } |
2715 | 2729 |
2716 | 2730 |
2717 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, | 2731 DoWhileStatement* Parser::ParseDoWhileStatement( |
2718 bool* ok) { | 2732 ZoneList<const AstRawString*>* labels, bool* ok) { |
2719 // DoStatement :: | 2733 // DoStatement :: |
2720 // 'do' Statement 'while' '(' Expression ')' ';' | 2734 // 'do' Statement 'while' '(' Expression ')' ';' |
2721 | 2735 |
2722 DoWhileStatement* loop = | 2736 DoWhileStatement* loop = |
2723 factory()->NewDoWhileStatement(labels, peek_position()); | 2737 factory()->NewDoWhileStatement(labels, peek_position()); |
2724 Target target(&this->target_stack_, loop); | 2738 Target target(&this->target_stack_, loop); |
2725 | 2739 |
2726 Expect(Token::DO, CHECK_OK); | 2740 Expect(Token::DO, CHECK_OK); |
2727 Statement* body = ParseStatement(NULL, CHECK_OK); | 2741 Statement* body = ParseStatement(NULL, CHECK_OK); |
2728 Expect(Token::WHILE, CHECK_OK); | 2742 Expect(Token::WHILE, CHECK_OK); |
2729 Expect(Token::LPAREN, CHECK_OK); | 2743 Expect(Token::LPAREN, CHECK_OK); |
2730 | 2744 |
2731 Expression* cond = ParseExpression(true, CHECK_OK); | 2745 Expression* cond = ParseExpression(true, CHECK_OK); |
2732 Expect(Token::RPAREN, CHECK_OK); | 2746 Expect(Token::RPAREN, CHECK_OK); |
2733 | 2747 |
2734 // Allow do-statements to be terminated with and without | 2748 // Allow do-statements to be terminated with and without |
2735 // semi-colons. This allows code such as 'do;while(0)return' to | 2749 // semi-colons. This allows code such as 'do;while(0)return' to |
2736 // parse, which would not be the case if we had used the | 2750 // parse, which would not be the case if we had used the |
2737 // ExpectSemicolon() functionality here. | 2751 // ExpectSemicolon() functionality here. |
2738 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); | 2752 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); |
2739 | 2753 |
2740 if (loop != NULL) loop->Initialize(cond, body); | 2754 if (loop != NULL) loop->Initialize(cond, body); |
2741 return loop; | 2755 return loop; |
2742 } | 2756 } |
2743 | 2757 |
2744 | 2758 |
2745 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { | 2759 WhileStatement* Parser::ParseWhileStatement( |
| 2760 ZoneList<const AstRawString*>* labels, bool* ok) { |
2746 // WhileStatement :: | 2761 // WhileStatement :: |
2747 // 'while' '(' Expression ')' Statement | 2762 // 'while' '(' Expression ')' Statement |
2748 | 2763 |
2749 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); | 2764 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); |
2750 Target target(&this->target_stack_, loop); | 2765 Target target(&this->target_stack_, loop); |
2751 | 2766 |
2752 Expect(Token::WHILE, CHECK_OK); | 2767 Expect(Token::WHILE, CHECK_OK); |
2753 Expect(Token::LPAREN, CHECK_OK); | 2768 Expect(Token::LPAREN, CHECK_OK); |
2754 Expression* cond = ParseExpression(true, CHECK_OK); | 2769 Expression* cond = ParseExpression(true, CHECK_OK); |
2755 Expect(Token::RPAREN, CHECK_OK); | 2770 Expect(Token::RPAREN, CHECK_OK); |
(...skipping 18 matching lines...) Expand all Loading... |
2774 } | 2789 } |
2775 | 2790 |
2776 | 2791 |
2777 void Parser::InitializeForEachStatement(ForEachStatement* stmt, | 2792 void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
2778 Expression* each, | 2793 Expression* each, |
2779 Expression* subject, | 2794 Expression* subject, |
2780 Statement* body) { | 2795 Statement* body) { |
2781 ForOfStatement* for_of = stmt->AsForOfStatement(); | 2796 ForOfStatement* for_of = stmt->AsForOfStatement(); |
2782 | 2797 |
2783 if (for_of != NULL) { | 2798 if (for_of != NULL) { |
2784 Factory* heap_factory = isolate()->factory(); | |
2785 Variable* iterable = scope_->DeclarationScope()->NewTemporary( | 2799 Variable* iterable = scope_->DeclarationScope()->NewTemporary( |
2786 heap_factory->dot_iterable_string()); | 2800 ast_value_factory_->dot_iterable_string()); |
2787 Variable* iterator = scope_->DeclarationScope()->NewTemporary( | 2801 Variable* iterator = scope_->DeclarationScope()->NewTemporary( |
2788 heap_factory->dot_iterator_string()); | 2802 ast_value_factory_->dot_iterator_string()); |
2789 Variable* result = scope_->DeclarationScope()->NewTemporary( | 2803 Variable* result = scope_->DeclarationScope()->NewTemporary( |
2790 heap_factory->dot_result_string()); | 2804 ast_value_factory_->dot_result_string()); |
2791 | 2805 |
2792 Expression* assign_iterable; | 2806 Expression* assign_iterable; |
2793 Expression* assign_iterator; | 2807 Expression* assign_iterator; |
2794 Expression* next_result; | 2808 Expression* next_result; |
2795 Expression* result_done; | 2809 Expression* result_done; |
2796 Expression* assign_each; | 2810 Expression* assign_each; |
2797 | 2811 |
2798 // var iterable = subject; | 2812 // var iterable = subject; |
2799 { | 2813 { |
2800 Expression* iterable_proxy = factory()->NewVariableProxy(iterable); | 2814 Expression* iterable_proxy = factory()->NewVariableProxy(iterable); |
2801 assign_iterable = factory()->NewAssignment( | 2815 assign_iterable = factory()->NewAssignment( |
2802 Token::ASSIGN, iterable_proxy, subject, subject->position()); | 2816 Token::ASSIGN, iterable_proxy, subject, subject->position()); |
2803 } | 2817 } |
2804 | 2818 |
2805 // var iterator = iterable[Symbol.iterator](); | 2819 // var iterator = iterable[Symbol.iterator](); |
2806 { | 2820 { |
2807 Expression* iterable_proxy = factory()->NewVariableProxy(iterable); | 2821 Expression* iterable_proxy = factory()->NewVariableProxy(iterable); |
2808 Handle<Symbol> iterator_symbol( | 2822 Expression* iterator_symbol_literal = |
2809 isolate()->native_context()->iterator_symbol(), isolate()); | 2823 factory()->NewSymbolLiteral("symbolIterator", RelocInfo::kNoPosition); |
2810 Expression* iterator_symbol_literal = factory()->NewLiteral( | |
2811 iterator_symbol, RelocInfo::kNoPosition); | |
2812 // FIXME(wingo): Unhappily, it will be a common error that the RHS of a | 2824 // FIXME(wingo): Unhappily, it will be a common error that the RHS of a |
2813 // for-of doesn't have a Symbol.iterator property. We should do better | 2825 // for-of doesn't have a Symbol.iterator property. We should do better |
2814 // than informing the user that "undefined is not a function". | 2826 // than informing the user that "undefined is not a function". |
2815 int pos = subject->position(); | 2827 int pos = subject->position(); |
2816 Expression* iterator_property = factory()->NewProperty( | 2828 Expression* iterator_property = factory()->NewProperty( |
2817 iterable_proxy, iterator_symbol_literal, pos); | 2829 iterable_proxy, iterator_symbol_literal, pos); |
2818 ZoneList<Expression*>* iterator_arguments = | 2830 ZoneList<Expression*>* iterator_arguments = |
2819 new(zone()) ZoneList<Expression*>(0, zone()); | 2831 new(zone()) ZoneList<Expression*>(0, zone()); |
2820 Expression* iterator_call = factory()->NewCall( | 2832 Expression* iterator_call = factory()->NewCall( |
2821 iterator_property, iterator_arguments, pos); | 2833 iterator_property, iterator_arguments, pos); |
2822 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2834 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
2823 assign_iterator = factory()->NewAssignment( | 2835 assign_iterator = factory()->NewAssignment( |
2824 Token::ASSIGN, iterator_proxy, iterator_call, RelocInfo::kNoPosition); | 2836 Token::ASSIGN, iterator_proxy, iterator_call, RelocInfo::kNoPosition); |
2825 } | 2837 } |
2826 | 2838 |
2827 // var result = iterator.next(); | 2839 // var result = iterator.next(); |
2828 { | 2840 { |
2829 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2841 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
2830 Expression* next_literal = factory()->NewLiteral( | 2842 Expression* next_literal = factory()->NewStringLiteral( |
2831 heap_factory->next_string(), RelocInfo::kNoPosition); | 2843 ast_value_factory_->next_string(), RelocInfo::kNoPosition); |
2832 Expression* next_property = factory()->NewProperty( | 2844 Expression* next_property = factory()->NewProperty( |
2833 iterator_proxy, next_literal, RelocInfo::kNoPosition); | 2845 iterator_proxy, next_literal, RelocInfo::kNoPosition); |
2834 ZoneList<Expression*>* next_arguments = | 2846 ZoneList<Expression*>* next_arguments = |
2835 new(zone()) ZoneList<Expression*>(0, zone()); | 2847 new(zone()) ZoneList<Expression*>(0, zone()); |
2836 Expression* next_call = factory()->NewCall( | 2848 Expression* next_call = factory()->NewCall( |
2837 next_property, next_arguments, RelocInfo::kNoPosition); | 2849 next_property, next_arguments, RelocInfo::kNoPosition); |
2838 Expression* result_proxy = factory()->NewVariableProxy(result); | 2850 Expression* result_proxy = factory()->NewVariableProxy(result); |
2839 next_result = factory()->NewAssignment( | 2851 next_result = factory()->NewAssignment( |
2840 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); | 2852 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); |
2841 } | 2853 } |
2842 | 2854 |
2843 // result.done | 2855 // result.done |
2844 { | 2856 { |
2845 Expression* done_literal = factory()->NewLiteral( | 2857 Expression* done_literal = factory()->NewStringLiteral( |
2846 heap_factory->done_string(), RelocInfo::kNoPosition); | 2858 ast_value_factory_->done_string(), RelocInfo::kNoPosition); |
2847 Expression* result_proxy = factory()->NewVariableProxy(result); | 2859 Expression* result_proxy = factory()->NewVariableProxy(result); |
2848 result_done = factory()->NewProperty( | 2860 result_done = factory()->NewProperty( |
2849 result_proxy, done_literal, RelocInfo::kNoPosition); | 2861 result_proxy, done_literal, RelocInfo::kNoPosition); |
2850 } | 2862 } |
2851 | 2863 |
2852 // each = result.value | 2864 // each = result.value |
2853 { | 2865 { |
2854 Expression* value_literal = factory()->NewLiteral( | 2866 Expression* value_literal = factory()->NewStringLiteral( |
2855 heap_factory->value_string(), RelocInfo::kNoPosition); | 2867 ast_value_factory_->value_string(), RelocInfo::kNoPosition); |
2856 Expression* result_proxy = factory()->NewVariableProxy(result); | 2868 Expression* result_proxy = factory()->NewVariableProxy(result); |
2857 Expression* result_value = factory()->NewProperty( | 2869 Expression* result_value = factory()->NewProperty( |
2858 result_proxy, value_literal, RelocInfo::kNoPosition); | 2870 result_proxy, value_literal, RelocInfo::kNoPosition); |
2859 assign_each = factory()->NewAssignment( | 2871 assign_each = factory()->NewAssignment( |
2860 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); | 2872 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); |
2861 } | 2873 } |
2862 | 2874 |
2863 for_of->Initialize(each, subject, body, | 2875 for_of->Initialize(each, subject, body, |
2864 assign_iterable, | 2876 assign_iterable, |
2865 assign_iterator, | 2877 assign_iterator, |
2866 next_result, | 2878 next_result, |
2867 result_done, | 2879 result_done, |
2868 assign_each); | 2880 assign_each); |
2869 } else { | 2881 } else { |
2870 stmt->Initialize(each, subject, body); | 2882 stmt->Initialize(each, subject, body); |
2871 } | 2883 } |
2872 } | 2884 } |
2873 | 2885 |
2874 | 2886 |
2875 Statement* Parser::DesugarLetBindingsInForStatement( | 2887 Statement* Parser::DesugarLetBindingsInForStatement( |
2876 Scope* inner_scope, ZoneStringList* names, ForStatement* loop, | 2888 Scope* inner_scope, ZoneList<const AstRawString*>* names, |
2877 Statement* init, Expression* cond, Statement* next, Statement* body, | 2889 ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
2878 bool* ok) { | 2890 Statement* body, bool* ok) { |
2879 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are | 2891 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are |
2880 // copied into a new environment. After copying, the "next" statement of the | 2892 // copied into a new environment. After copying, the "next" statement of the |
2881 // loop is executed to update the loop variables. The loop condition is | 2893 // loop is executed to update the loop variables. The loop condition is |
2882 // checked and the loop body is executed. | 2894 // checked and the loop body is executed. |
2883 // | 2895 // |
2884 // We rewrite a for statement of the form | 2896 // We rewrite a for statement of the form |
2885 // | 2897 // |
2886 // for (let x = i; cond; next) body | 2898 // for (let x = i; cond; next) body |
2887 // | 2899 // |
2888 // into | 2900 // into |
(...skipping 20 matching lines...) Expand all Loading... |
2909 // } | 2921 // } |
2910 | 2922 |
2911 ASSERT(names->length() > 0); | 2923 ASSERT(names->length() > 0); |
2912 Scope* for_scope = scope_; | 2924 Scope* for_scope = scope_; |
2913 ZoneList<Variable*> temps(names->length(), zone()); | 2925 ZoneList<Variable*> temps(names->length(), zone()); |
2914 | 2926 |
2915 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false, | 2927 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false, |
2916 RelocInfo::kNoPosition); | 2928 RelocInfo::kNoPosition); |
2917 outer_block->AddStatement(init, zone()); | 2929 outer_block->AddStatement(init, zone()); |
2918 | 2930 |
2919 Handle<String> temp_name = isolate()->factory()->dot_for_string(); | 2931 const AstRawString* temp_name = ast_value_factory_->dot_for_string(); |
2920 Handle<Smi> smi0 = handle(Smi::FromInt(0), isolate()); | |
2921 Handle<Smi> smi1 = handle(Smi::FromInt(1), isolate()); | |
2922 | |
2923 | 2932 |
2924 // For each let variable x: | 2933 // For each let variable x: |
2925 // make statement: temp_x = x. | 2934 // make statement: temp_x = x. |
2926 for (int i = 0; i < names->length(); i++) { | 2935 for (int i = 0; i < names->length(); i++) { |
2927 VariableProxy* proxy = | 2936 VariableProxy* proxy = |
2928 NewUnresolved(names->at(i), LET, Interface::NewValue()); | 2937 NewUnresolved(names->at(i), LET, Interface::NewValue()); |
2929 Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name); | 2938 Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name); |
2930 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 2939 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
2931 Assignment* assignment = factory()->NewAssignment( | 2940 Assignment* assignment = factory()->NewAssignment( |
2932 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition); | 2941 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition); |
2933 Statement* assignment_statement = factory()->NewExpressionStatement( | 2942 Statement* assignment_statement = factory()->NewExpressionStatement( |
2934 assignment, RelocInfo::kNoPosition); | 2943 assignment, RelocInfo::kNoPosition); |
2935 outer_block->AddStatement(assignment_statement, zone()); | 2944 outer_block->AddStatement(assignment_statement, zone()); |
2936 temps.Add(temp, zone()); | 2945 temps.Add(temp, zone()); |
2937 } | 2946 } |
2938 | 2947 |
2939 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name); | 2948 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name); |
2940 // Make statement: flag = 1. | 2949 // Make statement: flag = 1. |
2941 { | 2950 { |
2942 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); | 2951 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); |
2943 Expression* const1 = factory()->NewLiteral(smi1, RelocInfo::kNoPosition); | 2952 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); |
2944 Assignment* assignment = factory()->NewAssignment( | 2953 Assignment* assignment = factory()->NewAssignment( |
2945 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition); | 2954 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition); |
2946 Statement* assignment_statement = factory()->NewExpressionStatement( | 2955 Statement* assignment_statement = factory()->NewExpressionStatement( |
2947 assignment, RelocInfo::kNoPosition); | 2956 assignment, RelocInfo::kNoPosition); |
2948 outer_block->AddStatement(assignment_statement, zone()); | 2957 outer_block->AddStatement(assignment_statement, zone()); |
2949 } | 2958 } |
2950 | 2959 |
2951 outer_block->AddStatement(loop, zone()); | 2960 outer_block->AddStatement(loop, zone()); |
2952 outer_block->set_scope(for_scope); | 2961 outer_block->set_scope(for_scope); |
2953 scope_ = inner_scope; | 2962 scope_ = inner_scope; |
(...skipping 19 matching lines...) Expand all Loading... |
2973 assignment, pos); | 2982 assignment, pos); |
2974 proxy->var()->set_initializer_position(pos); | 2983 proxy->var()->set_initializer_position(pos); |
2975 inner_block->AddStatement(assignment_statement, zone()); | 2984 inner_block->AddStatement(assignment_statement, zone()); |
2976 } | 2985 } |
2977 | 2986 |
2978 // Make statement: if (flag == 1) { flag = 0; } else { next; }. | 2987 // Make statement: if (flag == 1) { flag = 0; } else { next; }. |
2979 { | 2988 { |
2980 Expression* compare = NULL; | 2989 Expression* compare = NULL; |
2981 // Make compare expresion: flag == 1. | 2990 // Make compare expresion: flag == 1. |
2982 { | 2991 { |
2983 Expression* const1 = factory()->NewLiteral(smi1, RelocInfo::kNoPosition); | 2992 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); |
2984 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); | 2993 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); |
2985 compare = factory()->NewCompareOperation( | 2994 compare = factory()->NewCompareOperation( |
2986 Token::EQ, flag_proxy, const1, pos); | 2995 Token::EQ, flag_proxy, const1, pos); |
2987 } | 2996 } |
2988 Statement* clear_flag = NULL; | 2997 Statement* clear_flag = NULL; |
2989 // Make statement: flag = 0. | 2998 // Make statement: flag = 0. |
2990 { | 2999 { |
2991 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); | 3000 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); |
2992 Expression* const0 = factory()->NewLiteral(smi0, RelocInfo::kNoPosition); | 3001 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition); |
2993 Assignment* assignment = factory()->NewAssignment( | 3002 Assignment* assignment = factory()->NewAssignment( |
2994 Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition); | 3003 Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition); |
2995 clear_flag = factory()->NewExpressionStatement(assignment, pos); | 3004 clear_flag = factory()->NewExpressionStatement(assignment, pos); |
2996 } | 3005 } |
2997 Statement* clear_flag_or_next = factory()->NewIfStatement( | 3006 Statement* clear_flag_or_next = factory()->NewIfStatement( |
2998 compare, clear_flag, next, RelocInfo::kNoPosition); | 3007 compare, clear_flag, next, RelocInfo::kNoPosition); |
2999 inner_block->AddStatement(clear_flag_or_next, zone()); | 3008 inner_block->AddStatement(clear_flag_or_next, zone()); |
3000 } | 3009 } |
3001 | 3010 |
3002 | 3011 |
3003 // Make statement: if (cond) { } else { break; }. | 3012 // Make statement: if (cond) { } else { break; }. |
3004 { | 3013 { |
3005 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 3014 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
3006 BreakableStatement* t = LookupBreakTarget(Handle<String>(), CHECK_OK); | 3015 BreakableStatement* t = LookupBreakTarget(NULL, CHECK_OK); |
3007 Statement* stop = factory()->NewBreakStatement(t, RelocInfo::kNoPosition); | 3016 Statement* stop = factory()->NewBreakStatement(t, RelocInfo::kNoPosition); |
3008 Statement* if_not_cond_break = factory()->NewIfStatement( | 3017 Statement* if_not_cond_break = factory()->NewIfStatement( |
3009 cond, empty, stop, cond->position()); | 3018 cond, empty, stop, cond->position()); |
3010 inner_block->AddStatement(if_not_cond_break, zone()); | 3019 inner_block->AddStatement(if_not_cond_break, zone()); |
3011 } | 3020 } |
3012 | 3021 |
3013 inner_block->AddStatement(body, zone()); | 3022 inner_block->AddStatement(body, zone()); |
3014 | 3023 |
3015 // For each let variable x: | 3024 // For each let variable x: |
3016 // make statement: temp_x = x; | 3025 // make statement: temp_x = x; |
(...skipping 10 matching lines...) Expand all Loading... |
3027 | 3036 |
3028 inner_scope->set_end_position(scanner()->location().end_pos); | 3037 inner_scope->set_end_position(scanner()->location().end_pos); |
3029 inner_block->set_scope(inner_scope); | 3038 inner_block->set_scope(inner_scope); |
3030 scope_ = for_scope; | 3039 scope_ = for_scope; |
3031 | 3040 |
3032 loop->Initialize(NULL, NULL, NULL, inner_block); | 3041 loop->Initialize(NULL, NULL, NULL, inner_block); |
3033 return outer_block; | 3042 return outer_block; |
3034 } | 3043 } |
3035 | 3044 |
3036 | 3045 |
3037 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 3046 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, |
| 3047 bool* ok) { |
3038 // ForStatement :: | 3048 // ForStatement :: |
3039 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 3049 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
3040 | 3050 |
3041 int pos = peek_position(); | 3051 int pos = peek_position(); |
3042 Statement* init = NULL; | 3052 Statement* init = NULL; |
3043 ZoneStringList let_bindings(1, zone()); | 3053 ZoneList<const AstRawString*> let_bindings(1, zone()); |
3044 | 3054 |
3045 // Create an in-between scope for let-bound iteration variables. | 3055 // Create an in-between scope for let-bound iteration variables. |
3046 Scope* saved_scope = scope_; | 3056 Scope* saved_scope = scope_; |
3047 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); | 3057 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); |
3048 scope_ = for_scope; | 3058 scope_ = for_scope; |
3049 | 3059 |
3050 Expect(Token::FOR, CHECK_OK); | 3060 Expect(Token::FOR, CHECK_OK); |
3051 Expect(Token::LPAREN, CHECK_OK); | 3061 Expect(Token::LPAREN, CHECK_OK); |
3052 for_scope->set_start_position(scanner()->location().beg_pos); | 3062 for_scope->set_start_position(scanner()->location().beg_pos); |
3053 if (peek() != Token::SEMICOLON) { | 3063 if (peek() != Token::SEMICOLON) { |
3054 if (peek() == Token::VAR || peek() == Token::CONST) { | 3064 if (peek() == Token::VAR || peek() == Token::CONST) { |
3055 bool is_const = peek() == Token::CONST; | 3065 bool is_const = peek() == Token::CONST; |
3056 Handle<String> name; | 3066 const AstRawString* name = NULL; |
3057 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3067 VariableDeclarationProperties decl_props = kHasNoInitializers; |
3058 Block* variable_statement = | 3068 Block* variable_statement = |
3059 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 3069 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
3060 CHECK_OK); | 3070 CHECK_OK); |
3061 bool accept_OF = decl_props == kHasNoInitializers; | 3071 bool accept_OF = decl_props == kHasNoInitializers; |
3062 ForEachStatement::VisitMode mode; | 3072 ForEachStatement::VisitMode mode; |
3063 | 3073 |
3064 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { | 3074 if (name != NULL && CheckInOrOf(accept_OF, &mode)) { |
3065 Interface* interface = | 3075 Interface* interface = |
3066 is_const ? Interface::NewConst() : Interface::NewValue(); | 3076 is_const ? Interface::NewConst() : Interface::NewValue(); |
3067 ForEachStatement* loop = | 3077 ForEachStatement* loop = |
3068 factory()->NewForEachStatement(mode, labels, pos); | 3078 factory()->NewForEachStatement(mode, labels, pos); |
3069 Target target(&this->target_stack_, loop); | 3079 Target target(&this->target_stack_, loop); |
3070 | 3080 |
3071 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3081 Expression* enumerable = ParseExpression(true, CHECK_OK); |
3072 Expect(Token::RPAREN, CHECK_OK); | 3082 Expect(Token::RPAREN, CHECK_OK); |
3073 | 3083 |
3074 VariableProxy* each = | 3084 VariableProxy* each = |
3075 scope_->NewUnresolved(factory(), name, interface); | 3085 scope_->NewUnresolved(factory(), name, interface); |
3076 Statement* body = ParseStatement(NULL, CHECK_OK); | 3086 Statement* body = ParseStatement(NULL, CHECK_OK); |
3077 InitializeForEachStatement(loop, each, enumerable, body); | 3087 InitializeForEachStatement(loop, each, enumerable, body); |
3078 Block* result = | 3088 Block* result = |
3079 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 3089 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
3080 result->AddStatement(variable_statement, zone()); | 3090 result->AddStatement(variable_statement, zone()); |
3081 result->AddStatement(loop, zone()); | 3091 result->AddStatement(loop, zone()); |
3082 scope_ = saved_scope; | 3092 scope_ = saved_scope; |
3083 for_scope->set_end_position(scanner()->location().end_pos); | 3093 for_scope->set_end_position(scanner()->location().end_pos); |
3084 for_scope = for_scope->FinalizeBlockScope(); | 3094 for_scope = for_scope->FinalizeBlockScope(); |
3085 ASSERT(for_scope == NULL); | 3095 ASSERT(for_scope == NULL); |
3086 // Parsed for-in loop w/ variable/const declaration. | 3096 // Parsed for-in loop w/ variable/const declaration. |
3087 return result; | 3097 return result; |
3088 } else { | 3098 } else { |
3089 init = variable_statement; | 3099 init = variable_statement; |
3090 } | 3100 } |
3091 } else if (peek() == Token::LET) { | 3101 } else if (peek() == Token::LET) { |
3092 Handle<String> name; | 3102 const AstRawString* name = NULL; |
3093 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3103 VariableDeclarationProperties decl_props = kHasNoInitializers; |
3094 Block* variable_statement = | 3104 Block* variable_statement = |
3095 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, | 3105 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, |
3096 &name, CHECK_OK); | 3106 &name, CHECK_OK); |
3097 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; | 3107 bool accept_IN = name != NULL && decl_props != kHasInitializers; |
3098 bool accept_OF = decl_props == kHasNoInitializers; | 3108 bool accept_OF = decl_props == kHasNoInitializers; |
3099 ForEachStatement::VisitMode mode; | 3109 ForEachStatement::VisitMode mode; |
3100 | 3110 |
3101 if (accept_IN && CheckInOrOf(accept_OF, &mode)) { | 3111 if (accept_IN && CheckInOrOf(accept_OF, &mode)) { |
3102 // Rewrite a for-in statement of the form | 3112 // Rewrite a for-in statement of the form |
3103 // | 3113 // |
3104 // for (let x in e) b | 3114 // for (let x in e) b |
3105 // | 3115 // |
3106 // into | 3116 // into |
3107 // | 3117 // |
3108 // <let x' be a temporary variable> | 3118 // <let x' be a temporary variable> |
3109 // for (x' in e) { | 3119 // for (x' in e) { |
3110 // let x; | 3120 // let x; |
3111 // x = x'; | 3121 // x = x'; |
3112 // b; | 3122 // b; |
3113 // } | 3123 // } |
3114 | 3124 |
3115 // TODO(keuchel): Move the temporary variable to the block scope, after | 3125 // TODO(keuchel): Move the temporary variable to the block scope, after |
3116 // implementing stack allocated block scoped variables. | 3126 // implementing stack allocated block scoped variables. |
3117 Factory* heap_factory = isolate()->factory(); | 3127 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
3118 Handle<String> tempstr; | 3128 ast_value_factory_->dot_for_string()); |
3119 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
3120 isolate(), tempstr, | |
3121 heap_factory->NewConsString(heap_factory->dot_for_string(), name), | |
3122 0); | |
3123 Handle<String> tempname = heap_factory->InternalizeString(tempstr); | |
3124 Variable* temp = scope_->DeclarationScope()->NewTemporary(tempname); | |
3125 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 3129 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
3126 ForEachStatement* loop = | 3130 ForEachStatement* loop = |
3127 factory()->NewForEachStatement(mode, labels, pos); | 3131 factory()->NewForEachStatement(mode, labels, pos); |
3128 Target target(&this->target_stack_, loop); | 3132 Target target(&this->target_stack_, loop); |
3129 | 3133 |
3130 // The expression does not see the loop variable. | 3134 // The expression does not see the loop variable. |
3131 scope_ = saved_scope; | 3135 scope_ = saved_scope; |
3132 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3136 Expression* enumerable = ParseExpression(true, CHECK_OK); |
3133 scope_ = for_scope; | 3137 scope_ = for_scope; |
3134 Expect(Token::RPAREN, CHECK_OK); | 3138 Expect(Token::RPAREN, CHECK_OK); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3245 // DebuggerStatement :: | 3249 // DebuggerStatement :: |
3246 // 'debugger' ';' | 3250 // 'debugger' ';' |
3247 | 3251 |
3248 int pos = peek_position(); | 3252 int pos = peek_position(); |
3249 Expect(Token::DEBUGGER, CHECK_OK); | 3253 Expect(Token::DEBUGGER, CHECK_OK); |
3250 ExpectSemicolon(CHECK_OK); | 3254 ExpectSemicolon(CHECK_OK); |
3251 return factory()->NewDebuggerStatement(pos); | 3255 return factory()->NewDebuggerStatement(pos); |
3252 } | 3256 } |
3253 | 3257 |
3254 | 3258 |
3255 void Parser::ReportInvalidCachedData(Handle<String> name, bool* ok) { | 3259 void Parser::ReportInvalidCachedData(const AstRawString* name, bool* ok) { |
3256 ParserTraits::ReportMessage("invalid_cached_data_function", name); | 3260 ParserTraits::ReportMessage("invalid_cached_data_function", name); |
3257 *ok = false; | 3261 *ok = false; |
3258 } | 3262 } |
3259 | 3263 |
3260 | 3264 |
3261 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { | 3265 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { |
3262 if (expression->IsLiteral()) return true; | 3266 if (expression->IsLiteral()) return true; |
3263 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); | 3267 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); |
3264 return lit != NULL && lit->is_simple(); | 3268 return lit != NULL && lit->is_simple(); |
3265 } | 3269 } |
(...skipping 29 matching lines...) Expand all Loading... |
3295 return static_cast<LiteralType>(literal_type->value()); | 3299 return static_cast<LiteralType>(literal_type->value()); |
3296 } | 3300 } |
3297 | 3301 |
3298 | 3302 |
3299 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { | 3303 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { |
3300 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); | 3304 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); |
3301 } | 3305 } |
3302 | 3306 |
3303 | 3307 |
3304 FunctionLiteral* Parser::ParseFunctionLiteral( | 3308 FunctionLiteral* Parser::ParseFunctionLiteral( |
3305 Handle<String> function_name, | 3309 const AstRawString* function_name, |
3306 Scanner::Location function_name_location, | 3310 Scanner::Location function_name_location, |
3307 bool name_is_strict_reserved, | 3311 bool name_is_strict_reserved, |
3308 bool is_generator, | 3312 bool is_generator, |
3309 int function_token_pos, | 3313 int function_token_pos, |
3310 FunctionLiteral::FunctionType function_type, | 3314 FunctionLiteral::FunctionType function_type, |
3311 FunctionLiteral::ArityRestriction arity_restriction, | 3315 FunctionLiteral::ArityRestriction arity_restriction, |
3312 bool* ok) { | 3316 bool* ok) { |
3313 // Function :: | 3317 // Function :: |
3314 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 3318 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
3315 // | 3319 // |
3316 // Getter :: | 3320 // Getter :: |
3317 // '(' ')' '{' FunctionBody '}' | 3321 // '(' ')' '{' FunctionBody '}' |
3318 // | 3322 // |
3319 // Setter :: | 3323 // Setter :: |
3320 // '(' PropertySetParameterList ')' '{' FunctionBody '}' | 3324 // '(' PropertySetParameterList ')' '{' FunctionBody '}' |
3321 | 3325 |
3322 int pos = function_token_pos == RelocInfo::kNoPosition | 3326 int pos = function_token_pos == RelocInfo::kNoPosition |
3323 ? peek_position() : function_token_pos; | 3327 ? peek_position() : function_token_pos; |
3324 | 3328 |
3325 // Anonymous functions were passed either the empty symbol or a null | 3329 // Anonymous functions were passed either the empty symbol or a null |
3326 // handle as the function name. Remember if we were passed a non-empty | 3330 // handle as the function name. Remember if we were passed a non-empty |
3327 // handle to decide whether to invoke function name inference. | 3331 // handle to decide whether to invoke function name inference. |
3328 bool should_infer_name = function_name.is_null(); | 3332 bool should_infer_name = function_name == NULL; |
3329 | 3333 |
3330 // We want a non-null handle as the function name. | 3334 // We want a non-null handle as the function name. |
3331 if (should_infer_name) { | 3335 if (should_infer_name) { |
3332 function_name = isolate()->factory()->empty_string(); | 3336 function_name = ast_value_factory_->empty_string(); |
3333 } | 3337 } |
3334 | 3338 |
3335 int num_parameters = 0; | 3339 int num_parameters = 0; |
3336 // Function declarations are function scoped in normal mode, so they are | 3340 // Function declarations are function scoped in normal mode, so they are |
3337 // hoisted. In harmony block scoping mode they are block scoped, so they | 3341 // hoisted. In harmony block scoping mode they are block scoped, so they |
3338 // are not hoisted. | 3342 // are not hoisted. |
3339 // | 3343 // |
3340 // One tricky case are function declarations in a local sloppy-mode eval: | 3344 // One tricky case are function declarations in a local sloppy-mode eval: |
3341 // their declaration is hoisted, but they still see the local scope. E.g., | 3345 // their declaration is hoisted, but they still see the local scope. E.g., |
3342 // | 3346 // |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3374 int expected_property_count = -1; | 3378 int expected_property_count = -1; |
3375 int handler_count = 0; | 3379 int handler_count = 0; |
3376 FunctionLiteral::ParameterFlag duplicate_parameters = | 3380 FunctionLiteral::ParameterFlag duplicate_parameters = |
3377 FunctionLiteral::kNoDuplicateParameters; | 3381 FunctionLiteral::kNoDuplicateParameters; |
3378 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ | 3382 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ |
3379 ? FunctionLiteral::kIsParenthesized | 3383 ? FunctionLiteral::kIsParenthesized |
3380 : FunctionLiteral::kNotParenthesized; | 3384 : FunctionLiteral::kNotParenthesized; |
3381 AstProperties ast_properties; | 3385 AstProperties ast_properties; |
3382 BailoutReason dont_optimize_reason = kNoReason; | 3386 BailoutReason dont_optimize_reason = kNoReason; |
3383 // Parse function body. | 3387 // Parse function body. |
3384 { FunctionState function_state(&function_state_, &scope_, scope, zone()); | 3388 { |
| 3389 FunctionState function_state(&function_state_, &scope_, scope, zone(), |
| 3390 ast_value_factory_); |
3385 scope_->SetScopeName(function_name); | 3391 scope_->SetScopeName(function_name); |
3386 | 3392 |
3387 if (is_generator) { | 3393 if (is_generator) { |
3388 // For generators, allocating variables in contexts is currently a win | 3394 // For generators, allocating variables in contexts is currently a win |
3389 // because it minimizes the work needed to suspend and resume an | 3395 // because it minimizes the work needed to suspend and resume an |
3390 // activation. | 3396 // activation. |
3391 scope_->ForceContextAllocation(); | 3397 scope_->ForceContextAllocation(); |
3392 | 3398 |
3393 // Calling a generator returns a generator object. That object is stored | 3399 // Calling a generator returns a generator object. That object is stored |
3394 // in a temporary variable, a definition that is used by "yield" | 3400 // in a temporary variable, a definition that is used by "yield" |
3395 // expressions. This also marks the FunctionState as a generator. | 3401 // expressions. This also marks the FunctionState as a generator. |
3396 Variable* temp = scope_->DeclarationScope()->NewTemporary( | 3402 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
3397 isolate()->factory()->dot_generator_object_string()); | 3403 ast_value_factory_->dot_generator_object_string()); |
3398 function_state.set_generator_object_variable(temp); | 3404 function_state.set_generator_object_variable(temp); |
3399 } | 3405 } |
3400 | 3406 |
3401 // FormalParameterList :: | 3407 // FormalParameterList :: |
3402 // '(' (Identifier)*[','] ')' | 3408 // '(' (Identifier)*[','] ')' |
3403 Expect(Token::LPAREN, CHECK_OK); | 3409 Expect(Token::LPAREN, CHECK_OK); |
3404 scope->set_start_position(scanner()->location().beg_pos); | 3410 scope->set_start_position(scanner()->location().beg_pos); |
3405 | 3411 |
3406 // We don't yet know if the function will be strict, so we cannot yet | 3412 // We don't yet know if the function will be strict, so we cannot yet |
3407 // produce errors for parameter names or duplicates. However, we remember | 3413 // produce errors for parameter names or duplicates. However, we remember |
3408 // the locations of these errors if they occur and produce the errors later. | 3414 // the locations of these errors if they occur and produce the errors later. |
3409 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); | 3415 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); |
3410 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | 3416 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); |
3411 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 3417 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
3412 | 3418 |
3413 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY || | 3419 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY || |
3414 (peek() == Token::RPAREN && | 3420 (peek() == Token::RPAREN && |
3415 arity_restriction != FunctionLiteral::SETTER_ARITY); | 3421 arity_restriction != FunctionLiteral::SETTER_ARITY); |
3416 while (!done) { | 3422 while (!done) { |
3417 bool is_strict_reserved = false; | 3423 bool is_strict_reserved = false; |
3418 Handle<String> param_name = | 3424 const AstRawString* param_name = |
3419 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 3425 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
3420 | 3426 |
3421 // Store locations for possible future error reports. | 3427 // Store locations for possible future error reports. |
3422 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { | 3428 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { |
3423 eval_args_error_log = scanner()->location(); | 3429 eval_args_error_log = scanner()->location(); |
3424 } | 3430 } |
3425 if (!reserved_loc.IsValid() && is_strict_reserved) { | 3431 if (!reserved_loc.IsValid() && is_strict_reserved) { |
3426 reserved_loc = scanner()->location(); | 3432 reserved_loc = scanner()->location(); |
3427 } | 3433 } |
3428 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { | 3434 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { |
(...skipping 24 matching lines...) Expand all Loading... |
3453 // instead of Variables and Proxis as is the case now. | 3459 // instead of Variables and Proxis as is the case now. |
3454 Variable* fvar = NULL; | 3460 Variable* fvar = NULL; |
3455 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; | 3461 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; |
3456 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 3462 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
3457 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 3463 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
3458 fvar_init_op = Token::INIT_CONST; | 3464 fvar_init_op = Token::INIT_CONST; |
3459 } | 3465 } |
3460 VariableMode fvar_mode = | 3466 VariableMode fvar_mode = |
3461 allow_harmony_scoping() && strict_mode() == STRICT ? CONST | 3467 allow_harmony_scoping() && strict_mode() == STRICT ? CONST |
3462 : CONST_LEGACY; | 3468 : CONST_LEGACY; |
| 3469 ASSERT(function_name != NULL); |
3463 fvar = new(zone()) Variable(scope_, | 3470 fvar = new(zone()) Variable(scope_, |
3464 function_name, fvar_mode, true /* is valid LHS */, | 3471 function_name, fvar_mode, true /* is valid LHS */, |
3465 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); | 3472 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); |
3466 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 3473 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
3467 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( | 3474 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
3468 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); | 3475 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); |
3469 scope_->DeclareFunctionVar(fvar_declaration); | 3476 scope_->DeclareFunctionVar(fvar_declaration); |
3470 } | 3477 } |
3471 | 3478 |
3472 // Determine if the function can be parsed lazily. Lazy parsing is different | 3479 // Determine if the function can be parsed lazily. Lazy parsing is different |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3537 | 3544 |
3538 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 3545 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
3539 CheckConflictingVarDeclarations(scope, CHECK_OK); | 3546 CheckConflictingVarDeclarations(scope, CHECK_OK); |
3540 } | 3547 } |
3541 | 3548 |
3542 FunctionLiteral::IsGeneratorFlag generator = is_generator | 3549 FunctionLiteral::IsGeneratorFlag generator = is_generator |
3543 ? FunctionLiteral::kIsGenerator | 3550 ? FunctionLiteral::kIsGenerator |
3544 : FunctionLiteral::kNotGenerator; | 3551 : FunctionLiteral::kNotGenerator; |
3545 FunctionLiteral* function_literal = | 3552 FunctionLiteral* function_literal = |
3546 factory()->NewFunctionLiteral(function_name, | 3553 factory()->NewFunctionLiteral(function_name, |
| 3554 ast_value_factory_, |
3547 scope, | 3555 scope, |
3548 body, | 3556 body, |
3549 materialized_literal_count, | 3557 materialized_literal_count, |
3550 expected_property_count, | 3558 expected_property_count, |
3551 handler_count, | 3559 handler_count, |
3552 num_parameters, | 3560 num_parameters, |
3553 duplicate_parameters, | 3561 duplicate_parameters, |
3554 function_type, | 3562 function_type, |
3555 FunctionLiteral::kIsFunction, | 3563 FunctionLiteral::kIsFunction, |
3556 parenthesized, | 3564 parenthesized, |
3557 generator, | 3565 generator, |
3558 pos); | 3566 pos); |
3559 function_literal->set_function_token_position(function_token_pos); | 3567 function_literal->set_function_token_position(function_token_pos); |
3560 function_literal->set_ast_properties(&ast_properties); | 3568 function_literal->set_ast_properties(&ast_properties); |
3561 function_literal->set_dont_optimize_reason(dont_optimize_reason); | 3569 function_literal->set_dont_optimize_reason(dont_optimize_reason); |
3562 | 3570 |
3563 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 3571 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
3564 return function_literal; | 3572 return function_literal; |
3565 } | 3573 } |
3566 | 3574 |
3567 | 3575 |
3568 void Parser::SkipLazyFunctionBody(Handle<String> function_name, | 3576 void Parser::SkipLazyFunctionBody(const AstRawString* function_name, |
3569 int* materialized_literal_count, | 3577 int* materialized_literal_count, |
3570 int* expected_property_count, | 3578 int* expected_property_count, |
3571 bool* ok) { | 3579 bool* ok) { |
3572 int function_block_pos = position(); | 3580 int function_block_pos = position(); |
3573 if (cached_data_mode_ == CONSUME_CACHED_DATA) { | 3581 if (cached_data_mode_ == CONSUME_CACHED_DATA) { |
3574 // If we have cached data, we use it to skip parsing the function body. The | 3582 // If we have cached data, we use it to skip parsing the function body. The |
3575 // data contains the information we need to construct the lazy function. | 3583 // data contains the information we need to construct the lazy function. |
3576 FunctionEntry entry = | 3584 FunctionEntry entry = |
3577 (*cached_data())->GetFunctionEntry(function_block_pos); | 3585 (*cached_data())->GetFunctionEntry(function_block_pos); |
3578 if (entry.is_valid()) { | 3586 if (entry.is_valid()) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3637 log_->LogFunction(function_block_pos, body_end, | 3645 log_->LogFunction(function_block_pos, body_end, |
3638 *materialized_literal_count, | 3646 *materialized_literal_count, |
3639 *expected_property_count, | 3647 *expected_property_count, |
3640 scope_->strict_mode()); | 3648 scope_->strict_mode()); |
3641 } | 3649 } |
3642 } | 3650 } |
3643 } | 3651 } |
3644 | 3652 |
3645 | 3653 |
3646 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( | 3654 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
3647 Handle<String> function_name, int pos, Variable* fvar, | 3655 const AstRawString* function_name, int pos, Variable* fvar, |
3648 Token::Value fvar_init_op, bool is_generator, bool* ok) { | 3656 Token::Value fvar_init_op, bool is_generator, bool* ok) { |
3649 // Everything inside an eagerly parsed function will be parsed eagerly | 3657 // Everything inside an eagerly parsed function will be parsed eagerly |
3650 // (see comment above). | 3658 // (see comment above). |
3651 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 3659 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
3652 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone()); | 3660 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone()); |
3653 if (fvar != NULL) { | 3661 if (fvar != NULL) { |
3654 VariableProxy* fproxy = scope_->NewUnresolved( | 3662 VariableProxy* fproxy = scope_->NewUnresolved( |
3655 factory(), function_name, Interface::NewConst()); | 3663 factory(), function_name, Interface::NewConst()); |
3656 fproxy->BindTo(fvar); | 3664 fproxy->BindTo(fvar); |
3657 body->Add(factory()->NewExpressionStatement( | 3665 body->Add(factory()->NewExpressionStatement( |
3658 factory()->NewAssignment(fvar_init_op, | 3666 factory()->NewAssignment(fvar_init_op, |
3659 fproxy, | 3667 fproxy, |
3660 factory()->NewThisFunction(pos), | 3668 factory()->NewThisFunction(pos), |
3661 RelocInfo::kNoPosition), | 3669 RelocInfo::kNoPosition), |
3662 RelocInfo::kNoPosition), zone()); | 3670 RelocInfo::kNoPosition), zone()); |
3663 } | 3671 } |
3664 | 3672 |
3665 // For generators, allocate and yield an iterator on function entry. | 3673 // For generators, allocate and yield an iterator on function entry. |
3666 if (is_generator) { | 3674 if (is_generator) { |
3667 ZoneList<Expression*>* arguments = | 3675 ZoneList<Expression*>* arguments = |
3668 new(zone()) ZoneList<Expression*>(0, zone()); | 3676 new(zone()) ZoneList<Expression*>(0, zone()); |
3669 CallRuntime* allocation = factory()->NewCallRuntime( | 3677 CallRuntime* allocation = factory()->NewCallRuntime( |
3670 isolate()->factory()->empty_string(), | 3678 ast_value_factory_->empty_string(), |
3671 Runtime::FunctionForId(Runtime::kHiddenCreateJSGeneratorObject), | 3679 Runtime::FunctionForId(Runtime::kHiddenCreateJSGeneratorObject), |
3672 arguments, pos); | 3680 arguments, pos); |
3673 VariableProxy* init_proxy = factory()->NewVariableProxy( | 3681 VariableProxy* init_proxy = factory()->NewVariableProxy( |
3674 function_state_->generator_object_variable()); | 3682 function_state_->generator_object_variable()); |
3675 Assignment* assignment = factory()->NewAssignment( | 3683 Assignment* assignment = factory()->NewAssignment( |
3676 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); | 3684 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); |
3677 VariableProxy* get_proxy = factory()->NewVariableProxy( | 3685 VariableProxy* get_proxy = factory()->NewVariableProxy( |
3678 function_state_->generator_object_variable()); | 3686 function_state_->generator_object_variable()); |
3679 Yield* yield = factory()->NewYield( | 3687 Yield* yield = factory()->NewYield( |
3680 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); | 3688 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); |
3681 body->Add(factory()->NewExpressionStatement( | 3689 body->Add(factory()->NewExpressionStatement( |
3682 yield, RelocInfo::kNoPosition), zone()); | 3690 yield, RelocInfo::kNoPosition), zone()); |
3683 } | 3691 } |
3684 | 3692 |
3685 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); | 3693 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); |
3686 | 3694 |
3687 if (is_generator) { | 3695 if (is_generator) { |
3688 VariableProxy* get_proxy = factory()->NewVariableProxy( | 3696 VariableProxy* get_proxy = factory()->NewVariableProxy( |
3689 function_state_->generator_object_variable()); | 3697 function_state_->generator_object_variable()); |
3690 Expression *undefined = factory()->NewLiteral( | 3698 Expression* undefined = |
3691 isolate()->factory()->undefined_value(), RelocInfo::kNoPosition); | 3699 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); |
3692 Yield* yield = factory()->NewYield( | 3700 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::FINAL, |
3693 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); | 3701 RelocInfo::kNoPosition); |
3694 body->Add(factory()->NewExpressionStatement( | 3702 body->Add(factory()->NewExpressionStatement( |
3695 yield, RelocInfo::kNoPosition), zone()); | 3703 yield, RelocInfo::kNoPosition), zone()); |
3696 } | 3704 } |
3697 | 3705 |
3698 Expect(Token::RBRACE, CHECK_OK); | 3706 Expect(Token::RBRACE, CHECK_OK); |
3699 scope_->set_end_position(scanner()->location().end_pos); | 3707 scope_->set_end_position(scanner()->location().end_pos); |
3700 | 3708 |
3701 return body; | 3709 return body; |
3702 } | 3710 } |
3703 | 3711 |
(...skipping 23 matching lines...) Expand all Loading... |
3727 } | 3735 } |
3728 | 3736 |
3729 | 3737 |
3730 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3738 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
3731 // CallRuntime :: | 3739 // CallRuntime :: |
3732 // '%' Identifier Arguments | 3740 // '%' Identifier Arguments |
3733 | 3741 |
3734 int pos = peek_position(); | 3742 int pos = peek_position(); |
3735 Expect(Token::MOD, CHECK_OK); | 3743 Expect(Token::MOD, CHECK_OK); |
3736 // Allow "eval" or "arguments" for backward compatibility. | 3744 // Allow "eval" or "arguments" for backward compatibility. |
3737 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 3745 const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
3738 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 3746 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
3739 | 3747 |
3740 if (extension_ != NULL) { | 3748 if (extension_ != NULL) { |
3741 // The extension structures are only accessible while parsing the | 3749 // The extension structures are only accessible while parsing the |
3742 // very first time not when reparsing because of lazy compilation. | 3750 // very first time not when reparsing because of lazy compilation. |
3743 scope_->DeclarationScope()->ForceEagerCompilation(); | 3751 scope_->DeclarationScope()->ForceEagerCompilation(); |
3744 } | 3752 } |
3745 | 3753 |
3746 const Runtime::Function* function = Runtime::FunctionForName(name); | 3754 const Runtime::Function* function = Runtime::FunctionForName(name->string()); |
3747 | 3755 |
3748 // Check for built-in IS_VAR macro. | 3756 // Check for built-in IS_VAR macro. |
3749 if (function != NULL && | 3757 if (function != NULL && |
3750 function->intrinsic_type == Runtime::RUNTIME && | 3758 function->intrinsic_type == Runtime::RUNTIME && |
3751 function->function_id == Runtime::kIS_VAR) { | 3759 function->function_id == Runtime::kIS_VAR) { |
3752 // %IS_VAR(x) evaluates to x if x is a variable, | 3760 // %IS_VAR(x) evaluates to x if x is a variable, |
3753 // leads to a parse error otherwise. Could be implemented as an | 3761 // leads to a parse error otherwise. Could be implemented as an |
3754 // inline function %_IS_VAR(x) to eliminate this special case. | 3762 // inline function %_IS_VAR(x) to eliminate this special case. |
3755 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { | 3763 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { |
3756 return args->at(0); | 3764 return args->at(0); |
3757 } else { | 3765 } else { |
3758 ReportMessage("not_isvar"); | 3766 ReportMessage("not_isvar"); |
3759 *ok = false; | 3767 *ok = false; |
3760 return NULL; | 3768 return NULL; |
3761 } | 3769 } |
3762 } | 3770 } |
3763 | 3771 |
3764 // Check that the expected number of arguments are being passed. | 3772 // Check that the expected number of arguments are being passed. |
3765 if (function != NULL && | 3773 if (function != NULL && |
3766 function->nargs != -1 && | 3774 function->nargs != -1 && |
3767 function->nargs != args->length()) { | 3775 function->nargs != args->length()) { |
3768 ReportMessage("illegal_access"); | 3776 ReportMessage("illegal_access"); |
3769 *ok = false; | 3777 *ok = false; |
3770 return NULL; | 3778 return NULL; |
3771 } | 3779 } |
3772 | 3780 |
3773 // Check that the function is defined if it's an inline runtime call. | 3781 // Check that the function is defined if it's an inline runtime call. |
3774 if (function == NULL && name->Get(0) == '_') { | 3782 if (function == NULL && name->FirstCharacter() == '_') { |
3775 ParserTraits::ReportMessage("not_defined", name); | 3783 ParserTraits::ReportMessage("not_defined", name); |
3776 *ok = false; | 3784 *ok = false; |
3777 return NULL; | 3785 return NULL; |
3778 } | 3786 } |
3779 | 3787 |
3780 // We have a valid intrinsics call or a call to a builtin. | 3788 // We have a valid intrinsics call or a call to a builtin. |
3781 return factory()->NewCallRuntime(name, function, args, pos); | 3789 return factory()->NewCallRuntime(name, function, args, pos); |
3782 } | 3790 } |
3783 | 3791 |
3784 | 3792 |
3785 Literal* Parser::GetLiteralUndefined(int position) { | 3793 Literal* Parser::GetLiteralUndefined(int position) { |
3786 return factory()->NewLiteral( | 3794 return factory()->NewUndefinedLiteral(position); |
3787 isolate()->factory()->undefined_value(), position); | |
3788 } | 3795 } |
3789 | 3796 |
3790 | 3797 |
3791 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 3798 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
3792 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 3799 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
3793 if (decl != NULL) { | 3800 if (decl != NULL) { |
3794 // In harmony mode we treat conflicting variable bindinds as early | 3801 // In harmony mode we treat conflicting variable bindinds as early |
3795 // errors. See ES5 16 for a definition of early errors. | 3802 // errors. See ES5 16 for a definition of early errors. |
3796 Handle<String> name = decl->proxy()->name(); | 3803 const AstRawString* name = decl->proxy()->raw_name(); |
3797 int position = decl->proxy()->position(); | 3804 int position = decl->proxy()->position(); |
3798 Scanner::Location location = position == RelocInfo::kNoPosition | 3805 Scanner::Location location = position == RelocInfo::kNoPosition |
3799 ? Scanner::Location::invalid() | 3806 ? Scanner::Location::invalid() |
3800 : Scanner::Location(position, position + 1); | 3807 : Scanner::Location(position, position + 1); |
3801 ParserTraits::ReportMessageAt(location, "var_redeclaration", name); | 3808 ParserTraits::ReportMessageAt(location, "var_redeclaration", name); |
3802 *ok = false; | 3809 *ok = false; |
3803 } | 3810 } |
3804 } | 3811 } |
3805 | 3812 |
3806 | 3813 |
3807 // ---------------------------------------------------------------------------- | 3814 // ---------------------------------------------------------------------------- |
3808 // Parser support | 3815 // Parser support |
3809 | 3816 |
3810 | 3817 |
3811 bool Parser::TargetStackContainsLabel(Handle<String> label) { | 3818 bool Parser::TargetStackContainsLabel(const AstRawString* label) { |
3812 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 3819 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
3813 BreakableStatement* stat = t->node()->AsBreakableStatement(); | 3820 BreakableStatement* stat = t->node()->AsBreakableStatement(); |
3814 if (stat != NULL && ContainsLabel(stat->labels(), label)) | 3821 if (stat != NULL && ContainsLabel(stat->labels(), label)) |
3815 return true; | 3822 return true; |
3816 } | 3823 } |
3817 return false; | 3824 return false; |
3818 } | 3825 } |
3819 | 3826 |
3820 | 3827 |
3821 BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) { | 3828 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label, |
3822 bool anonymous = label.is_null(); | 3829 bool* ok) { |
| 3830 bool anonymous = label == NULL; |
3823 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 3831 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
3824 BreakableStatement* stat = t->node()->AsBreakableStatement(); | 3832 BreakableStatement* stat = t->node()->AsBreakableStatement(); |
3825 if (stat == NULL) continue; | 3833 if (stat == NULL) continue; |
3826 if ((anonymous && stat->is_target_for_anonymous()) || | 3834 if ((anonymous && stat->is_target_for_anonymous()) || |
3827 (!anonymous && ContainsLabel(stat->labels(), label))) { | 3835 (!anonymous && ContainsLabel(stat->labels(), label))) { |
3828 RegisterTargetUse(stat->break_target(), t->previous()); | 3836 RegisterTargetUse(stat->break_target(), t->previous()); |
3829 return stat; | 3837 return stat; |
3830 } | 3838 } |
3831 } | 3839 } |
3832 return NULL; | 3840 return NULL; |
3833 } | 3841 } |
3834 | 3842 |
3835 | 3843 |
3836 IterationStatement* Parser::LookupContinueTarget(Handle<String> label, | 3844 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label, |
3837 bool* ok) { | 3845 bool* ok) { |
3838 bool anonymous = label.is_null(); | 3846 bool anonymous = label == NULL; |
3839 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 3847 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
3840 IterationStatement* stat = t->node()->AsIterationStatement(); | 3848 IterationStatement* stat = t->node()->AsIterationStatement(); |
3841 if (stat == NULL) continue; | 3849 if (stat == NULL) continue; |
3842 | 3850 |
3843 ASSERT(stat->is_target_for_anonymous()); | 3851 ASSERT(stat->is_target_for_anonymous()); |
3844 if (anonymous || ContainsLabel(stat->labels(), label)) { | 3852 if (anonymous || ContainsLabel(stat->labels(), label)) { |
3845 RegisterTargetUse(stat->continue_target(), t->previous()); | 3853 RegisterTargetUse(stat->continue_target(), t->previous()); |
3846 return stat; | 3854 return stat; |
3847 } | 3855 } |
3848 } | 3856 } |
3849 return NULL; | 3857 return NULL; |
3850 } | 3858 } |
3851 | 3859 |
3852 | 3860 |
3853 void Parser::RegisterTargetUse(Label* target, Target* stop) { | 3861 void Parser::RegisterTargetUse(Label* target, Target* stop) { |
3854 // Register that a break target found at the given stop in the | 3862 // Register that a break target found at the given stop in the |
3855 // target stack has been used from the top of the target stack. Add | 3863 // target stack has been used from the top of the target stack. Add |
3856 // the break target to any TargetCollectors passed on the stack. | 3864 // the break target to any TargetCollectors passed on the stack. |
3857 for (Target* t = target_stack_; t != stop; t = t->previous()) { | 3865 for (Target* t = target_stack_; t != stop; t = t->previous()) { |
3858 TargetCollector* collector = t->node()->AsTargetCollector(); | 3866 TargetCollector* collector = t->node()->AsTargetCollector(); |
3859 if (collector != NULL) collector->AddTarget(target, zone()); | 3867 if (collector != NULL) collector->AddTarget(target, zone()); |
3860 } | 3868 } |
3861 } | 3869 } |
3862 | 3870 |
3863 | 3871 |
3864 void Parser::ThrowPendingError() { | 3872 void Parser::ThrowPendingError() { |
| 3873 ASSERT(ast_value_factory_->IsInternalized()); |
3865 if (has_pending_error_) { | 3874 if (has_pending_error_) { |
3866 MessageLocation location(script_, | 3875 MessageLocation location(script_, |
3867 pending_error_location_.beg_pos, | 3876 pending_error_location_.beg_pos, |
3868 pending_error_location_.end_pos); | 3877 pending_error_location_.end_pos); |
3869 Factory* factory = isolate()->factory(); | 3878 Factory* factory = isolate()->factory(); |
3870 bool has_arg = | 3879 bool has_arg = |
3871 !pending_error_arg_.is_null() || pending_error_char_arg_ != NULL; | 3880 pending_error_arg_ != NULL || pending_error_char_arg_ != NULL; |
3872 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0); | 3881 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0); |
3873 if (!pending_error_arg_.is_null()) { | 3882 if (pending_error_arg_ != NULL) { |
3874 elements->set(0, *(pending_error_arg_.ToHandleChecked())); | 3883 Handle<String> arg_string = pending_error_arg_->string(); |
| 3884 elements->set(0, *arg_string); |
3875 } else if (pending_error_char_arg_ != NULL) { | 3885 } else if (pending_error_char_arg_ != NULL) { |
3876 Handle<String> arg_string = | 3886 Handle<String> arg_string = |
3877 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_)) | 3887 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_)) |
3878 .ToHandleChecked(); | 3888 .ToHandleChecked(); |
3879 elements->set(0, *arg_string); | 3889 elements->set(0, *arg_string); |
3880 } | 3890 } |
3881 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | 3891 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
3882 Handle<Object> result = pending_error_is_reference_error_ | 3892 Handle<Object> result = pending_error_is_reference_error_ |
3883 ? factory->NewReferenceError(pending_error_message_, array) | 3893 ? factory->NewReferenceError(pending_error_message_, array) |
3884 : factory->NewSyntaxError(pending_error_message_, array); | 3894 : factory->NewSyntaxError(pending_error_message_, array); |
(...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4778 result->contains_anchor = parser.contains_anchor(); | 4788 result->contains_anchor = parser.contains_anchor(); |
4779 result->capture_count = capture_count; | 4789 result->capture_count = capture_count; |
4780 } | 4790 } |
4781 return !parser.failed(); | 4791 return !parser.failed(); |
4782 } | 4792 } |
4783 | 4793 |
4784 | 4794 |
4785 bool Parser::Parse() { | 4795 bool Parser::Parse() { |
4786 ASSERT(info()->function() == NULL); | 4796 ASSERT(info()->function() == NULL); |
4787 FunctionLiteral* result = NULL; | 4797 FunctionLiteral* result = NULL; |
| 4798 ast_value_factory_ = info()->ast_value_factory(); |
| 4799 if (ast_value_factory_ == NULL) { |
| 4800 ast_value_factory_ = |
| 4801 new AstValueFactory(zone(), isolate()->heap()->HashSeed()); |
| 4802 } |
| 4803 if (allow_natives_syntax() || extension_ != NULL) { |
| 4804 // If intrinsics are allowed, the Parser cannot operate independent of the |
| 4805 // V8 heap because of Rumtime. Tell the string table to internalize strings |
| 4806 // and values right after they're created. |
| 4807 ast_value_factory_->Internalize(isolate()); |
| 4808 } |
| 4809 |
4788 if (info()->is_lazy()) { | 4810 if (info()->is_lazy()) { |
4789 ASSERT(!info()->is_eval()); | 4811 ASSERT(!info()->is_eval()); |
4790 if (info()->shared_info()->is_function()) { | 4812 if (info()->shared_info()->is_function()) { |
4791 result = ParseLazy(); | 4813 result = ParseLazy(); |
4792 } else { | 4814 } else { |
4793 result = ParseProgram(); | 4815 result = ParseProgram(); |
4794 } | 4816 } |
4795 } else { | 4817 } else { |
4796 SetCachedData(info()->cached_data(), info()->cached_data_mode()); | 4818 SetCachedData(info()->cached_data(), info()->cached_data_mode()); |
4797 if (info()->cached_data_mode() == CONSUME_CACHED_DATA && | 4819 if (info()->cached_data_mode() == CONSUME_CACHED_DATA && |
4798 (*info()->cached_data())->has_error()) { | 4820 (*info()->cached_data())->has_error()) { |
4799 ScriptData* cached_data = *(info()->cached_data()); | 4821 ScriptData* cached_data = *(info()->cached_data()); |
4800 Scanner::Location loc = cached_data->MessageLocation(); | 4822 Scanner::Location loc = cached_data->MessageLocation(); |
4801 const char* message = cached_data->BuildMessage(); | 4823 const char* message = cached_data->BuildMessage(); |
4802 const char* arg = cached_data->BuildArg(); | 4824 const char* arg = cached_data->BuildArg(); |
4803 ParserTraits::ReportMessageAt(loc, message, arg, | 4825 ParserTraits::ReportMessageAt(loc, message, arg, |
4804 cached_data->IsReferenceError()); | 4826 cached_data->IsReferenceError()); |
4805 DeleteArray(message); | 4827 DeleteArray(message); |
4806 DeleteArray(arg); | 4828 DeleteArray(arg); |
4807 ASSERT(info()->isolate()->has_pending_exception()); | 4829 ASSERT(info()->isolate()->has_pending_exception()); |
4808 } else { | 4830 } else { |
4809 result = ParseProgram(); | 4831 result = ParseProgram(); |
4810 } | 4832 } |
4811 } | 4833 } |
4812 info()->SetFunction(result); | 4834 info()->SetFunction(result); |
| 4835 ASSERT(ast_value_factory_->IsInternalized()); |
| 4836 // info takes ownership of ast_value_factory_. |
| 4837 if (info()->ast_value_factory() == NULL) { |
| 4838 info()->SetAstValueFactory(ast_value_factory_); |
| 4839 } |
| 4840 ast_value_factory_ = NULL; |
4813 return (result != NULL); | 4841 return (result != NULL); |
4814 } | 4842 } |
4815 | 4843 |
4816 } } // namespace v8::internal | 4844 } } // namespace v8::internal |
OLD | NEW |