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 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 } | 583 } |
584 // ...and one more time for '~foo' => 'foo^(~0)'. | 584 // ...and one more time for '~foo' => 'foo^(~0)'. |
585 if (op == Token::BIT_NOT) { | 585 if (op == Token::BIT_NOT) { |
586 return factory->NewBinaryOperation( | 586 return factory->NewBinaryOperation( |
587 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); | 587 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); |
588 } | 588 } |
589 return factory->NewUnaryOperation(op, expression, pos); | 589 return factory->NewUnaryOperation(op, expression, pos); |
590 } | 590 } |
591 | 591 |
592 | 592 |
593 Expression* ParserTraits::NewThrowReferenceError( | 593 Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) { |
594 const char* message, int pos) { | |
595 return NewThrowError( | 594 return NewThrowError( |
596 parser_->isolate()->factory()->MakeReferenceError_string(), | 595 parser_->isolate()->factory()->MakeReferenceError_string(), |
597 message, HandleVector<Object>(NULL, 0), pos); | 596 message, HandleVector<Object>(NULL, 0), pos); |
598 } | 597 } |
599 | 598 |
600 | 599 |
601 Expression* ParserTraits::NewThrowSyntaxError( | 600 Expression* ParserTraits::NewThrowSyntaxError( |
602 const char* message, Handle<Object> arg, int pos) { | 601 const char* message, Handle<Object> arg, int pos) { |
603 int argc = arg.is_null() ? 0 : 1; | 602 int argc = arg.is_null() ? 0 : 1; |
604 Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc); | 603 Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc); |
605 return NewThrowError( | 604 return NewThrowError( |
606 parser_->isolate()->factory()->MakeSyntaxError_string(), | 605 parser_->isolate()->factory()->MakeSyntaxError_string(), |
607 message, arguments, pos); | 606 message, arguments, pos); |
608 } | 607 } |
609 | 608 |
610 | 609 |
611 Expression* ParserTraits::NewThrowTypeError( | 610 Expression* ParserTraits::NewThrowTypeError( |
612 const char* message, Handle<Object> arg1, Handle<Object> arg2, int pos) { | 611 const char* message, Handle<Object> arg, int pos) { |
613 ASSERT(!arg1.is_null() && !arg2.is_null()); | 612 int argc = arg.is_null() ? 0 : 1; |
614 Handle<Object> elements[] = { arg1, arg2 }; | 613 Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc); |
615 Vector< Handle<Object> > arguments = | |
616 HandleVector<Object>(elements, ARRAY_SIZE(elements)); | |
617 return NewThrowError( | 614 return NewThrowError( |
618 parser_->isolate()->factory()->MakeTypeError_string(), | 615 parser_->isolate()->factory()->MakeTypeError_string(), |
619 message, arguments, pos); | 616 message, arguments, pos); |
620 } | 617 } |
621 | 618 |
622 | 619 |
623 Expression* ParserTraits::NewThrowError( | 620 Expression* ParserTraits::NewThrowError( |
624 Handle<String> constructor, const char* message, | 621 Handle<String> constructor, const char* message, |
625 Vector<Handle<Object> > arguments, int pos) { | 622 Vector<Handle<Object> > arguments, int pos) { |
626 Zone* zone = parser_->zone(); | 623 Zone* zone = parser_->zone(); |
(...skipping 1120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1747 // | 1744 // |
1748 // function () { let x; { var x; } } | 1745 // function () { let x; { var x; } } |
1749 // | 1746 // |
1750 // because the var declaration is hoisted to the function scope where 'x' | 1747 // because the var declaration is hoisted to the function scope where 'x' |
1751 // is already bound. | 1748 // is already bound. |
1752 ASSERT(IsDeclaredVariableMode(var->mode())); | 1749 ASSERT(IsDeclaredVariableMode(var->mode())); |
1753 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 1750 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
1754 // In harmony we treat re-declarations as early errors. See | 1751 // In harmony we treat re-declarations as early errors. See |
1755 // ES5 16 for a definition of early errors. | 1752 // ES5 16 for a definition of early errors. |
1756 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | 1753 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
1757 const char* elms[2] = { "Variable", c_string.get() }; | 1754 const char* elms[1] = { c_string.get() }; |
1758 Vector<const char*> args(elms, 2); | 1755 Vector<const char*> args(elms, 1); |
1759 ReportMessage("redeclaration", args); | 1756 ReportMessage("var_redeclaration", args); |
1760 *ok = false; | 1757 *ok = false; |
1761 return; | 1758 return; |
1762 } | 1759 } |
1763 Handle<String> message_string = | 1760 Expression* expression = NewThrowTypeError( |
1764 isolate()->factory()->InternalizeOneByteString( | 1761 "var_redeclaration", name, declaration->position()); |
1765 STATIC_ASCII_VECTOR("Variable")); | |
1766 Expression* expression = | |
1767 NewThrowTypeError("redeclaration", | |
1768 message_string, name, declaration->position()); | |
1769 declaration_scope->SetIllegalRedeclaration(expression); | 1762 declaration_scope->SetIllegalRedeclaration(expression); |
1770 } | 1763 } |
1771 } | 1764 } |
1772 | 1765 |
1773 // We add a declaration node for every declaration. The compiler | 1766 // We add a declaration node for every declaration. The compiler |
1774 // will only generate code if necessary. In particular, declarations | 1767 // will only generate code if necessary. In particular, declarations |
1775 // for inner local variables that do not represent functions won't | 1768 // for inner local variables that do not represent functions won't |
1776 // result in any generated code. | 1769 // result in any generated code. |
1777 // | 1770 // |
1778 // Note that we always add an unresolved proxy even if it's not | 1771 // Note that we always add an unresolved proxy even if it's not |
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2367 // identifier. | 2360 // identifier. |
2368 VariableProxy* var = expr->AsVariableProxy(); | 2361 VariableProxy* var = expr->AsVariableProxy(); |
2369 Handle<String> label = var->name(); | 2362 Handle<String> label = var->name(); |
2370 // TODO(1240780): We don't check for redeclaration of labels | 2363 // TODO(1240780): We don't check for redeclaration of labels |
2371 // during preparsing since keeping track of the set of active | 2364 // during preparsing since keeping track of the set of active |
2372 // labels requires nontrivial changes to the way scopes are | 2365 // labels requires nontrivial changes to the way scopes are |
2373 // structured. However, these are probably changes we want to | 2366 // structured. However, these are probably changes we want to |
2374 // make later anyway so we should go back and fix this then. | 2367 // make later anyway so we should go back and fix this then. |
2375 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { | 2368 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { |
2376 SmartArrayPointer<char> c_string = label->ToCString(DISALLOW_NULLS); | 2369 SmartArrayPointer<char> c_string = label->ToCString(DISALLOW_NULLS); |
2377 const char* elms[2] = { "Label", c_string.get() }; | 2370 const char* elms[1] = { c_string.get() }; |
2378 Vector<const char*> args(elms, 2); | 2371 Vector<const char*> args(elms, 1); |
2379 ReportMessage("redeclaration", args); | 2372 ReportMessage("label_redeclaration", args); |
2380 *ok = false; | 2373 *ok = false; |
2381 return NULL; | 2374 return NULL; |
2382 } | 2375 } |
2383 if (labels == NULL) { | 2376 if (labels == NULL) { |
2384 labels = new(zone()) ZoneStringList(4, zone()); | 2377 labels = new(zone()) ZoneStringList(4, zone()); |
2385 } | 2378 } |
2386 labels->Add(label, zone()); | 2379 labels->Add(label, zone()); |
2387 // Remove the "ghost" variable that turned out to be a label | 2380 // Remove the "ghost" variable that turned out to be a label |
2388 // from the top scope. This way, we don't try to resolve it | 2381 // from the top scope. This way, we don't try to resolve it |
2389 // during the scope processing. | 2382 // during the scope processing. |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2514 | 2507 |
2515 | 2508 |
2516 Statement* Parser::ParseReturnStatement(bool* ok) { | 2509 Statement* Parser::ParseReturnStatement(bool* ok) { |
2517 // ReturnStatement :: | 2510 // ReturnStatement :: |
2518 // 'return' Expression? ';' | 2511 // 'return' Expression? ';' |
2519 | 2512 |
2520 // Consume the return token. It is necessary to do that before | 2513 // Consume the return token. It is necessary to do that before |
2521 // reporting any errors on it, because of the way errors are | 2514 // reporting any errors on it, because of the way errors are |
2522 // reported (underlining). | 2515 // reported (underlining). |
2523 Expect(Token::RETURN, CHECK_OK); | 2516 Expect(Token::RETURN, CHECK_OK); |
2524 int pos = position(); | 2517 Scanner::Location loc = scanner()->location(); |
2525 | 2518 |
2526 Token::Value tok = peek(); | 2519 Token::Value tok = peek(); |
2527 Statement* result; | 2520 Statement* result; |
2528 Expression* return_value; | 2521 Expression* return_value; |
2529 if (scanner()->HasAnyLineTerminatorBeforeNext() || | 2522 if (scanner()->HasAnyLineTerminatorBeforeNext() || |
2530 tok == Token::SEMICOLON || | 2523 tok == Token::SEMICOLON || |
2531 tok == Token::RBRACE || | 2524 tok == Token::RBRACE || |
2532 tok == Token::EOS) { | 2525 tok == Token::EOS) { |
2533 return_value = GetLiteralUndefined(position()); | 2526 return_value = GetLiteralUndefined(position()); |
2534 } else { | 2527 } else { |
2535 return_value = ParseExpression(true, CHECK_OK); | 2528 return_value = ParseExpression(true, CHECK_OK); |
2536 } | 2529 } |
2537 ExpectSemicolon(CHECK_OK); | 2530 ExpectSemicolon(CHECK_OK); |
2538 if (is_generator()) { | 2531 if (is_generator()) { |
2539 Expression* generator = factory()->NewVariableProxy( | 2532 Expression* generator = factory()->NewVariableProxy( |
2540 function_state_->generator_object_variable()); | 2533 function_state_->generator_object_variable()); |
2541 Expression* yield = factory()->NewYield( | 2534 Expression* yield = factory()->NewYield( |
2542 generator, return_value, Yield::FINAL, pos); | 2535 generator, return_value, Yield::FINAL, loc.beg_pos); |
2543 result = factory()->NewExpressionStatement(yield, pos); | 2536 result = factory()->NewExpressionStatement(yield, loc.beg_pos); |
2544 } else { | 2537 } else { |
2545 result = factory()->NewReturnStatement(return_value, pos); | 2538 result = factory()->NewReturnStatement(return_value, loc.beg_pos); |
2546 } | 2539 } |
2547 | 2540 |
2548 // An ECMAScript program is considered syntactically incorrect if it | 2541 Scope* decl_scope = scope_->DeclarationScope(); |
2549 // contains a return statement that is not within the body of a | 2542 if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) { |
2550 // function. See ECMA-262, section 12.9, page 67. | 2543 ReportMessageAt(loc, "illegal_return"); |
2551 // | 2544 *ok = false; |
2552 // To be consistent with KJS we report the syntax error at runtime. | 2545 return NULL; |
2553 Scope* declaration_scope = scope_->DeclarationScope(); | |
2554 if (declaration_scope->is_global_scope() || | |
2555 declaration_scope->is_eval_scope()) { | |
2556 Expression* throw_error = | |
2557 NewThrowSyntaxError("illegal_return", Handle<Object>::null(), pos); | |
2558 return factory()->NewExpressionStatement(throw_error, pos); | |
2559 } | 2546 } |
2560 return result; | 2547 return result; |
2561 } | 2548 } |
2562 | 2549 |
2563 | 2550 |
2564 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 2551 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
2565 // WithStatement :: | 2552 // WithStatement :: |
2566 // 'with' '(' Expression ')' Statement | 2553 // 'with' '(' Expression ')' Statement |
2567 | 2554 |
2568 Expect(Token::WITH, CHECK_OK); | 2555 Expect(Token::WITH, CHECK_OK); |
(...skipping 1093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3662 } | 3649 } |
3663 | 3650 |
3664 | 3651 |
3665 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 3652 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
3666 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 3653 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
3667 if (decl != NULL) { | 3654 if (decl != NULL) { |
3668 // In harmony mode we treat conflicting variable bindinds as early | 3655 // In harmony mode we treat conflicting variable bindinds as early |
3669 // errors. See ES5 16 for a definition of early errors. | 3656 // errors. See ES5 16 for a definition of early errors. |
3670 Handle<String> name = decl->proxy()->name(); | 3657 Handle<String> name = decl->proxy()->name(); |
3671 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | 3658 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
3672 const char* elms[2] = { "Variable", c_string.get() }; | 3659 const char* elms[1] = { c_string.get() }; |
3673 Vector<const char*> args(elms, 2); | 3660 Vector<const char*> args(elms, 1); |
3674 int position = decl->proxy()->position(); | 3661 int position = decl->proxy()->position(); |
3675 Scanner::Location location = position == RelocInfo::kNoPosition | 3662 Scanner::Location location = position == RelocInfo::kNoPosition |
3676 ? Scanner::Location::invalid() | 3663 ? Scanner::Location::invalid() |
3677 : Scanner::Location(position, position + 1); | 3664 : Scanner::Location(position, position + 1); |
3678 ParserTraits::ReportMessageAt(location, "redeclaration", args); | 3665 ParserTraits::ReportMessageAt(location, "var_redeclaration", args); |
3679 *ok = false; | 3666 *ok = false; |
3680 } | 3667 } |
3681 } | 3668 } |
3682 | 3669 |
3683 | 3670 |
3684 // ---------------------------------------------------------------------------- | 3671 // ---------------------------------------------------------------------------- |
3685 // Parser support | 3672 // Parser support |
3686 | 3673 |
3687 | 3674 |
3688 bool Parser::TargetStackContainsLabel(Handle<String> label) { | 3675 bool Parser::TargetStackContainsLabel(Handle<String> label) { |
(...skipping 1000 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4689 ASSERT(info()->isolate()->has_pending_exception()); | 4676 ASSERT(info()->isolate()->has_pending_exception()); |
4690 } else { | 4677 } else { |
4691 result = ParseProgram(); | 4678 result = ParseProgram(); |
4692 } | 4679 } |
4693 } | 4680 } |
4694 info()->SetFunction(result); | 4681 info()->SetFunction(result); |
4695 return (result != NULL); | 4682 return (result != NULL); |
4696 } | 4683 } |
4697 | 4684 |
4698 } } // namespace v8::internal | 4685 } } // namespace v8::internal |
OLD | NEW |