Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 #define CHECK_FAILED /**/); \ | 411 #define CHECK_FAILED /**/); \ |
| 412 if (failed_) return NULL; \ | 412 if (failed_) return NULL; \ |
| 413 ((void)0 | 413 ((void)0 |
| 414 #define DUMMY ) // to make indentation work | 414 #define DUMMY ) // to make indentation work |
| 415 #undef DUMMY | 415 #undef DUMMY |
| 416 | 416 |
| 417 // ---------------------------------------------------------------------------- | 417 // ---------------------------------------------------------------------------- |
| 418 // Implementation of Parser | 418 // Implementation of Parser |
| 419 | 419 |
| 420 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { | 420 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { |
| 421 return identifier.is_identical_to( | 421 Factory* factory = parser_->isolate()->factory(); |
| 422 parser_->isolate()->factory()->eval_string()) || | 422 return identifier.is_identical_to(factory->eval_string()) |
| 423 identifier.is_identical_to( | 423 || identifier.is_identical_to(factory->arguments_string()); |
| 424 parser_->isolate()->factory()->arguments_string()); | |
| 425 } | 424 } |
| 426 | 425 |
| 427 | 426 |
| 428 bool ParserTraits::IsThisProperty(Expression* expression) { | 427 bool ParserTraits::IsThisProperty(Expression* expression) { |
| 429 ASSERT(expression != NULL); | 428 ASSERT(expression != NULL); |
| 430 Property* property = expression->AsProperty(); | 429 Property* property = expression->AsProperty(); |
| 431 return property != NULL && | 430 return property != NULL && |
| 432 property->obj()->AsVariableProxy() != NULL && | 431 property->obj()->AsVariableProxy() != NULL && |
| 433 property->obj()->AsVariableProxy()->is_this(); | 432 property->obj()->AsVariableProxy()->is_this(); |
| 434 } | 433 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 473 | 472 |
| 474 Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) { | 473 Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) { |
| 475 VariableProxy* proxy = expression != NULL | 474 VariableProxy* proxy = expression != NULL |
| 476 ? expression->AsVariableProxy() | 475 ? expression->AsVariableProxy() |
| 477 : NULL; | 476 : NULL; |
| 478 if (proxy != NULL) proxy->MarkAsLValue(); | 477 if (proxy != NULL) proxy->MarkAsLValue(); |
| 479 return expression; | 478 return expression; |
| 480 } | 479 } |
| 481 | 480 |
| 482 | 481 |
| 483 void ParserTraits::CheckStrictModeLValue(Expression* expression, | |
| 484 bool* ok) { | |
| 485 VariableProxy* lhs = expression != NULL | |
| 486 ? expression->AsVariableProxy() | |
| 487 : NULL; | |
| 488 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | |
| 489 parser_->ReportMessage("strict_eval_arguments", | |
| 490 Vector<const char*>::empty()); | |
| 491 *ok = false; | |
| 492 } | |
| 493 } | |
| 494 | |
| 495 | |
| 496 bool ParserTraits::ShortcutNumericLiteralBinaryExpression( | 482 bool ParserTraits::ShortcutNumericLiteralBinaryExpression( |
| 497 Expression** x, Expression* y, Token::Value op, int pos, | 483 Expression** x, Expression* y, Token::Value op, int pos, |
| 498 AstNodeFactory<AstConstructionVisitor>* factory) { | 484 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 499 if ((*x)->AsLiteral() && (*x)->AsLiteral()->value()->IsNumber() && | 485 if ((*x)->AsLiteral() && (*x)->AsLiteral()->value()->IsNumber() && |
| 500 y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) { | 486 y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) { |
| 501 double x_val = (*x)->AsLiteral()->value()->Number(); | 487 double x_val = (*x)->AsLiteral()->value()->Number(); |
| 502 double y_val = y->AsLiteral()->value()->Number(); | 488 double y_val = y->AsLiteral()->value()->Number(); |
| 503 switch (op) { | 489 switch (op) { |
| 504 case Token::ADD: | 490 case Token::ADD: |
| 505 *x = factory->NewNumberLiteral(x_val + y_val, pos); | 491 *x = factory->NewNumberLiteral(x_val + y_val, pos); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 592 } | 578 } |
| 593 // ...and one more time for '~foo' => 'foo^(~0)'. | 579 // ...and one more time for '~foo' => 'foo^(~0)'. |
| 594 if (op == Token::BIT_NOT) { | 580 if (op == Token::BIT_NOT) { |
| 595 return factory->NewBinaryOperation( | 581 return factory->NewBinaryOperation( |
| 596 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); | 582 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); |
| 597 } | 583 } |
| 598 return factory->NewUnaryOperation(op, expression, pos); | 584 return factory->NewUnaryOperation(op, expression, pos); |
| 599 } | 585 } |
| 600 | 586 |
| 601 | 587 |
| 588 Expression* ParserTraits::NewThrowReferenceError( | |
| 589 const char* message, int pos) { | |
| 590 return NewThrowError( | |
| 591 parser_->isolate()->factory()->MakeReferenceError_string(), | |
| 592 message, HandleVector<Object>(NULL, 0), pos); | |
| 593 } | |
| 594 | |
| 595 | |
| 596 Expression* ParserTraits::NewThrowSyntaxError( | |
| 597 const char* message, Handle<Object> arg, int pos) { | |
| 598 int argc = arg.is_null() ? 0 : 1; | |
| 599 Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc); | |
| 600 return NewThrowError( | |
| 601 parser_->isolate()->factory()->MakeSyntaxError_string(), | |
| 602 message, arguments, pos); | |
| 603 } | |
| 604 | |
| 605 | |
| 606 Expression* ParserTraits::NewThrowTypeError( | |
| 607 const char* message, Handle<Object> arg1, Handle<Object> arg2, int pos) { | |
| 608 ASSERT(!arg1.is_null() && !arg2.is_null()); | |
| 609 Handle<Object> elements[] = { arg1, arg2 }; | |
| 610 Vector< Handle<Object> > arguments = | |
| 611 HandleVector<Object>(elements, ARRAY_SIZE(elements)); | |
| 612 return NewThrowError( | |
| 613 parser_->isolate()->factory()->MakeTypeError_string(), | |
| 614 message, arguments, pos); | |
| 615 } | |
| 616 | |
| 617 | |
| 618 Expression* ParserTraits::NewThrowError( | |
| 619 Handle<String> constructor, const char* message, | |
| 620 Vector<Handle<Object> > arguments, int pos) { | |
| 621 Zone* zone = parser_->zone(); | |
| 622 Factory* factory = parser_->isolate()->factory(); | |
| 623 int argc = arguments.length(); | |
| 624 Handle<FixedArray> elements = factory->NewFixedArray(argc, TENURED); | |
| 625 for (int i = 0; i < argc; i++) { | |
| 626 Handle<Object> element = arguments[i]; | |
| 627 if (!element.is_null()) { | |
| 628 elements->set(i, *element); | |
| 629 } | |
| 630 } | |
| 631 Handle<JSArray> array = | |
| 632 factory->NewJSArrayWithElements(elements, FAST_ELEMENTS, TENURED); | |
| 633 | |
| 634 ZoneList<Expression*>* args = new(zone) ZoneList<Expression*>(2, zone); | |
| 635 Handle<String> type = factory->InternalizeUtf8String(message); | |
| 636 args->Add(parser_->factory()->NewLiteral(type, pos), zone); | |
| 637 args->Add(parser_->factory()->NewLiteral(array, pos), zone); | |
| 638 CallRuntime* call_constructor = | |
| 639 parser_->factory()->NewCallRuntime(constructor, NULL, args, pos); | |
| 640 return parser_->factory()->NewThrow(call_constructor, pos); | |
| 641 } | |
| 642 | |
| 643 | |
| 602 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 644 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
| 603 const char* message, | 645 const char* message, |
| 604 Vector<const char*> args, | 646 Vector<const char*> args, |
| 605 bool is_reference_error) { | 647 bool is_reference_error) { |
| 606 if (parser_->stack_overflow()) { | 648 if (parser_->stack_overflow()) { |
| 607 // Suppress the error message (syntax error or such) in the presence of a | 649 // Suppress the error message (syntax error or such) in the presence of a |
| 608 // stack overflow. The isolate allows only one pending exception at at time | 650 // stack overflow. The isolate allows only one pending exception at at time |
| 609 // and we want to report the stack overflow later. | 651 // and we want to report the stack overflow later. |
| 610 return; | 652 return; |
| 611 } | 653 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 668 if (symbol_id >= 0 && | 710 if (symbol_id >= 0 && |
| 669 symbol_id < (*parser_->cached_data())->symbol_count()) { | 711 symbol_id < (*parser_->cached_data())->symbol_count()) { |
| 670 return parser_->LookupCachedSymbol(symbol_id); | 712 return parser_->LookupCachedSymbol(symbol_id); |
| 671 } | 713 } |
| 672 } else if (parser_->cached_data_mode() == PRODUCE_CACHED_DATA) { | 714 } else if (parser_->cached_data_mode() == PRODUCE_CACHED_DATA) { |
| 673 if (parser_->log_->ShouldLogSymbols()) { | 715 if (parser_->log_->ShouldLogSymbols()) { |
| 674 parser_->scanner()->LogSymbol(parser_->log_, parser_->position()); | 716 parser_->scanner()->LogSymbol(parser_->log_, parser_->position()); |
| 675 } | 717 } |
| 676 } | 718 } |
| 677 Handle<String> result = | 719 Handle<String> result = |
| 678 parser_->scanner()->AllocateInternalizedString(parser_->isolate_); | 720 parser_->scanner()->AllocateInternalizedString(parser_->isolate()); |
| 679 ASSERT(!result.is_null()); | 721 ASSERT(!result.is_null()); |
| 680 return result; | 722 return result; |
| 681 } | 723 } |
| 682 | 724 |
| 683 | 725 |
| 684 Handle<String> ParserTraits::NextLiteralString(Scanner* scanner, | 726 Handle<String> ParserTraits::NextLiteralString(Scanner* scanner, |
| 685 PretenureFlag tenured) { | 727 PretenureFlag tenured) { |
| 686 return scanner->AllocateNextLiteralString(parser_->isolate(), tenured); | 728 return scanner->AllocateNextLiteralString(parser_->isolate(), tenured); |
| 687 } | 729 } |
| 688 | 730 |
| (...skipping 1021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1710 const char* elms[2] = { "Variable", c_string.get() }; | 1752 const char* elms[2] = { "Variable", c_string.get() }; |
| 1711 Vector<const char*> args(elms, 2); | 1753 Vector<const char*> args(elms, 2); |
| 1712 ReportMessage("redeclaration", args); | 1754 ReportMessage("redeclaration", args); |
| 1713 *ok = false; | 1755 *ok = false; |
| 1714 return; | 1756 return; |
| 1715 } | 1757 } |
| 1716 Handle<String> message_string = | 1758 Handle<String> message_string = |
| 1717 isolate()->factory()->InternalizeOneByteString( | 1759 isolate()->factory()->InternalizeOneByteString( |
| 1718 STATIC_ASCII_VECTOR("Variable")); | 1760 STATIC_ASCII_VECTOR("Variable")); |
| 1719 Expression* expression = | 1761 Expression* expression = |
| 1720 NewThrowTypeError(isolate()->factory()->redeclaration_string(), | 1762 NewThrowTypeError("redeclaration", |
| 1721 message_string, name); | 1763 message_string, name, declaration->position()); |
| 1722 declaration_scope->SetIllegalRedeclaration(expression); | 1764 declaration_scope->SetIllegalRedeclaration(expression); |
| 1723 } | 1765 } |
| 1724 } | 1766 } |
| 1725 | 1767 |
| 1726 // We add a declaration node for every declaration. The compiler | 1768 // We add a declaration node for every declaration. The compiler |
| 1727 // will only generate code if necessary. In particular, declarations | 1769 // will only generate code if necessary. In particular, declarations |
| 1728 // for inner local variables that do not represent functions won't | 1770 // for inner local variables that do not represent functions won't |
| 1729 // result in any generated code. | 1771 // result in any generated code. |
| 1730 // | 1772 // |
| 1731 // Note that we always add an unresolved proxy even if it's not | 1773 // Note that we always add an unresolved proxy even if it's not |
| (...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2499 } | 2541 } |
| 2500 | 2542 |
| 2501 // An ECMAScript program is considered syntactically incorrect if it | 2543 // An ECMAScript program is considered syntactically incorrect if it |
| 2502 // contains a return statement that is not within the body of a | 2544 // contains a return statement that is not within the body of a |
| 2503 // function. See ECMA-262, section 12.9, page 67. | 2545 // function. See ECMA-262, section 12.9, page 67. |
| 2504 // | 2546 // |
| 2505 // To be consistent with KJS we report the syntax error at runtime. | 2547 // To be consistent with KJS we report the syntax error at runtime. |
| 2506 Scope* declaration_scope = scope_->DeclarationScope(); | 2548 Scope* declaration_scope = scope_->DeclarationScope(); |
| 2507 if (declaration_scope->is_global_scope() || | 2549 if (declaration_scope->is_global_scope() || |
| 2508 declaration_scope->is_eval_scope()) { | 2550 declaration_scope->is_eval_scope()) { |
| 2509 Handle<String> message = isolate()->factory()->illegal_return_string(); | |
| 2510 Expression* throw_error = | 2551 Expression* throw_error = |
| 2511 NewThrowSyntaxError(message, Handle<Object>::null()); | 2552 NewThrowSyntaxError("illegal_return", Handle<Object>::null(), pos); |
| 2512 return factory()->NewExpressionStatement(throw_error, pos); | 2553 return factory()->NewExpressionStatement(throw_error, pos); |
| 2513 } | 2554 } |
| 2514 return result; | 2555 return result; |
| 2515 } | 2556 } |
| 2516 | 2557 |
| 2517 | 2558 |
| 2518 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 2559 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
| 2519 // WithStatement :: | 2560 // WithStatement :: |
| 2520 // 'with' '(' Expression ')' Statement | 2561 // 'with' '(' Expression ')' Statement |
| 2521 | 2562 |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2980 } else { | 3021 } else { |
| 2981 init = variable_statement; | 3022 init = variable_statement; |
| 2982 } | 3023 } |
| 2983 } else { | 3024 } else { |
| 2984 Scanner::Location lhs_location = scanner()->peek_location(); | 3025 Scanner::Location lhs_location = scanner()->peek_location(); |
| 2985 Expression* expression = ParseExpression(false, CHECK_OK); | 3026 Expression* expression = ParseExpression(false, CHECK_OK); |
| 2986 ForEachStatement::VisitMode mode; | 3027 ForEachStatement::VisitMode mode; |
| 2987 bool accept_OF = expression->AsVariableProxy(); | 3028 bool accept_OF = expression->AsVariableProxy(); |
| 2988 | 3029 |
| 2989 if (CheckInOrOf(accept_OF, &mode)) { | 3030 if (CheckInOrOf(accept_OF, &mode)) { |
| 2990 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3031 if (expression == NULL) { |
|
marja
2014/04/01 16:13:47
I don't think that expression can be NULL here. Af
rossberg
2014/04/01 17:20:06
Good to know. :) Removed.
| |
| 2991 ReportMessageAt(lhs_location, "invalid_lhs_in_for", true); | 3032 // Dummy invalid lhs expression. |
| 2992 *ok = false; | 3033 expression = factory()->NewNumberLiteral(0, lhs_location.beg_pos); |
| 2993 return NULL; | |
| 2994 } | 3034 } |
| 3035 expression = this->RewriteReferenceExpression( | |
| 3036 expression, lhs_location, "invalid_lhs_in_for", CHECK_OK); | |
| 3037 | |
| 2995 ForEachStatement* loop = | 3038 ForEachStatement* loop = |
| 2996 factory()->NewForEachStatement(mode, labels, pos); | 3039 factory()->NewForEachStatement(mode, labels, pos); |
| 2997 Target target(&this->target_stack_, loop); | 3040 Target target(&this->target_stack_, loop); |
| 2998 | 3041 |
| 2999 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3042 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 3000 Expect(Token::RPAREN, CHECK_OK); | 3043 Expect(Token::RPAREN, CHECK_OK); |
| 3001 | 3044 |
| 3002 Statement* body = ParseStatement(NULL, CHECK_OK); | 3045 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 3003 InitializeForEachStatement(loop, expression, enumerable, body); | 3046 InitializeForEachStatement(loop, expression, enumerable, body); |
| 3004 scope_ = saved_scope; | 3047 scope_ = saved_scope; |
| (...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3688 // Register that a break target found at the given stop in the | 3731 // Register that a break target found at the given stop in the |
| 3689 // target stack has been used from the top of the target stack. Add | 3732 // target stack has been used from the top of the target stack. Add |
| 3690 // the break target to any TargetCollectors passed on the stack. | 3733 // the break target to any TargetCollectors passed on the stack. |
| 3691 for (Target* t = target_stack_; t != stop; t = t->previous()) { | 3734 for (Target* t = target_stack_; t != stop; t = t->previous()) { |
| 3692 TargetCollector* collector = t->node()->AsTargetCollector(); | 3735 TargetCollector* collector = t->node()->AsTargetCollector(); |
| 3693 if (collector != NULL) collector->AddTarget(target, zone()); | 3736 if (collector != NULL) collector->AddTarget(target, zone()); |
| 3694 } | 3737 } |
| 3695 } | 3738 } |
| 3696 | 3739 |
| 3697 | 3740 |
| 3698 Expression* Parser::NewThrowReferenceError(Handle<String> message) { | |
| 3699 return NewThrowError(isolate()->factory()->MakeReferenceError_string(), | |
| 3700 message, HandleVector<Object>(NULL, 0)); | |
| 3701 } | |
| 3702 | |
| 3703 | |
| 3704 Expression* Parser::NewThrowSyntaxError(Handle<String> message, | |
| 3705 Handle<Object> first) { | |
| 3706 int argc = first.is_null() ? 0 : 1; | |
| 3707 Vector< Handle<Object> > arguments = HandleVector<Object>(&first, argc); | |
| 3708 return NewThrowError( | |
| 3709 isolate()->factory()->MakeSyntaxError_string(), message, arguments); | |
| 3710 } | |
| 3711 | |
| 3712 | |
| 3713 Expression* Parser::NewThrowTypeError(Handle<String> message, | |
| 3714 Handle<Object> first, | |
| 3715 Handle<Object> second) { | |
| 3716 ASSERT(!first.is_null() && !second.is_null()); | |
| 3717 Handle<Object> elements[] = { first, second }; | |
| 3718 Vector< Handle<Object> > arguments = | |
| 3719 HandleVector<Object>(elements, ARRAY_SIZE(elements)); | |
| 3720 return NewThrowError( | |
| 3721 isolate()->factory()->MakeTypeError_string(), message, arguments); | |
| 3722 } | |
| 3723 | |
| 3724 | |
| 3725 Expression* Parser::NewThrowError(Handle<String> constructor, | |
| 3726 Handle<String> message, | |
| 3727 Vector< Handle<Object> > arguments) { | |
| 3728 int argc = arguments.length(); | |
| 3729 Handle<FixedArray> elements = isolate()->factory()->NewFixedArray(argc, | |
| 3730 TENURED); | |
| 3731 for (int i = 0; i < argc; i++) { | |
| 3732 Handle<Object> element = arguments[i]; | |
| 3733 if (!element.is_null()) { | |
| 3734 elements->set(i, *element); | |
| 3735 } | |
| 3736 } | |
| 3737 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements( | |
| 3738 elements, FAST_ELEMENTS, TENURED); | |
| 3739 | |
| 3740 int pos = position(); | |
| 3741 ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2, zone()); | |
| 3742 args->Add(factory()->NewLiteral(message, pos), zone()); | |
| 3743 args->Add(factory()->NewLiteral(array, pos), zone()); | |
| 3744 CallRuntime* call_constructor = | |
| 3745 factory()->NewCallRuntime(constructor, NULL, args, pos); | |
| 3746 return factory()->NewThrow(call_constructor, pos); | |
| 3747 } | |
| 3748 | |
| 3749 | |
| 3750 // ---------------------------------------------------------------------------- | 3741 // ---------------------------------------------------------------------------- |
| 3751 // Regular expressions | 3742 // Regular expressions |
| 3752 | 3743 |
| 3753 | 3744 |
| 3754 RegExpParser::RegExpParser(FlatStringReader* in, | 3745 RegExpParser::RegExpParser(FlatStringReader* in, |
| 3755 Handle<String>* error, | 3746 Handle<String>* error, |
| 3756 bool multiline, | 3747 bool multiline, |
| 3757 Zone* zone) | 3748 Zone* zone) |
| 3758 : isolate_(zone->isolate()), | 3749 : isolate_(zone->isolate()), |
| 3759 zone_(zone), | 3750 zone_(zone), |
| (...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4697 ASSERT(info()->isolate()->has_pending_exception()); | 4688 ASSERT(info()->isolate()->has_pending_exception()); |
| 4698 } else { | 4689 } else { |
| 4699 result = ParseProgram(); | 4690 result = ParseProgram(); |
| 4700 } | 4691 } |
| 4701 } | 4692 } |
| 4702 info()->SetFunction(result); | 4693 info()->SetFunction(result); |
| 4703 return (result != NULL); | 4694 return (result != NULL); |
| 4704 } | 4695 } |
| 4705 | 4696 |
| 4706 } } // namespace v8::internal | 4697 } } // namespace v8::internal |
| OLD | NEW |