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

Side by Side Diff: src/parser.cc

Issue 7860035: Merge bleeding edge up to 9192 into the GC branch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Created 9 years, 3 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/platform.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 12 matching lines...) Expand all
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "api.h" 30 #include "api.h"
31 #include "ast-inl.h" 31 #include "ast-inl.h"
32 #include "bootstrapper.h" 32 #include "bootstrapper.h"
33 #include "char-predicates-inl.h"
33 #include "codegen.h" 34 #include "codegen.h"
34 #include "compiler.h" 35 #include "compiler.h"
35 #include "func-name-inferrer.h" 36 #include "func-name-inferrer.h"
36 #include "messages.h" 37 #include "messages.h"
37 #include "parser.h" 38 #include "parser.h"
38 #include "platform.h" 39 #include "platform.h"
39 #include "preparser.h" 40 #include "preparser.h"
40 #include "runtime.h" 41 #include "runtime.h"
41 #include "scopeinfo.h" 42 #include "scopeinfo.h"
42 #include "string-stream.h" 43 #include "string-stream.h"
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 only_simple_this_property_assignments_(false), 526 only_simple_this_property_assignments_(false),
526 this_property_assignments_(isolate->factory()->empty_fixed_array()), 527 this_property_assignments_(isolate->factory()->empty_fixed_array()),
527 parser_(parser), 528 parser_(parser),
528 lexical_scope_parent_(parser->lexical_scope_), 529 lexical_scope_parent_(parser->lexical_scope_),
529 previous_scope_(parser->top_scope_), 530 previous_scope_(parser->top_scope_),
530 previous_with_nesting_level_(parser->with_nesting_level_), 531 previous_with_nesting_level_(parser->with_nesting_level_),
531 previous_ast_node_id_(isolate->ast_node_id()) { 532 previous_ast_node_id_(isolate->ast_node_id()) {
532 parser->top_scope_ = scope; 533 parser->top_scope_ = scope;
533 parser->lexical_scope_ = this; 534 parser->lexical_scope_ = this;
534 parser->with_nesting_level_ = 0; 535 parser->with_nesting_level_ = 0;
535 isolate->set_ast_node_id(AstNode::kFunctionEntryId + 1); 536 isolate->set_ast_node_id(AstNode::kDeclarationsId + 1);
536 } 537 }
537 538
538 539
539 LexicalScope::~LexicalScope() { 540 LexicalScope::~LexicalScope() {
540 parser_->top_scope_ = previous_scope_; 541 parser_->top_scope_ = previous_scope_;
541 parser_->lexical_scope_ = lexical_scope_parent_; 542 parser_->lexical_scope_ = lexical_scope_parent_;
542 parser_->with_nesting_level_ = previous_with_nesting_level_; 543 parser_->with_nesting_level_ = previous_with_nesting_level_;
543 parser_->isolate()->set_ast_node_id(previous_ast_node_id_); 544 parser_->isolate()->set_ast_node_id(previous_ast_node_id_);
544 } 545 }
545 546
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 if (strict_mode == kStrictMode) { 641 if (strict_mode == kStrictMode) {
641 top_scope_->EnableStrictMode(); 642 top_scope_->EnableStrictMode();
642 } 643 }
643 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16); 644 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16);
644 bool ok = true; 645 bool ok = true;
645 int beg_loc = scanner().location().beg_pos; 646 int beg_loc = scanner().location().beg_pos;
646 ParseSourceElements(body, Token::EOS, &ok); 647 ParseSourceElements(body, Token::EOS, &ok);
647 if (ok && top_scope_->is_strict_mode()) { 648 if (ok && top_scope_->is_strict_mode()) {
648 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); 649 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
649 } 650 }
651
652 if (ok && harmony_block_scoping_) {
653 CheckConflictingVarDeclarations(scope, &ok);
654 }
655
650 if (ok) { 656 if (ok) {
651 result = new(zone()) FunctionLiteral( 657 result = new(zone()) FunctionLiteral(
652 isolate(), 658 isolate(),
653 no_name, 659 no_name,
654 top_scope_, 660 top_scope_,
655 body, 661 body,
656 lexical_scope.materialized_literal_count(), 662 lexical_scope.materialized_literal_count(),
657 lexical_scope.expected_property_count(), 663 lexical_scope.expected_property_count(),
658 lexical_scope.only_simple_this_property_assignments(), 664 lexical_scope.only_simple_this_property_assignments(),
659 lexical_scope.this_property_assignments(), 665 lexical_scope.this_property_assignments(),
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after
1336 : top_scope_->DeclarationScope(); 1342 : top_scope_->DeclarationScope();
1337 if (declaration_scope->is_function_scope() || 1343 if (declaration_scope->is_function_scope() ||
1338 declaration_scope->is_strict_mode_eval_scope() || 1344 declaration_scope->is_strict_mode_eval_scope() ||
1339 declaration_scope->is_block_scope()) { 1345 declaration_scope->is_block_scope()) {
1340 // Declare the variable in the function scope. 1346 // Declare the variable in the function scope.
1341 var = declaration_scope->LocalLookup(name); 1347 var = declaration_scope->LocalLookup(name);
1342 if (var == NULL) { 1348 if (var == NULL) {
1343 // Declare the name. 1349 // Declare the name.
1344 var = declaration_scope->DeclareLocal(name, mode); 1350 var = declaration_scope->DeclareLocal(name, mode);
1345 } else { 1351 } else {
1346 // The name was declared before; check for conflicting re-declarations. 1352 // The name was declared in this scope before; check for conflicting
1347 // We have a conflict if either of the declarations is not a var. There 1353 // re-declarations. We have a conflict if either of the declarations is
1348 // is similar code in runtime.cc in the Declare functions. 1354 // not a var. There is similar code in runtime.cc in the Declare
1355 // functions. The function CheckNonConflictingScope checks for conflicting
1356 // var and let bindings from different scopes whereas this is a check for
1357 // conflicting declarations within the same scope. This check also covers
1358 //
1359 // function () { let x; { var x; } }
1360 //
1361 // because the var declaration is hoisted to the function scope where 'x'
1362 // is already bound.
1349 if ((mode != Variable::VAR) || (var->mode() != Variable::VAR)) { 1363 if ((mode != Variable::VAR) || (var->mode() != Variable::VAR)) {
1350 // We only have vars, consts and lets in declarations. 1364 // We only have vars, consts and lets in declarations.
1351 ASSERT(var->mode() == Variable::VAR || 1365 ASSERT(var->mode() == Variable::VAR ||
1352 var->mode() == Variable::CONST || 1366 var->mode() == Variable::CONST ||
1353 var->mode() == Variable::LET); 1367 var->mode() == Variable::LET);
1368 if (harmony_block_scoping_) {
1369 // In harmony mode we treat re-declarations as early errors. See
1370 // ES5 16 for a definition of early errors.
1371 SmartPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
1372 const char* elms[2] = { "Variable", *c_string };
1373 Vector<const char*> args(elms, 2);
1374 ReportMessage("redeclaration", args);
1375 *ok = false;
1376 return NULL;
1377 }
1354 const char* type = (var->mode() == Variable::VAR) ? "var" : 1378 const char* type = (var->mode() == Variable::VAR) ? "var" :
1355 (var->mode() == Variable::CONST) ? "const" : "let"; 1379 (var->mode() == Variable::CONST) ? "const" : "let";
1356 Handle<String> type_string = 1380 Handle<String> type_string =
1357 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); 1381 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED);
1358 Expression* expression = 1382 Expression* expression =
1359 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), 1383 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
1360 type_string, name); 1384 type_string, name);
1361 declaration_scope->SetIllegalRedeclaration(expression); 1385 declaration_scope->SetIllegalRedeclaration(expression);
1362 } 1386 }
1363 } 1387 }
1364 } 1388 }
1365 1389
1366 // We add a declaration node for every declaration. The compiler 1390 // We add a declaration node for every declaration. The compiler
1367 // will only generate code if necessary. In particular, declarations 1391 // will only generate code if necessary. In particular, declarations
1368 // for inner local variables that do not represent functions won't 1392 // for inner local variables that do not represent functions won't
1369 // result in any generated code. 1393 // result in any generated code.
1370 // 1394 //
1371 // Note that we always add an unresolved proxy even if it's not 1395 // Note that we always add an unresolved proxy even if it's not
1372 // used, simply because we don't know in this method (w/o extra 1396 // used, simply because we don't know in this method (w/o extra
1373 // parameters) if the proxy is needed or not. The proxy will be 1397 // parameters) if the proxy is needed or not. The proxy will be
1374 // bound during variable resolution time unless it was pre-bound 1398 // bound during variable resolution time unless it was pre-bound
1375 // below. 1399 // below.
1376 // 1400 //
1377 // WARNING: This will lead to multiple declaration nodes for the 1401 // WARNING: This will lead to multiple declaration nodes for the
1378 // same variable if it is declared several times. This is not a 1402 // same variable if it is declared several times. This is not a
1379 // semantic issue as long as we keep the source order, but it may be 1403 // semantic issue as long as we keep the source order, but it may be
1380 // a performance issue since it may lead to repeated 1404 // a performance issue since it may lead to repeated
1381 // Runtime::DeclareContextSlot() calls. 1405 // Runtime::DeclareContextSlot() calls.
1382 VariableProxy* proxy = declaration_scope->NewUnresolved(name, false); 1406 VariableProxy* proxy = declaration_scope->NewUnresolved(
1383 declaration_scope->AddDeclaration(new(zone()) Declaration(proxy, mode, fun)); 1407 name, false, scanner().location().beg_pos);
1408 declaration_scope->AddDeclaration(
1409 new(zone()) Declaration(proxy, mode, fun, top_scope_));
1384 1410
1385 // For global const variables we bind the proxy to a variable. 1411 // For global const variables we bind the proxy to a variable.
1386 if (mode == Variable::CONST && declaration_scope->is_global_scope()) { 1412 if (mode == Variable::CONST && declaration_scope->is_global_scope()) {
1387 ASSERT(resolve); // should be set by all callers 1413 ASSERT(resolve); // should be set by all callers
1388 Variable::Kind kind = Variable::NORMAL; 1414 Variable::Kind kind = Variable::NORMAL;
1389 var = new(zone()) Variable(declaration_scope, 1415 var = new(zone()) Variable(declaration_scope,
1390 name, 1416 name,
1391 Variable::CONST, 1417 Variable::CONST,
1392 true, 1418 true,
1393 kind); 1419 kind);
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1527 } 1553 }
1528 1554
1529 1555
1530 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { 1556 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
1531 // Construct block expecting 16 statements. 1557 // Construct block expecting 16 statements.
1532 Block* body = new(zone()) Block(isolate(), labels, 16, false); 1558 Block* body = new(zone()) Block(isolate(), labels, 16, false);
1533 Scope* saved_scope = top_scope_; 1559 Scope* saved_scope = top_scope_;
1534 Scope* block_scope = NewScope(top_scope_, 1560 Scope* block_scope = NewScope(top_scope_,
1535 Scope::BLOCK_SCOPE, 1561 Scope::BLOCK_SCOPE,
1536 inside_with()); 1562 inside_with());
1537 body->set_block_scope(block_scope);
1538 block_scope->DeclareLocal(isolate()->factory()->block_scope_symbol(),
1539 Variable::VAR);
1540 if (top_scope_->is_strict_mode()) { 1563 if (top_scope_->is_strict_mode()) {
1541 block_scope->EnableStrictMode(); 1564 block_scope->EnableStrictMode();
1542 } 1565 }
1543 top_scope_ = block_scope; 1566 top_scope_ = block_scope;
1544 1567
1545 // Parse the statements and collect escaping labels. 1568 // Parse the statements and collect escaping labels.
1546 TargetCollector collector; 1569 TargetCollector collector;
1547 Target target(&this->target_stack_, &collector); 1570 Target target(&this->target_stack_, &collector);
1548 Expect(Token::LBRACE, CHECK_OK); 1571 Expect(Token::LBRACE, CHECK_OK);
1549 { 1572 {
1550 Target target_body(&this->target_stack_, body); 1573 Target target_body(&this->target_stack_, body);
1551 InitializationBlockFinder block_finder(top_scope_, target_stack_); 1574 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1552 1575
1553 while (peek() != Token::RBRACE) { 1576 while (peek() != Token::RBRACE) {
1554 Statement* stat = ParseSourceElement(NULL, CHECK_OK); 1577 Statement* stat = ParseSourceElement(NULL, CHECK_OK);
1555 if (stat && !stat->IsEmpty()) { 1578 if (stat && !stat->IsEmpty()) {
1556 body->AddStatement(stat); 1579 body->AddStatement(stat);
1557 block_finder.Update(stat); 1580 block_finder.Update(stat);
1558 } 1581 }
1559 } 1582 }
1560 } 1583 }
1561 Expect(Token::RBRACE, CHECK_OK); 1584 Expect(Token::RBRACE, CHECK_OK);
1562
1563 // Create exit block.
1564 Block* exit = new(zone()) Block(isolate(), NULL, 1, false);
1565 exit->AddStatement(new(zone()) ExitContextStatement());
1566
1567 // Create a try-finally statement.
1568 TryFinallyStatement* try_finally =
1569 new(zone()) TryFinallyStatement(body, exit);
1570 try_finally->set_escaping_targets(collector.targets());
1571 top_scope_ = saved_scope; 1585 top_scope_ = saved_scope;
1572 1586
1573 // Create a result block. 1587 block_scope = block_scope->FinalizeBlockScope();
1574 Block* result = new(zone()) Block(isolate(), NULL, 1, false); 1588 body->set_block_scope(block_scope);
1575 result->AddStatement(try_finally); 1589 return body;
1576 return result;
1577 } 1590 }
1578 1591
1579 1592
1580 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, 1593 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
1581 bool* ok) { 1594 bool* ok) {
1582 // VariableStatement :: 1595 // VariableStatement ::
1583 // VariableDeclarations ';' 1596 // VariableDeclarations ';'
1584 1597
1585 Handle<String> ignore; 1598 Handle<String> ignore;
1586 Block* result = ParseVariableDeclarations(var_context, 1599 Block* result = ParseVariableDeclarations(var_context,
(...skipping 15 matching lines...) Expand all
1602 // *var is untouched; in particular, it is the caller's responsibility 1615 // *var is untouched; in particular, it is the caller's responsibility
1603 // to initialize it properly. This mechanism is used for the parsing 1616 // to initialize it properly. This mechanism is used for the parsing
1604 // of 'for-in' loops. 1617 // of 'for-in' loops.
1605 Block* Parser::ParseVariableDeclarations(VariableDeclarationContext var_context, 1618 Block* Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
1606 Handle<String>* out, 1619 Handle<String>* out,
1607 bool* ok) { 1620 bool* ok) {
1608 // VariableDeclarations :: 1621 // VariableDeclarations ::
1609 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 1622 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
1610 1623
1611 Variable::Mode mode = Variable::VAR; 1624 Variable::Mode mode = Variable::VAR;
1625 // True if the binding needs initialization. 'let' and 'const' declared
1626 // bindings are created uninitialized by their declaration nodes and
1627 // need initialization. 'var' declared bindings are always initialized
1628 // immediately by their declaration nodes.
1629 bool needs_init = false;
1612 bool is_const = false; 1630 bool is_const = false;
1631 Token::Value init_op = Token::INIT_VAR;
1613 if (peek() == Token::VAR) { 1632 if (peek() == Token::VAR) {
1614 Consume(Token::VAR); 1633 Consume(Token::VAR);
1615 } else if (peek() == Token::CONST) { 1634 } else if (peek() == Token::CONST) {
1616 Consume(Token::CONST); 1635 Consume(Token::CONST);
1617 if (top_scope_->is_strict_mode()) { 1636 if (top_scope_->is_strict_mode()) {
1618 ReportMessage("strict_const", Vector<const char*>::empty()); 1637 ReportMessage("strict_const", Vector<const char*>::empty());
1619 *ok = false; 1638 *ok = false;
1620 return NULL; 1639 return NULL;
1621 } 1640 }
1622 mode = Variable::CONST; 1641 mode = Variable::CONST;
1623 is_const = true; 1642 is_const = true;
1643 needs_init = true;
1644 init_op = Token::INIT_CONST;
1624 } else if (peek() == Token::LET) { 1645 } else if (peek() == Token::LET) {
1625 Consume(Token::LET); 1646 Consume(Token::LET);
1626 if (var_context != kSourceElement && 1647 if (var_context != kSourceElement &&
1627 var_context != kForStatement) { 1648 var_context != kForStatement) {
1628 ASSERT(var_context == kStatement); 1649 ASSERT(var_context == kStatement);
1629 ReportMessage("unprotected_let", Vector<const char*>::empty()); 1650 ReportMessage("unprotected_let", Vector<const char*>::empty());
1630 *ok = false; 1651 *ok = false;
1631 return NULL; 1652 return NULL;
1632 } 1653 }
1633 mode = Variable::LET; 1654 mode = Variable::LET;
1655 needs_init = true;
1656 init_op = Token::INIT_LET;
1634 } else { 1657 } else {
1635 UNREACHABLE(); // by current callers 1658 UNREACHABLE(); // by current callers
1636 } 1659 }
1637 1660
1638 Scope* declaration_scope = mode == Variable::LET 1661 Scope* declaration_scope = mode == Variable::LET
1639 ? top_scope_ : top_scope_->DeclarationScope(); 1662 ? top_scope_ : top_scope_->DeclarationScope();
1640 // The scope of a var/const declared variable anywhere inside a function 1663 // The scope of a var/const declared variable anywhere inside a function
1641 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can 1664 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
1642 // transform a source-level var/const declaration into a (Function) 1665 // transform a source-level var/const declaration into a (Function)
1643 // Scope declaration, and rewrite the source-level initialization into an 1666 // Scope declaration, and rewrite the source-level initialization into an
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1725 position = scanner().location().beg_pos; 1748 position = scanner().location().beg_pos;
1726 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 1749 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
1727 // Don't infer if it is "a = function(){...}();"-like expression. 1750 // Don't infer if it is "a = function(){...}();"-like expression.
1728 if (fni_ != NULL && 1751 if (fni_ != NULL &&
1729 value->AsCall() == NULL && 1752 value->AsCall() == NULL &&
1730 value->AsCallNew() == NULL) { 1753 value->AsCallNew() == NULL) {
1731 fni_->Infer(); 1754 fni_->Infer();
1732 } 1755 }
1733 } 1756 }
1734 1757
1735 // Make sure that 'const c' actually initializes 'c' to undefined 1758 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
1736 // even though it seems like a stupid thing to do. 1759 if (value == NULL && needs_init) {
1737 if (value == NULL && is_const) {
1738 value = GetLiteralUndefined(); 1760 value = GetLiteralUndefined();
1739 } 1761 }
1740 1762
1741 // Global variable declarations must be compiled in a specific 1763 // Global variable declarations must be compiled in a specific
1742 // way. When the script containing the global variable declaration 1764 // way. When the script containing the global variable declaration
1743 // is entered, the global variable must be declared, so that if it 1765 // is entered, the global variable must be declared, so that if it
1744 // doesn't exist (not even in a prototype of the global object) it 1766 // doesn't exist (not even in a prototype of the global object) it
1745 // gets created with an initial undefined value. This is handled 1767 // gets created with an initial undefined value. This is handled
1746 // by the declarations part of the function representing the 1768 // by the declarations part of the function representing the
1747 // top-level global code; see Runtime::DeclareGlobalVariable. If 1769 // top-level global code; see Runtime::DeclareGlobalVariable. If
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1804 new(zone()) CallRuntime( 1826 new(zone()) CallRuntime(
1805 isolate(), 1827 isolate(),
1806 isolate()->factory()->InitializeVarGlobal_symbol(), 1828 isolate()->factory()->InitializeVarGlobal_symbol(),
1807 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), 1829 Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
1808 arguments); 1830 arguments);
1809 } 1831 }
1810 1832
1811 block->AddStatement(new(zone()) ExpressionStatement(initialize)); 1833 block->AddStatement(new(zone()) ExpressionStatement(initialize));
1812 } 1834 }
1813 1835
1814 // Add an assignment node to the initialization statement block if 1836 // Add an assignment node to the initialization statement block if we still
1815 // we still have a pending initialization value. We must distinguish 1837 // have a pending initialization value. We must distinguish between
1816 // between variables and constants: Variable initializations are simply 1838 // different kinds of declarations: 'var' initializations are simply
1817 // assignments (with all the consequences if they are inside a 'with' 1839 // assignments (with all the consequences if they are inside a 'with'
1818 // statement - they may change a 'with' object property). Constant 1840 // statement - they may change a 'with' object property). Constant
1819 // initializations always assign to the declared constant which is 1841 // initializations always assign to the declared constant which is
1820 // always at the function scope level. This is only relevant for 1842 // always at the function scope level. This is only relevant for
1821 // dynamically looked-up variables and constants (the start context 1843 // dynamically looked-up variables and constants (the start context
1822 // for constant lookups is always the function context, while it is 1844 // for constant lookups is always the function context, while it is
1823 // the top context for variables). Sigh... 1845 // the top context for var declared variables). Sigh...
1846 // For 'let' declared variables the initialization is in the same scope
1847 // as the declaration. Thus dynamic lookups are unnecessary even if the
1848 // block scope is inside a with.
1824 if (value != NULL) { 1849 if (value != NULL) {
1825 Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR); 1850 bool in_with = mode == Variable::VAR ? inside_with() : false;
1826 bool in_with = is_const ? false : inside_with();
1827 VariableProxy* proxy = 1851 VariableProxy* proxy =
1828 initialization_scope->NewUnresolved(name, in_with); 1852 initialization_scope->NewUnresolved(name, in_with);
1829 Assignment* assignment = 1853 Assignment* assignment =
1830 new(zone()) Assignment(isolate(), op, proxy, value, position); 1854 new(zone()) Assignment(isolate(), init_op, proxy, value, position);
1831 if (block) { 1855 if (block) {
1832 block->AddStatement(new(zone()) ExpressionStatement(assignment)); 1856 block->AddStatement(new(zone()) ExpressionStatement(assignment));
1833 } 1857 }
1834 } 1858 }
1835 1859
1836 if (fni_ != NULL) fni_->Leave(); 1860 if (fni_ != NULL) fni_->Leave();
1837 } while (peek() == Token::COMMA); 1861 } while (peek() == Token::COMMA);
1838 1862
1839 // If there was a single non-const declaration, return it in the output 1863 // If there was a single non-const declaration, return it in the output
1840 // parameter for possible use by for/in. 1864 // parameter for possible use by for/in.
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
2185 2209
2186 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { 2210 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) {
2187 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); 2211 ReportMessage("strict_catch_variable", Vector<const char*>::empty());
2188 *ok = false; 2212 *ok = false;
2189 return NULL; 2213 return NULL;
2190 } 2214 }
2191 2215
2192 Expect(Token::RPAREN, CHECK_OK); 2216 Expect(Token::RPAREN, CHECK_OK);
2193 2217
2194 if (peek() == Token::LBRACE) { 2218 if (peek() == Token::LBRACE) {
2195 // Rewrite the catch body { B } to a block:
2196 // { { B } ExitContext; }.
2197 Target target(&this->target_stack_, &catch_collector); 2219 Target target(&this->target_stack_, &catch_collector);
2198 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with()); 2220 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with());
2199 if (top_scope_->is_strict_mode()) { 2221 if (top_scope_->is_strict_mode()) {
2200 catch_scope->EnableStrictMode(); 2222 catch_scope->EnableStrictMode();
2201 } 2223 }
2202 catch_variable = catch_scope->DeclareLocal(name, Variable::VAR); 2224 Variable::Mode mode = harmony_block_scoping_
2203 catch_block = new(zone()) Block(isolate(), NULL, 2, false); 2225 ? Variable::LET : Variable::VAR;
2226 catch_variable = catch_scope->DeclareLocal(name, mode);
2204 2227
2205 Scope* saved_scope = top_scope_; 2228 Scope* saved_scope = top_scope_;
2206 top_scope_ = catch_scope; 2229 top_scope_ = catch_scope;
2207 Block* catch_body = ParseBlock(NULL, CHECK_OK); 2230 catch_block = ParseBlock(NULL, CHECK_OK);
2208 top_scope_ = saved_scope; 2231 top_scope_ = saved_scope;
2209 catch_block->AddStatement(catch_body);
2210 catch_block->AddStatement(new(zone()) ExitContextStatement());
2211 } else { 2232 } else {
2212 Expect(Token::LBRACE, CHECK_OK); 2233 Expect(Token::LBRACE, CHECK_OK);
2213 } 2234 }
2214 2235
2215 tok = peek(); 2236 tok = peek();
2216 } 2237 }
2217 2238
2218 Block* finally_block = NULL; 2239 Block* finally_block = NULL;
2219 if (tok == Token::FINALLY || catch_block == NULL) { 2240 if (tok == Token::FINALLY || catch_block == NULL) {
2220 Consume(Token::FINALLY); 2241 Consume(Token::FINALLY);
(...skipping 1500 matching lines...) Expand 10 before | Expand all | Expand 10 after
3721 name_loc = scanner().location(); 3742 name_loc = scanner().location();
3722 } 3743 }
3723 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { 3744 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) {
3724 has_duplicate_parameters = true; 3745 has_duplicate_parameters = true;
3725 dupe_loc = scanner().location(); 3746 dupe_loc = scanner().location();
3726 } 3747 }
3727 if (!reserved_loc.IsValid() && is_strict_reserved) { 3748 if (!reserved_loc.IsValid() && is_strict_reserved) {
3728 reserved_loc = scanner().location(); 3749 reserved_loc = scanner().location();
3729 } 3750 }
3730 3751
3731 top_scope_->DeclareParameter(param_name); 3752 top_scope_->DeclareParameter(param_name,
3753 harmony_block_scoping_
3754 ? Variable::LET
3755 : Variable::VAR);
3732 num_parameters++; 3756 num_parameters++;
3733 if (num_parameters > kMaxNumFunctionParameters) { 3757 if (num_parameters > kMaxNumFunctionParameters) {
3734 ReportMessageAt(scanner().location(), "too_many_parameters", 3758 ReportMessageAt(scanner().location(), "too_many_parameters",
3735 Vector<const char*>::empty()); 3759 Vector<const char*>::empty());
3736 *ok = false; 3760 *ok = false;
3737 return NULL; 3761 return NULL;
3738 } 3762 }
3739 done = (peek() == Token::RPAREN); 3763 done = (peek() == Token::RPAREN);
3740 if (!done) Expect(Token::COMMA, CHECK_OK); 3764 if (!done) Expect(Token::COMMA, CHECK_OK);
3741 } 3765 }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
3848 if (reserved_loc.IsValid()) { 3872 if (reserved_loc.IsValid()) {
3849 ReportMessageAt(reserved_loc, "strict_reserved_word", 3873 ReportMessageAt(reserved_loc, "strict_reserved_word",
3850 Vector<const char*>::empty()); 3874 Vector<const char*>::empty());
3851 *ok = false; 3875 *ok = false;
3852 return NULL; 3876 return NULL;
3853 } 3877 }
3854 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); 3878 CheckOctalLiteral(start_pos, end_pos, CHECK_OK);
3855 } 3879 }
3856 } 3880 }
3857 3881
3882 if (harmony_block_scoping_) {
3883 CheckConflictingVarDeclarations(scope, CHECK_OK);
3884 }
3885
3858 FunctionLiteral* function_literal = 3886 FunctionLiteral* function_literal =
3859 new(zone()) FunctionLiteral(isolate(), 3887 new(zone()) FunctionLiteral(isolate(),
3860 function_name, 3888 function_name,
3861 scope, 3889 scope,
3862 body, 3890 body,
3863 materialized_literal_count, 3891 materialized_literal_count,
3864 expected_property_count, 3892 expected_property_count,
3865 only_simple_this_property_assignments, 3893 only_simple_this_property_assignments,
3866 this_property_assignments, 3894 this_property_assignments,
3867 num_parameters, 3895 num_parameters,
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
4054 beg_pos <= octal.beg_pos && 4082 beg_pos <= octal.beg_pos &&
4055 octal.end_pos <= end_pos) { 4083 octal.end_pos <= end_pos) {
4056 ReportMessageAt(octal, "strict_octal_literal", 4084 ReportMessageAt(octal, "strict_octal_literal",
4057 Vector<const char*>::empty()); 4085 Vector<const char*>::empty());
4058 scanner().clear_octal_position(); 4086 scanner().clear_octal_position();
4059 *ok = false; 4087 *ok = false;
4060 } 4088 }
4061 } 4089 }
4062 4090
4063 4091
4092 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
4093 Declaration* decl = scope->CheckConflictingVarDeclarations();
4094 if (decl != NULL) {
4095 // In harmony mode we treat conflicting variable bindinds as early
4096 // errors. See ES5 16 for a definition of early errors.
4097 Handle<String> name = decl->proxy()->name();
4098 SmartPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
4099 const char* elms[2] = { "Variable", *c_string };
4100 Vector<const char*> args(elms, 2);
4101 int position = decl->proxy()->position();
4102 Scanner::Location location = position == RelocInfo::kNoPosition
4103 ? Scanner::Location::invalid()
4104 : Scanner::Location(position, position + 1);
4105 ReportMessageAt(location, "redeclaration", args);
4106 *ok = false;
4107 }
4108 }
4109
4110
4064 // This function reads an identifier name and determines whether or not it 4111 // This function reads an identifier name and determines whether or not it
4065 // is 'get' or 'set'. 4112 // is 'get' or 'set'.
4066 Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get, 4113 Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get,
4067 bool* is_set, 4114 bool* is_set,
4068 bool* ok) { 4115 bool* ok) {
4069 Handle<String> result = ParseIdentifierName(ok); 4116 Handle<String> result = ParseIdentifierName(ok);
4070 if (!*ok) return Handle<String>(); 4117 if (!*ok) return Handle<String>();
4071 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) { 4118 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
4072 const char* token = scanner().literal_ascii_string().start(); 4119 const char* token = scanner().literal_ascii_string().start();
4073 *is_get = strncmp(token, "get", 3) == 0; 4120 *is_get = strncmp(token, "get", 3) == 0;
(...skipping 1101 matching lines...) Expand 10 before | Expand all | Expand 10 after
5175 result = parser.ParseProgram(source, 5222 result = parser.ParseProgram(source,
5176 info->is_global(), 5223 info->is_global(),
5177 info->StrictMode()); 5224 info->StrictMode());
5178 } 5225 }
5179 } 5226 }
5180 info->SetFunction(result); 5227 info->SetFunction(result);
5181 return (result != NULL); 5228 return (result != NULL);
5182 } 5229 }
5183 5230
5184 } } // namespace v8::internal 5231 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/platform.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698