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

Side by Side Diff: src/parser.cc

Issue 7992005: Block scoped const variables. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased. Created 9 years, 2 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 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 1123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1134 Statement* Parser::ParseSourceElement(ZoneStringList* labels, 1134 Statement* Parser::ParseSourceElement(ZoneStringList* labels,
1135 bool* ok) { 1135 bool* ok) {
1136 // (Ecma 262 5th Edition, clause 14): 1136 // (Ecma 262 5th Edition, clause 14):
1137 // SourceElement: 1137 // SourceElement:
1138 // Statement 1138 // Statement
1139 // FunctionDeclaration 1139 // FunctionDeclaration
1140 // 1140 //
1141 // In harmony mode we allow additionally the following productions 1141 // In harmony mode we allow additionally the following productions
1142 // SourceElement: 1142 // SourceElement:
1143 // LetDeclaration 1143 // LetDeclaration
1144 // ConstDeclaration
1144 1145
1145 if (peek() == Token::FUNCTION) { 1146 if (peek() == Token::FUNCTION) {
1146 return ParseFunctionDeclaration(ok); 1147 return ParseFunctionDeclaration(ok);
1147 } else if (peek() == Token::LET) { 1148 } else if (peek() == Token::LET) {
1148 return ParseVariableStatement(kSourceElement, ok); 1149 return ParseVariableStatement(kSourceElement, ok);
1149 } else { 1150 } else if (peek() == Token::CONST && harmony_scoping_) {
1150 return ParseStatement(labels, ok); 1151 return ParseHarmonyConstDeclaration(ok);
1151 } 1152 }
1153 return ParseStatement(labels, ok);
1152 } 1154 }
1153 1155
1154 1156
1155 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, 1157 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
1156 int end_token, 1158 int end_token,
1157 bool* ok) { 1159 bool* ok) {
1158 // SourceElements :: 1160 // SourceElements ::
1159 // (SourceElement)* <end_token> 1161 // (SourceElement)* <end_token>
1160 1162
1161 // Allocate a target stack to use for this set of source 1163 // Allocate a target stack to use for this set of source
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 1361
1360 VariableProxy* Parser::Declare(Handle<String> name, 1362 VariableProxy* Parser::Declare(Handle<String> name,
1361 VariableMode mode, 1363 VariableMode mode,
1362 FunctionLiteral* fun, 1364 FunctionLiteral* fun,
1363 bool resolve, 1365 bool resolve,
1364 bool* ok) { 1366 bool* ok) {
1365 Variable* var = NULL; 1367 Variable* var = NULL;
1366 // If we are inside a function, a declaration of a var/const variable is a 1368 // If we are inside a function, a declaration of a var/const variable is a
1367 // truly local variable, and the scope of the variable is always the function 1369 // truly local variable, and the scope of the variable is always the function
1368 // scope. 1370 // scope.
1371 // Let/const variables in harmony mode are always added to the immediately
1372 // enclosing scope.
1373 Scope* declaration_scope = mode == LET || mode == CONST_HARMONY
1374 ? top_scope_ : top_scope_->DeclarationScope();
1369 1375
1370 // If a function scope exists, then we can statically declare this 1376 // If a function scope exists, then we can statically declare this
1371 // variable and also set its mode. In any case, a Declaration node 1377 // variable and also set its mode. In any case, a Declaration node
1372 // will be added to the scope so that the declaration can be added 1378 // will be added to the scope so that the declaration can be added
1373 // to the corresponding activation frame at runtime if necessary. 1379 // to the corresponding activation frame at runtime if necessary.
1374 // For instance declarations inside an eval scope need to be added 1380 // For instance declarations inside an eval scope need to be added
1375 // to the calling function context. 1381 // to the calling function context.
1376 // Similarly, strict mode eval scope does not leak variable declarations to 1382 // Similarly, strict mode eval scope does not leak variable declarations to
1377 // the caller's scope so we declare all locals, too. 1383 // the caller's scope so we declare all locals, too.
1378 1384 // Also for block scoped let/const bindings the variable can be
1379 Scope* declaration_scope = mode == LET ? top_scope_ 1385 // statically declared.
1380 : top_scope_->DeclarationScope();
1381 if (declaration_scope->is_function_scope() || 1386 if (declaration_scope->is_function_scope() ||
1382 declaration_scope->is_strict_mode_eval_scope() || 1387 declaration_scope->is_strict_mode_eval_scope() ||
1383 declaration_scope->is_block_scope()) { 1388 declaration_scope->is_block_scope()) {
1384 // Declare the variable in the function scope. 1389 // Declare the variable in the function scope.
1385 var = declaration_scope->LocalLookup(name); 1390 var = declaration_scope->LocalLookup(name);
1386 if (var == NULL) { 1391 if (var == NULL) {
1387 // Declare the name. 1392 // Declare the name.
1388 var = declaration_scope->DeclareLocal(name, mode); 1393 var = declaration_scope->DeclareLocal(name, mode);
1389 } else { 1394 } else {
1390 // The name was declared in this scope before; check for conflicting 1395 // The name was declared in this scope before; check for conflicting
1391 // re-declarations. We have a conflict if either of the declarations is 1396 // re-declarations. We have a conflict if either of the declarations is
1392 // not a var. There is similar code in runtime.cc in the Declare 1397 // not a var. There is similar code in runtime.cc in the Declare
1393 // functions. The function CheckNonConflictingScope checks for conflicting 1398 // functions. The function CheckNonConflictingScope checks for conflicting
1394 // var and let bindings from different scopes whereas this is a check for 1399 // var and let bindings from different scopes whereas this is a check for
1395 // conflicting declarations within the same scope. This check also covers 1400 // conflicting declarations within the same scope. This check also covers
1396 // 1401 //
1397 // function () { let x; { var x; } } 1402 // function () { let x; { var x; } }
1398 // 1403 //
1399 // because the var declaration is hoisted to the function scope where 'x' 1404 // because the var declaration is hoisted to the function scope where 'x'
1400 // is already bound. 1405 // is already bound.
1401 if ((mode != VAR) || (var->mode() != VAR)) { 1406 if ((mode != VAR) || (var->mode() != VAR)) {
1402 // We only have vars, consts and lets in declarations. 1407 // We only have vars, consts and lets in declarations.
1403 ASSERT(var->mode() == VAR || 1408 ASSERT(var->mode() == VAR ||
1404 var->mode() == CONST || 1409 var->mode() == CONST ||
1410 var->mode() == CONST_HARMONY ||
1405 var->mode() == LET); 1411 var->mode() == LET);
1406 if (harmony_scoping_) { 1412 if (harmony_scoping_) {
1407 // In harmony mode we treat re-declarations as early errors. See 1413 // In harmony mode we treat re-declarations as early errors. See
1408 // ES5 16 for a definition of early errors. 1414 // ES5 16 for a definition of early errors.
1409 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); 1415 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
1410 const char* elms[2] = { "Variable", *c_string }; 1416 const char* elms[2] = { "Variable", *c_string };
1411 Vector<const char*> args(elms, 2); 1417 Vector<const char*> args(elms, 2);
1412 ReportMessage("redeclaration", args); 1418 ReportMessage("redeclaration", args);
1413 *ok = false; 1419 *ok = false;
1414 return NULL; 1420 return NULL;
1415 } 1421 }
1416 const char* type = (var->mode() == VAR) ? "var" : 1422 const char* type = (var->mode() == VAR)
1417 (var->mode() == CONST) ? "const" : "let"; 1423 ? "var" : var->is_const_mode() ? "const" : "let";
1418 Handle<String> type_string = 1424 Handle<String> type_string =
1419 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); 1425 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED);
1420 Expression* expression = 1426 Expression* expression =
1421 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), 1427 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
1422 type_string, name); 1428 type_string, name);
1423 declaration_scope->SetIllegalRedeclaration(expression); 1429 declaration_scope->SetIllegalRedeclaration(expression);
1424 } 1430 }
1425 } 1431 }
1426 } 1432 }
1427 1433
(...skipping 12 matching lines...) Expand all
1440 // same variable if it is declared several times. This is not a 1446 // same variable if it is declared several times. This is not a
1441 // semantic issue as long as we keep the source order, but it may be 1447 // semantic issue as long as we keep the source order, but it may be
1442 // a performance issue since it may lead to repeated 1448 // a performance issue since it may lead to repeated
1443 // Runtime::DeclareContextSlot() calls. 1449 // Runtime::DeclareContextSlot() calls.
1444 VariableProxy* proxy = declaration_scope->NewUnresolved( 1450 VariableProxy* proxy = declaration_scope->NewUnresolved(
1445 name, scanner().location().beg_pos); 1451 name, scanner().location().beg_pos);
1446 declaration_scope->AddDeclaration( 1452 declaration_scope->AddDeclaration(
1447 new(zone()) Declaration(proxy, mode, fun, top_scope_)); 1453 new(zone()) Declaration(proxy, mode, fun, top_scope_));
1448 1454
1449 // For global const variables we bind the proxy to a variable. 1455 // For global const variables we bind the proxy to a variable.
1450 if (mode == CONST && declaration_scope->is_global_scope()) { 1456 if ((mode == CONST || mode == CONST_HARMONY) &&
1457 declaration_scope->is_global_scope()) {
1451 ASSERT(resolve); // should be set by all callers 1458 ASSERT(resolve); // should be set by all callers
1452 Variable::Kind kind = Variable::NORMAL; 1459 Variable::Kind kind = Variable::NORMAL;
1453 var = new(zone()) Variable(declaration_scope, name, CONST, true, kind); 1460 var = new(zone()) Variable(declaration_scope, name, CONST, true, kind);
1454 } 1461 }
1455 1462
1456 // If requested and we have a local variable, bind the proxy to the variable 1463 // If requested and we have a local variable, bind the proxy to the variable
1457 // at parse-time. This is used for functions (and consts) declared inside 1464 // at parse-time. This is used for functions (and consts) declared inside
1458 // statements: the corresponding function (or const) variable must be in the 1465 // statements: the corresponding function (or const) variable must be in the
1459 // function scope and not a statement-local scope, e.g. as provided with a 1466 // function scope and not a statement-local scope, e.g. as provided with a
1460 // 'with' statement: 1467 // 'with' statement:
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1638 return result; 1645 return result;
1639 } 1646 }
1640 1647
1641 1648
1642 bool Parser::IsEvalOrArguments(Handle<String> string) { 1649 bool Parser::IsEvalOrArguments(Handle<String> string) {
1643 return string.is_identical_to(isolate()->factory()->eval_symbol()) || 1650 return string.is_identical_to(isolate()->factory()->eval_symbol()) ||
1644 string.is_identical_to(isolate()->factory()->arguments_symbol()); 1651 string.is_identical_to(isolate()->factory()->arguments_symbol());
1645 } 1652 }
1646 1653
1647 1654
1655 Block* Parser::ParseHarmonyConstDeclaration(bool* ok) {
1656 // ES6 Draft Rev3
1657 //
1658 // ConstDeclaration ::
1659 // const ConstBinding (',' ConstBinding)* ';'
1660 // ConstBinding ::
1661 // Identifier '=' AssignmentExpression
1662 //
1663 // TODO(ES6):
1664 // ConstBinding ::
1665 // BindingPattern '=' AssignmentExpression
1666
1667 Consume(Token::CONST);
1668
1669 // A block is used to collect the initialization assignments and it
1670 // is marked as an initializer block to prevent the rewriter from
1671 // adding a '.result' assignment to such a block.
1672 //
1673 // Create new block with one expected declaration.
1674 Block* block = new(zone()) Block(isolate(), NULL, 1, true);
1675 Handle<String> name;
1676 do {
1677 if (fni_ != NULL) fni_->Enter();
1678
1679 // Parse variable name.
1680 name = ParseIdentifier(CHECK_OK);
1681 if (fni_ != NULL) fni_->PushVariableName(name);
1682
1683 // Strict mode variables may not be named eval or arguments
1684 if (IsEvalOrArguments(name)) {
1685 ReportMessage("strict_var_name", Vector<const char*>::empty());
1686 *ok = false;
1687 return NULL;
1688 }
1689
1690 // Declare the variable. The proxy can always be pre-resolved to the
1691 // declared variable, because it resides in the same scope as the
1692 // declaration.
1693 VariableProxy* proxy = Declare(name, CONST_HARMONY, NULL, true, CHECK_OK);
1694 if (top_scope_->num_var_or_const() > kMaxNumFunctionLocals) {
fschneider 2011/10/21 09:19:40 This function contains a lot of duplicated code. C
Steven 2011/10/24 09:37:55 Done. Was actually easier than I thought to add it
1695 ReportMessageAt(scanner().location(), "too_many_variables",
1696 Vector<const char*>::empty());
1697 *ok = false;
1698 return NULL;
1699 }
1700
1701 // Parse initialiser.
1702 Expression* value = NULL;
1703 Expect(Token::ASSIGN, CHECK_OK);
1704 int position = scanner().location().beg_pos;
1705 value = ParseAssignmentExpression(false, CHECK_OK);
1706
1707 // Don't infer if it is "a = function(){...}();"-like expression.
1708 if (fni_ != NULL && value->AsCall() == NULL && value->AsCallNew() == NULL) {
1709 fni_->Infer();
1710 }
1711
1712 // Global variable declarations must be compiled in a specific
1713 // way. When the script containing the global variable declaration
1714 // is entered, the global variable must be declared, so that if it
1715 // doesn't exist (not even in a prototype of the global object) it
1716 // gets created with an initial undefined value. This is handled
1717 // by the declarations part of the function representing the
1718 // top-level global code; see Runtime::DeclareGlobals. If
1719 // it already exists (in the object or in a prototype), it is
1720 // *not* touched until the variable declaration statement is
1721 // executed.
1722 //
1723 // Executing the variable declaration statement will always
1724 // guarantee to give the global object a "local" variable; a
1725 // variable defined in the global object and not in any
1726 // prototype. This way, global variable declarations can shadow
1727 // properties in the prototype chain, but only after the variable
1728 // declaration statement has been executed. This is important in
1729 // browsers where the global object (window) has lots of
1730 // properties defined in prototype objects.
1731 if (top_scope_->is_global_scope()) {
1732 // Compute the arguments for the runtime call.
1733 ZoneList<Expression*>* arguments = new(zone()) ZoneList<Expression*>(3);
1734 // We have at least 1 parameter.
1735 arguments->Add(NewLiteral(name));
1736 arguments->Add(value);
1737
1738 // Construct the call to Runtime_InitializeConstGlobal
1739 // and add it to the initialization statement block.
1740 CallRuntime* initialize =
1741 new(zone()) CallRuntime(
1742 isolate(),
1743 isolate()->factory()->InitializeConstGlobal_symbol(),
1744 Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
1745 arguments);
1746
1747 block->AddStatement(new(zone()) ExpressionStatement(initialize));
1748 } else {
1749 // Add an assignment node for the initializations to the initialization
1750 // statement block.
1751 Assignment* assignment = new(zone()) Assignment(
1752 isolate(), Token::INIT_CONST_HARMONY, proxy, value, position);
1753 block->AddStatement(new(zone()) ExpressionStatement(assignment));
1754 }
1755 if (fni_ != NULL) fni_->Leave();
1756 } while (Check(Token::COMMA));
1757
1758 ExpectSemicolon(CHECK_OK);
1759 return block;
1760 }
1761
1762
1648 // If the variable declaration declares exactly one non-const 1763 // If the variable declaration declares exactly one non-const
1649 // variable, then *var is set to that variable. In all other cases, 1764 // variable, then *var is set to that variable. In all other cases,
1650 // *var is untouched; in particular, it is the caller's responsibility 1765 // *var is untouched; in particular, it is the caller's responsibility
1651 // to initialize it properly. This mechanism is used for the parsing 1766 // to initialize it properly. This mechanism is used for the parsing
1652 // of 'for-in' loops. 1767 // of 'for-in' loops.
1653 Block* Parser::ParseVariableDeclarations( 1768 Block* Parser::ParseVariableDeclarations(
1654 VariableDeclarationContext var_context, 1769 VariableDeclarationContext var_context,
1655 VariableDeclarationProperties* decl_props, 1770 VariableDeclarationProperties* decl_props,
1656 Handle<String>* out, 1771 Handle<String>* out,
1657 bool* ok) { 1772 bool* ok) {
1658 // VariableDeclarations :: 1773 // VariableDeclarations ::
1659 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 1774 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
1660 1775
1661 VariableMode mode = VAR; 1776 VariableMode mode = VAR;
1662 // True if the binding needs initialization. 'let' and 'const' declared 1777 // True if the binding needs initialization. 'let' and 'const' declared
1663 // bindings are created uninitialized by their declaration nodes and 1778 // bindings are created uninitialized by their declaration nodes and
1664 // need initialization. 'var' declared bindings are always initialized 1779 // need initialization. 'var' declared bindings are always initialized
1665 // immediately by their declaration nodes. 1780 // immediately by their declaration nodes.
1666 bool needs_init = false; 1781 bool needs_init = false;
1667 bool is_const = false; 1782 bool is_const = false;
1668 Token::Value init_op = Token::INIT_VAR; 1783 Token::Value init_op = Token::INIT_VAR;
1669 if (peek() == Token::VAR) { 1784 if (peek() == Token::VAR) {
1670 Consume(Token::VAR); 1785 Consume(Token::VAR);
1671 } else if (peek() == Token::CONST) { 1786 } else if (peek() == Token::CONST) {
1672 Consume(Token::CONST); 1787 Consume(Token::CONST);
1788 if (harmony_scoping_) {
1789 ASSERT(var_context == kForStatement ||
1790 var_context == kStatement);
1791 // In harmony mode 'const' declarations are only allowed in source
1792 // element positions and that is handled by ParseHarmonyConstDeclaration.
1793 ReportMessage("unprotected_const", Vector<const char*>::empty());
1794 *ok = false;
1795 return NULL;
1796 }
1673 if (top_scope_->is_strict_mode()) { 1797 if (top_scope_->is_strict_mode()) {
1674 ReportMessage("strict_const", Vector<const char*>::empty()); 1798 ReportMessage("strict_const", Vector<const char*>::empty());
1675 *ok = false; 1799 *ok = false;
1676 return NULL; 1800 return NULL;
1677 } 1801 }
1678 mode = CONST; 1802 mode = CONST;
1679 is_const = true; 1803 is_const = true;
1680 needs_init = true; 1804 needs_init = true;
1681 init_op = Token::INIT_CONST; 1805 init_op = Token::INIT_CONST;
1682 } else if (peek() == Token::LET) { 1806 } else if (peek() == Token::LET) {
1683 Consume(Token::LET); 1807 Consume(Token::LET);
1684 if (var_context != kSourceElement && 1808 if (var_context != kSourceElement &&
1685 var_context != kForStatement) { 1809 var_context != kForStatement) {
1810 // Let declarations are only allowed in source element positions.
1686 ASSERT(var_context == kStatement); 1811 ASSERT(var_context == kStatement);
1687 ReportMessage("unprotected_let", Vector<const char*>::empty()); 1812 ReportMessage("unprotected_let", Vector<const char*>::empty());
1688 *ok = false; 1813 *ok = false;
1689 return NULL; 1814 return NULL;
1690 } 1815 }
1691 mode = LET; 1816 mode = LET;
1692 needs_init = true; 1817 needs_init = true;
1693 init_op = Token::INIT_LET; 1818 init_op = Token::INIT_LET;
1694 } else { 1819 } else {
1695 UNREACHABLE(); // by current callers 1820 UNREACHABLE(); // by current callers
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1733 // assignment for variables and constants because the value must be assigned 1858 // assignment for variables and constants because the value must be assigned
1734 // when the variable is encountered in the source. But the variable/constant 1859 // when the variable is encountered in the source. But the variable/constant
1735 // is declared (and set to 'undefined') upon entering the function within 1860 // is declared (and set to 'undefined') upon entering the function within
1736 // which the variable or constant is declared. Only function variables have 1861 // which the variable or constant is declared. Only function variables have
1737 // an initial value in the declaration (because they are initialized upon 1862 // an initial value in the declaration (because they are initialized upon
1738 // entering the function). 1863 // entering the function).
1739 // 1864 //
1740 // If we have a const declaration, in an inner scope, the proxy is always 1865 // If we have a const declaration, in an inner scope, the proxy is always
1741 // bound to the declared variable (independent of possibly surrounding with 1866 // bound to the declared variable (independent of possibly surrounding with
1742 // statements). 1867 // statements).
1743 Declare(name, mode, NULL, is_const /* always bound for CONST! */, 1868 // For let/const declarations in harmony mode, we can also immediately
1744 CHECK_OK); 1869 // pre-resolve the proxy because it resides in the same scope as the
1870 // declaration.
1871 Declare(name, mode, NULL, mode != VAR, CHECK_OK);
1745 nvars++; 1872 nvars++;
1746 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { 1873 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
1747 ReportMessageAt(scanner().location(), "too_many_variables", 1874 ReportMessageAt(scanner().location(), "too_many_variables",
1748 Vector<const char*>::empty()); 1875 Vector<const char*>::empty());
1749 *ok = false; 1876 *ok = false;
1750 return NULL; 1877 return NULL;
1751 } 1878 }
1752 1879
1753 // Parse initialization expression if present and/or needed. A 1880 // Parse initialization expression if present and/or needed. A
1754 // declaration of the form: 1881 // declaration of the form:
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1876 // Add an assignment node to the initialization statement block if we still 2003 // Add an assignment node to the initialization statement block if we still
1877 // have a pending initialization value. We must distinguish between 2004 // have a pending initialization value. We must distinguish between
1878 // different kinds of declarations: 'var' initializations are simply 2005 // different kinds of declarations: 'var' initializations are simply
1879 // assignments (with all the consequences if they are inside a 'with' 2006 // assignments (with all the consequences if they are inside a 'with'
1880 // statement - they may change a 'with' object property). Constant 2007 // statement - they may change a 'with' object property). Constant
1881 // initializations always assign to the declared constant which is 2008 // initializations always assign to the declared constant which is
1882 // always at the function scope level. This is only relevant for 2009 // always at the function scope level. This is only relevant for
1883 // dynamically looked-up variables and constants (the start context 2010 // dynamically looked-up variables and constants (the start context
1884 // for constant lookups is always the function context, while it is 2011 // for constant lookups is always the function context, while it is
1885 // the top context for var declared variables). Sigh... 2012 // the top context for var declared variables). Sigh...
1886 // For 'let' declared variables the initialization is in the same scope 2013 // For 'let' and 'const' declared variables in harmony mode the
1887 // as the declaration. Thus dynamic lookups are unnecessary even if the 2014 // initialization is in the same scope as the declaration. Thus dynamic
1888 // block scope is inside a with. 2015 // lookups are unnecessary even if the block scope is inside a with.
1889 if (value != NULL) { 2016 if (value != NULL) {
1890 VariableProxy* proxy = initialization_scope->NewUnresolved(name); 2017 VariableProxy* proxy = initialization_scope->NewUnresolved(name);
1891 Assignment* assignment = 2018 Assignment* assignment =
1892 new(zone()) Assignment(isolate(), init_op, proxy, value, position); 2019 new(zone()) Assignment(isolate(), init_op, proxy, value, position);
1893 block->AddStatement(new(zone()) ExpressionStatement(assignment)); 2020 block->AddStatement(new(zone()) ExpressionStatement(assignment));
1894 } 2021 }
1895 2022
1896 if (fni_ != NULL) fni_->Leave(); 2023 if (fni_ != NULL) fni_->Leave();
1897 } while (peek() == Token::COMMA); 2024 } while (peek() == Token::COMMA);
1898 2025
(...skipping 1971 matching lines...) Expand 10 before | Expand all | Expand 10 after
3870 3997
3871 Expect(Token::LBRACE, CHECK_OK); 3998 Expect(Token::LBRACE, CHECK_OK);
3872 3999
3873 // If we have a named function expression, we add a local variable 4000 // If we have a named function expression, we add a local variable
3874 // declaration to the body of the function with the name of the 4001 // declaration to the body of the function with the name of the
3875 // function and let it refer to the function itself (closure). 4002 // function and let it refer to the function itself (closure).
3876 // NOTE: We create a proxy and resolve it here so that in the 4003 // NOTE: We create a proxy and resolve it here so that in the
3877 // future we can change the AST to only refer to VariableProxies 4004 // future we can change the AST to only refer to VariableProxies
3878 // instead of Variables and Proxis as is the case now. 4005 // instead of Variables and Proxis as is the case now.
3879 if (type == FunctionLiteral::NAMED_EXPRESSION) { 4006 if (type == FunctionLiteral::NAMED_EXPRESSION) {
3880 Variable* fvar = top_scope_->DeclareFunctionVar(function_name); 4007 VariableMode fvar_mode;
4008 Token::Value fvar_init_op;
4009 if (harmony_scoping_) {
4010 fvar_mode = CONST_HARMONY;
4011 fvar_init_op = Token::INIT_CONST_HARMONY;
4012 } else {
4013 fvar_mode = CONST;
4014 fvar_init_op = Token::INIT_CONST;
4015 }
4016 Variable* fvar = top_scope_->DeclareFunctionVar(function_name, fvar_mode);
3881 VariableProxy* fproxy = top_scope_->NewUnresolved(function_name); 4017 VariableProxy* fproxy = top_scope_->NewUnresolved(function_name);
3882 fproxy->BindTo(fvar); 4018 fproxy->BindTo(fvar);
3883 body->Add(new(zone()) ExpressionStatement( 4019 body->Add(new(zone()) ExpressionStatement(
3884 new(zone()) Assignment(isolate(), 4020 new(zone()) Assignment(isolate(),
3885 Token::INIT_CONST, 4021 fvar_init_op,
3886 fproxy, 4022 fproxy,
3887 new(zone()) ThisFunction(isolate()), 4023 new(zone()) ThisFunction(isolate()),
3888 RelocInfo::kNoPosition))); 4024 RelocInfo::kNoPosition)));
3889 } 4025 }
3890 4026
3891 // Determine if the function will be lazily compiled. The mode can only 4027 // Determine if the function will be lazily compiled. The mode can only
3892 // be PARSE_LAZILY if the --lazy flag is true. We will not lazily 4028 // be PARSE_LAZILY if the --lazy flag is true. We will not lazily
3893 // compile if we do not have preparser data for the function. 4029 // compile if we do not have preparser data for the function.
3894 bool is_lazily_compiled = (mode() == PARSE_LAZILY && 4030 bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
3895 top_scope_->outer_scope()->is_global_scope() && 4031 top_scope_->outer_scope()->is_global_scope() &&
(...skipping 1432 matching lines...) Expand 10 before | Expand all | Expand 10 after
5328 result = parser.ParseProgram(source, 5464 result = parser.ParseProgram(source,
5329 info->is_global(), 5465 info->is_global(),
5330 info->StrictMode()); 5466 info->StrictMode());
5331 } 5467 }
5332 } 5468 }
5333 info->SetFunction(result); 5469 info->SetFunction(result);
5334 return (result != NULL); 5470 return (result != NULL);
5335 } 5471 }
5336 5472
5337 } } // namespace v8::internal 5473 } } // 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