Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: src/parser.cc

Issue 217823003: Make invalid LHSs that are calls late errors (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comments Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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 expression = this->CheckAndRewriteReferenceExpression(
2991 ReportMessageAt(lhs_location, "invalid_lhs_in_for", true); 3032 expression, lhs_location, "invalid_lhs_in_for", CHECK_OK);
2992 *ok = false; 3033
2993 return NULL;
2994 }
2995 ForEachStatement* loop = 3034 ForEachStatement* loop =
2996 factory()->NewForEachStatement(mode, labels, pos); 3035 factory()->NewForEachStatement(mode, labels, pos);
2997 Target target(&this->target_stack_, loop); 3036 Target target(&this->target_stack_, loop);
2998 3037
2999 Expression* enumerable = ParseExpression(true, CHECK_OK); 3038 Expression* enumerable = ParseExpression(true, CHECK_OK);
3000 Expect(Token::RPAREN, CHECK_OK); 3039 Expect(Token::RPAREN, CHECK_OK);
3001 3040
3002 Statement* body = ParseStatement(NULL, CHECK_OK); 3041 Statement* body = ParseStatement(NULL, CHECK_OK);
3003 InitializeForEachStatement(loop, expression, enumerable, body); 3042 InitializeForEachStatement(loop, expression, enumerable, body);
3004 scope_ = saved_scope; 3043 scope_ = saved_scope;
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after
3688 // Register that a break target found at the given stop in the 3727 // 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 3728 // target stack has been used from the top of the target stack. Add
3690 // the break target to any TargetCollectors passed on the stack. 3729 // the break target to any TargetCollectors passed on the stack.
3691 for (Target* t = target_stack_; t != stop; t = t->previous()) { 3730 for (Target* t = target_stack_; t != stop; t = t->previous()) {
3692 TargetCollector* collector = t->node()->AsTargetCollector(); 3731 TargetCollector* collector = t->node()->AsTargetCollector();
3693 if (collector != NULL) collector->AddTarget(target, zone()); 3732 if (collector != NULL) collector->AddTarget(target, zone());
3694 } 3733 }
3695 } 3734 }
3696 3735
3697 3736
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 // ---------------------------------------------------------------------------- 3737 // ----------------------------------------------------------------------------
3751 // Regular expressions 3738 // Regular expressions
3752 3739
3753 3740
3754 RegExpParser::RegExpParser(FlatStringReader* in, 3741 RegExpParser::RegExpParser(FlatStringReader* in,
3755 Handle<String>* error, 3742 Handle<String>* error,
3756 bool multiline, 3743 bool multiline,
3757 Zone* zone) 3744 Zone* zone)
3758 : isolate_(zone->isolate()), 3745 : isolate_(zone->isolate()),
3759 zone_(zone), 3746 zone_(zone),
(...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after
4697 ASSERT(info()->isolate()->has_pending_exception()); 4684 ASSERT(info()->isolate()->has_pending_exception());
4698 } else { 4685 } else {
4699 result = ParseProgram(); 4686 result = ParseProgram();
4700 } 4687 }
4701 } 4688 }
4702 info()->SetFunction(result); 4689 info()->SetFunction(result);
4703 return (result != NULL); 4690 return (result != NULL);
4704 } 4691 }
4705 4692
4706 } } // namespace v8::internal 4693 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698