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

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: Comments, function variable mode, preparser. 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.cc » ('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 1120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1131 Statement* Parser::ParseSourceElement(ZoneStringList* labels, 1131 Statement* Parser::ParseSourceElement(ZoneStringList* labels,
1132 bool* ok) { 1132 bool* ok) {
1133 // (Ecma 262 5th Edition, clause 14): 1133 // (Ecma 262 5th Edition, clause 14):
1134 // SourceElement: 1134 // SourceElement:
1135 // Statement 1135 // Statement
1136 // FunctionDeclaration 1136 // FunctionDeclaration
1137 // 1137 //
1138 // In harmony mode we allow additionally the following productions 1138 // In harmony mode we allow additionally the following productions
1139 // SourceElement: 1139 // SourceElement:
1140 // LetDeclaration 1140 // LetDeclaration
1141 // ConstDeclaration
1141 1142
1142 if (peek() == Token::FUNCTION) { 1143 if (peek() == Token::FUNCTION) {
1143 return ParseFunctionDeclaration(ok); 1144 return ParseFunctionDeclaration(ok);
1144 } else if (peek() == Token::LET) { 1145 } else if (peek() == Token::LET || peek() == Token::CONST) {
1145 return ParseVariableStatement(kSourceElement, ok); 1146 return ParseVariableStatement(kSourceElement, ok);
1146 } else {
1147 return ParseStatement(labels, ok);
1148 } 1147 }
1148 return ParseStatement(labels, ok);
1149 } 1149 }
1150 1150
1151 1151
1152 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, 1152 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
1153 int end_token, 1153 int end_token,
1154 bool* ok) { 1154 bool* ok) {
1155 // SourceElements :: 1155 // SourceElements ::
1156 // (SourceElement)* <end_token> 1156 // (SourceElement)* <end_token>
1157 1157
1158 // Allocate a target stack to use for this set of source 1158 // Allocate a target stack to use for this set of source
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
1356 1356
1357 VariableProxy* Parser::Declare(Handle<String> name, 1357 VariableProxy* Parser::Declare(Handle<String> name,
1358 VariableMode mode, 1358 VariableMode mode,
1359 FunctionLiteral* fun, 1359 FunctionLiteral* fun,
1360 bool resolve, 1360 bool resolve,
1361 bool* ok) { 1361 bool* ok) {
1362 Variable* var = NULL; 1362 Variable* var = NULL;
1363 // If we are inside a function, a declaration of a var/const variable is a 1363 // If we are inside a function, a declaration of a var/const variable is a
1364 // truly local variable, and the scope of the variable is always the function 1364 // truly local variable, and the scope of the variable is always the function
1365 // scope. 1365 // scope.
1366 // Let/const variables in harmony mode are always added to the immediately
1367 // enclosing scope.
1368 Scope* declaration_scope = mode == LET || mode == CONST_HARMONY
1369 ? top_scope_ : top_scope_->DeclarationScope();
1366 1370
1367 // If a function scope exists, then we can statically declare this 1371 // If a function scope exists, then we can statically declare this
1368 // variable and also set its mode. In any case, a Declaration node 1372 // variable and also set its mode. In any case, a Declaration node
1369 // will be added to the scope so that the declaration can be added 1373 // will be added to the scope so that the declaration can be added
1370 // to the corresponding activation frame at runtime if necessary. 1374 // to the corresponding activation frame at runtime if necessary.
1371 // For instance declarations inside an eval scope need to be added 1375 // For instance declarations inside an eval scope need to be added
1372 // to the calling function context. 1376 // to the calling function context.
1373 // Similarly, strict mode eval scope does not leak variable declarations to 1377 // Similarly, strict mode eval scope does not leak variable declarations to
1374 // the caller's scope so we declare all locals, too. 1378 // the caller's scope so we declare all locals, too.
1375 1379 // Also for block scoped let/const bindings the variable can be
1376 Scope* declaration_scope = mode == LET ? top_scope_ 1380 // statically declared.
1377 : top_scope_->DeclarationScope();
1378 if (declaration_scope->is_function_scope() || 1381 if (declaration_scope->is_function_scope() ||
1379 declaration_scope->is_strict_mode_eval_scope() || 1382 declaration_scope->is_strict_mode_eval_scope() ||
1380 declaration_scope->is_block_scope()) { 1383 declaration_scope->is_block_scope()) {
1381 // Declare the variable in the function scope. 1384 // Declare the variable in the function scope.
1382 var = declaration_scope->LocalLookup(name); 1385 var = declaration_scope->LocalLookup(name);
1383 if (var == NULL) { 1386 if (var == NULL) {
1384 // Declare the name. 1387 // Declare the name.
1385 var = declaration_scope->DeclareLocal(name, mode); 1388 var = declaration_scope->DeclareLocal(name, mode);
1386 } else { 1389 } else {
1387 // The name was declared in this scope before; check for conflicting 1390 // The name was declared in this scope before; check for conflicting
1388 // re-declarations. We have a conflict if either of the declarations is 1391 // re-declarations. We have a conflict if either of the declarations is
1389 // not a var. There is similar code in runtime.cc in the Declare 1392 // not a var. There is similar code in runtime.cc in the Declare
1390 // functions. The function CheckNonConflictingScope checks for conflicting 1393 // functions. The function CheckNonConflictingScope checks for conflicting
1391 // var and let bindings from different scopes whereas this is a check for 1394 // var and let bindings from different scopes whereas this is a check for
1392 // conflicting declarations within the same scope. This check also covers 1395 // conflicting declarations within the same scope. This check also covers
1393 // 1396 //
1394 // function () { let x; { var x; } } 1397 // function () { let x; { var x; } }
1395 // 1398 //
1396 // because the var declaration is hoisted to the function scope where 'x' 1399 // because the var declaration is hoisted to the function scope where 'x'
1397 // is already bound. 1400 // is already bound.
1398 if ((mode != VAR) || (var->mode() != VAR)) { 1401 if ((mode != VAR) || (var->mode() != VAR)) {
1399 // We only have vars, consts and lets in declarations. 1402 // We only have vars, consts and lets in declarations.
1400 ASSERT(var->mode() == VAR || 1403 ASSERT(var->mode() == VAR ||
1401 var->mode() == CONST || 1404 var->mode() == CONST ||
1405 var->mode() == CONST_HARMONY ||
1402 var->mode() == LET); 1406 var->mode() == LET);
1403 if (harmony_scoping_) { 1407 if (harmony_scoping_) {
1404 // In harmony mode we treat re-declarations as early errors. See 1408 // In harmony mode we treat re-declarations as early errors. See
1405 // ES5 16 for a definition of early errors. 1409 // ES5 16 for a definition of early errors.
1406 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); 1410 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
1407 const char* elms[2] = { "Variable", *c_string }; 1411 const char* elms[2] = { "Variable", *c_string };
1408 Vector<const char*> args(elms, 2); 1412 Vector<const char*> args(elms, 2);
1409 ReportMessage("redeclaration", args); 1413 ReportMessage("redeclaration", args);
1410 *ok = false; 1414 *ok = false;
1411 return NULL; 1415 return NULL;
1412 } 1416 }
1413 const char* type = (var->mode() == VAR) ? "var" : 1417 const char* type = (var->mode() == VAR)
1414 (var->mode() == CONST) ? "const" : "let"; 1418 ? "var" : var->is_const_mode() ? "const" : "let";
1415 Handle<String> type_string = 1419 Handle<String> type_string =
1416 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); 1420 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED);
1417 Expression* expression = 1421 Expression* expression =
1418 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), 1422 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
1419 type_string, name); 1423 type_string, name);
1420 declaration_scope->SetIllegalRedeclaration(expression); 1424 declaration_scope->SetIllegalRedeclaration(expression);
1421 } 1425 }
1422 } 1426 }
1423 } 1427 }
1424 1428
(...skipping 12 matching lines...) Expand all
1437 // same variable if it is declared several times. This is not a 1441 // same variable if it is declared several times. This is not a
1438 // semantic issue as long as we keep the source order, but it may be 1442 // semantic issue as long as we keep the source order, but it may be
1439 // a performance issue since it may lead to repeated 1443 // a performance issue since it may lead to repeated
1440 // Runtime::DeclareContextSlot() calls. 1444 // Runtime::DeclareContextSlot() calls.
1441 VariableProxy* proxy = declaration_scope->NewUnresolved( 1445 VariableProxy* proxy = declaration_scope->NewUnresolved(
1442 name, scanner().location().beg_pos); 1446 name, scanner().location().beg_pos);
1443 declaration_scope->AddDeclaration( 1447 declaration_scope->AddDeclaration(
1444 new(zone()) Declaration(proxy, mode, fun, top_scope_)); 1448 new(zone()) Declaration(proxy, mode, fun, top_scope_));
1445 1449
1446 // For global const variables we bind the proxy to a variable. 1450 // For global const variables we bind the proxy to a variable.
1447 if (mode == CONST && declaration_scope->is_global_scope()) { 1451 if ((mode == CONST || mode == CONST_HARMONY) &&
1452 declaration_scope->is_global_scope()) {
1448 ASSERT(resolve); // should be set by all callers 1453 ASSERT(resolve); // should be set by all callers
1449 Variable::Kind kind = Variable::NORMAL; 1454 Variable::Kind kind = Variable::NORMAL;
1450 var = new(zone()) Variable(declaration_scope, name, CONST, true, kind); 1455 var = new(zone()) Variable(declaration_scope, name, CONST, true, kind);
1451 } 1456 }
1452 1457
1453 // If requested and we have a local variable, bind the proxy to the variable 1458 // If requested and we have a local variable, bind the proxy to the variable
1454 // at parse-time. This is used for functions (and consts) declared inside 1459 // at parse-time. This is used for functions (and consts) declared inside
1455 // statements: the corresponding function (or const) variable must be in the 1460 // statements: the corresponding function (or const) variable must be in the
1456 // function scope and not a statement-local scope, e.g. as provided with a 1461 // function scope and not a statement-local scope, e.g. as provided with a
1457 // 'with' statement: 1462 // 'with' statement:
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
1647 // variable, then *var is set to that variable. In all other cases, 1652 // variable, then *var is set to that variable. In all other cases,
1648 // *var is untouched; in particular, it is the caller's responsibility 1653 // *var is untouched; in particular, it is the caller's responsibility
1649 // to initialize it properly. This mechanism is used for the parsing 1654 // to initialize it properly. This mechanism is used for the parsing
1650 // of 'for-in' loops. 1655 // of 'for-in' loops.
1651 Block* Parser::ParseVariableDeclarations( 1656 Block* Parser::ParseVariableDeclarations(
1652 VariableDeclarationContext var_context, 1657 VariableDeclarationContext var_context,
1653 VariableDeclarationProperties* decl_props, 1658 VariableDeclarationProperties* decl_props,
1654 Handle<String>* out, 1659 Handle<String>* out,
1655 bool* ok) { 1660 bool* ok) {
1656 // VariableDeclarations :: 1661 // VariableDeclarations ::
1657 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 1662 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
1658 1663 //
1664 // The ES6 Draft Rev3 specifies the following grammar for const declarations
1665 //
1666 // ConstDeclaration ::
1667 // const ConstBinding (',' ConstBinding)* ';'
1668 // ConstBinding ::
1669 // Identifier '=' AssignmentExpression
1670 //
1671 // TODO(ES6):
1672 // ConstBinding ::
1673 // BindingPattern '=' AssignmentExpression
1659 VariableMode mode = VAR; 1674 VariableMode mode = VAR;
1660 // True if the binding needs initialization. 'let' and 'const' declared 1675 // True if the binding needs initialization. 'let' and 'const' declared
1661 // bindings are created uninitialized by their declaration nodes and 1676 // bindings are created uninitialized by their declaration nodes and
1662 // need initialization. 'var' declared bindings are always initialized 1677 // need initialization. 'var' declared bindings are always initialized
1663 // immediately by their declaration nodes. 1678 // immediately by their declaration nodes.
1664 bool needs_init = false; 1679 bool needs_init = false;
1665 bool is_const = false; 1680 bool is_const = false;
1666 Token::Value init_op = Token::INIT_VAR; 1681 Token::Value init_op = Token::INIT_VAR;
1667 if (peek() == Token::VAR) { 1682 if (peek() == Token::VAR) {
1668 Consume(Token::VAR); 1683 Consume(Token::VAR);
1669 } else if (peek() == Token::CONST) { 1684 } else if (peek() == Token::CONST) {
1670 Consume(Token::CONST); 1685 Consume(Token::CONST);
1671 if (top_scope_->is_strict_mode()) { 1686 if (harmony_scoping_) {
1687 if (var_context != kSourceElement &&
1688 var_context != kForStatement) {
1689 // In harmony mode 'const' declarations are only allowed in source
1690 // element positions.
1691 ReportMessage("unprotected_const", Vector<const char*>::empty());
1692 *ok = false;
1693 return NULL;
1694 }
1695 mode = CONST_HARMONY;
1696 init_op = Token::INIT_CONST_HARMONY;
1697 } else if (top_scope_->is_strict_mode()) {
1672 ReportMessage("strict_const", Vector<const char*>::empty()); 1698 ReportMessage("strict_const", Vector<const char*>::empty());
1673 *ok = false; 1699 *ok = false;
1674 return NULL; 1700 return NULL;
1701 } else {
1702 mode = CONST;
1703 init_op = Token::INIT_CONST;
1675 } 1704 }
1676 mode = CONST;
1677 is_const = true; 1705 is_const = true;
1678 needs_init = true; 1706 needs_init = true;
1679 init_op = Token::INIT_CONST;
1680 } else if (peek() == Token::LET) { 1707 } else if (peek() == Token::LET) {
1681 Consume(Token::LET); 1708 Consume(Token::LET);
1682 if (var_context != kSourceElement && 1709 if (var_context != kSourceElement &&
1683 var_context != kForStatement) { 1710 var_context != kForStatement) {
1711 // Let declarations are only allowed in source element positions.
1684 ASSERT(var_context == kStatement); 1712 ASSERT(var_context == kStatement);
1685 ReportMessage("unprotected_let", Vector<const char*>::empty()); 1713 ReportMessage("unprotected_let", Vector<const char*>::empty());
1686 *ok = false; 1714 *ok = false;
1687 return NULL; 1715 return NULL;
1688 } 1716 }
1689 mode = LET; 1717 mode = LET;
1690 needs_init = true; 1718 needs_init = true;
1691 init_op = Token::INIT_LET; 1719 init_op = Token::INIT_LET;
1692 } else { 1720 } else {
1693 UNREACHABLE(); // by current callers 1721 UNREACHABLE(); // by current callers
1694 } 1722 }
1695 1723
1696 Scope* declaration_scope = (mode == LET) 1724 Scope* declaration_scope = (mode == LET || mode == CONST_HARMONY)
1697 ? top_scope_ : top_scope_->DeclarationScope(); 1725 ? top_scope_ : top_scope_->DeclarationScope();
1698 // The scope of a var/const declared variable anywhere inside a function 1726 // The scope of a var/const declared variable anywhere inside a function
1699 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can 1727 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
1700 // transform a source-level var/const declaration into a (Function) 1728 // transform a source-level var/const declaration into a (Function)
1701 // Scope declaration, and rewrite the source-level initialization into an 1729 // Scope declaration, and rewrite the source-level initialization into an
1702 // assignment statement. We use a block to collect multiple assignments. 1730 // assignment statement. We use a block to collect multiple assignments.
1703 // 1731 //
1704 // We mark the block as initializer block because we don't want the 1732 // We mark the block as initializer block because we don't want the
1705 // rewriter to add a '.result' assignment to such a block (to get compliant 1733 // rewriter to add a '.result' assignment to such a block (to get compliant
1706 // behavior for code such as print(eval('var x = 7')), and for cosmetic 1734 // behavior for code such as print(eval('var x = 7')), and for cosmetic
(...skipping 24 matching lines...) Expand all
1731 // assignment for variables and constants because the value must be assigned 1759 // assignment for variables and constants because the value must be assigned
1732 // when the variable is encountered in the source. But the variable/constant 1760 // when the variable is encountered in the source. But the variable/constant
1733 // is declared (and set to 'undefined') upon entering the function within 1761 // is declared (and set to 'undefined') upon entering the function within
1734 // which the variable or constant is declared. Only function variables have 1762 // which the variable or constant is declared. Only function variables have
1735 // an initial value in the declaration (because they are initialized upon 1763 // an initial value in the declaration (because they are initialized upon
1736 // entering the function). 1764 // entering the function).
1737 // 1765 //
1738 // If we have a const declaration, in an inner scope, the proxy is always 1766 // If we have a const declaration, in an inner scope, the proxy is always
1739 // bound to the declared variable (independent of possibly surrounding with 1767 // bound to the declared variable (independent of possibly surrounding with
1740 // statements). 1768 // statements).
1741 Declare(name, mode, NULL, is_const /* always bound for CONST! */, 1769 // For let/const declarations in harmony mode, we can also immediately
1742 CHECK_OK); 1770 // pre-resolve the proxy because it resides in the same scope as the
1771 // declaration.
1772 Declare(name, mode, NULL, mode != VAR, CHECK_OK);
1743 nvars++; 1773 nvars++;
1744 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { 1774 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
1745 ReportMessageAt(scanner().location(), "too_many_variables", 1775 ReportMessageAt(scanner().location(), "too_many_variables",
1746 Vector<const char*>::empty()); 1776 Vector<const char*>::empty());
1747 *ok = false; 1777 *ok = false;
1748 return NULL; 1778 return NULL;
1749 } 1779 }
1750 1780
1751 // Parse initialization expression if present and/or needed. A 1781 // Parse initialization expression if present and/or needed. A
1752 // declaration of the form: 1782 // declaration of the form:
(...skipping 18 matching lines...) Expand all
1771 // 1801 //
1772 // const c; c = x; 1802 // const c; c = x;
1773 // 1803 //
1774 // The "variable" c initialized to x is the same as the declared 1804 // The "variable" c initialized to x is the same as the declared
1775 // one - there is no re-lookup (see the last parameter of the 1805 // one - there is no re-lookup (see the last parameter of the
1776 // Declare() call above). 1806 // Declare() call above).
1777 1807
1778 Scope* initialization_scope = is_const ? declaration_scope : top_scope_; 1808 Scope* initialization_scope = is_const ? declaration_scope : top_scope_;
1779 Expression* value = NULL; 1809 Expression* value = NULL;
1780 int position = -1; 1810 int position = -1;
1781 if (peek() == Token::ASSIGN) { 1811 // Harmony consts have non-optional initializers.
1812 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) {
1782 Expect(Token::ASSIGN, CHECK_OK); 1813 Expect(Token::ASSIGN, CHECK_OK);
1783 position = scanner().location().beg_pos; 1814 position = scanner().location().beg_pos;
1784 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 1815 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
1785 // Don't infer if it is "a = function(){...}();"-like expression. 1816 // Don't infer if it is "a = function(){...}();"-like expression.
1786 if (fni_ != NULL && 1817 if (fni_ != NULL &&
1787 value->AsCall() == NULL && 1818 value->AsCall() == NULL &&
1788 value->AsCallNew() == NULL) { 1819 value->AsCallNew() == NULL) {
1789 fni_->Infer(); 1820 fni_->Infer();
1790 } else { 1821 } else {
1791 fni_->RemoveLastFunction(); 1822 fni_->RemoveLastFunction();
(...skipping 18 matching lines...) Expand all
1810 // executed. 1841 // executed.
1811 // 1842 //
1812 // Executing the variable declaration statement will always 1843 // Executing the variable declaration statement will always
1813 // guarantee to give the global object a "local" variable; a 1844 // guarantee to give the global object a "local" variable; a
1814 // variable defined in the global object and not in any 1845 // variable defined in the global object and not in any
1815 // prototype. This way, global variable declarations can shadow 1846 // prototype. This way, global variable declarations can shadow
1816 // properties in the prototype chain, but only after the variable 1847 // properties in the prototype chain, but only after the variable
1817 // declaration statement has been executed. This is important in 1848 // declaration statement has been executed. This is important in
1818 // browsers where the global object (window) has lots of 1849 // browsers where the global object (window) has lots of
1819 // properties defined in prototype objects. 1850 // properties defined in prototype objects.
1820
1821 if (initialization_scope->is_global_scope()) { 1851 if (initialization_scope->is_global_scope()) {
1822 // Compute the arguments for the runtime call. 1852 // Compute the arguments for the runtime call.
1823 ZoneList<Expression*>* arguments = new(zone()) ZoneList<Expression*>(3); 1853 ZoneList<Expression*>* arguments = new(zone()) ZoneList<Expression*>(3);
1824 // We have at least 1 parameter. 1854 // We have at least 1 parameter.
1825 arguments->Add(NewLiteral(name)); 1855 arguments->Add(NewLiteral(name));
1826 CallRuntime* initialize; 1856 CallRuntime* initialize;
1827 1857
1828 if (is_const) { 1858 if (is_const) {
1829 arguments->Add(value); 1859 arguments->Add(value);
1830 value = NULL; // zap the value to avoid the unnecessary assignment 1860 value = NULL; // zap the value to avoid the unnecessary assignment
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1874 // Add an assignment node to the initialization statement block if we still 1904 // Add an assignment node to the initialization statement block if we still
1875 // have a pending initialization value. We must distinguish between 1905 // have a pending initialization value. We must distinguish between
1876 // different kinds of declarations: 'var' initializations are simply 1906 // different kinds of declarations: 'var' initializations are simply
1877 // assignments (with all the consequences if they are inside a 'with' 1907 // assignments (with all the consequences if they are inside a 'with'
1878 // statement - they may change a 'with' object property). Constant 1908 // statement - they may change a 'with' object property). Constant
1879 // initializations always assign to the declared constant which is 1909 // initializations always assign to the declared constant which is
1880 // always at the function scope level. This is only relevant for 1910 // always at the function scope level. This is only relevant for
1881 // dynamically looked-up variables and constants (the start context 1911 // dynamically looked-up variables and constants (the start context
1882 // for constant lookups is always the function context, while it is 1912 // for constant lookups is always the function context, while it is
1883 // the top context for var declared variables). Sigh... 1913 // the top context for var declared variables). Sigh...
1884 // For 'let' declared variables the initialization is in the same scope 1914 // For 'let' and 'const' declared variables in harmony mode the
1885 // as the declaration. Thus dynamic lookups are unnecessary even if the 1915 // initialization is in the same scope as the declaration. Thus dynamic
1886 // block scope is inside a with. 1916 // lookups are unnecessary even if the block scope is inside a with.
1887 if (value != NULL) { 1917 if (value != NULL) {
1888 VariableProxy* proxy = initialization_scope->NewUnresolved(name); 1918 VariableProxy* proxy = initialization_scope->NewUnresolved(name);
1889 Assignment* assignment = 1919 Assignment* assignment =
1890 new(zone()) Assignment(isolate(), init_op, proxy, value, position); 1920 new(zone()) Assignment(isolate(), init_op, proxy, value, position);
1891 block->AddStatement(new(zone()) ExpressionStatement(assignment)); 1921 block->AddStatement(new(zone()) ExpressionStatement(assignment));
1892 } 1922 }
1893 1923
1894 if (fni_ != NULL) fni_->Leave(); 1924 if (fni_ != NULL) fni_->Leave();
1895 } while (peek() == Token::COMMA); 1925 } while (peek() == Token::COMMA);
1896 1926
(...skipping 2034 matching lines...) Expand 10 before | Expand all | Expand 10 after
3931 3961
3932 Expect(Token::LBRACE, CHECK_OK); 3962 Expect(Token::LBRACE, CHECK_OK);
3933 3963
3934 // If we have a named function expression, we add a local variable 3964 // If we have a named function expression, we add a local variable
3935 // declaration to the body of the function with the name of the 3965 // declaration to the body of the function with the name of the
3936 // function and let it refer to the function itself (closure). 3966 // function and let it refer to the function itself (closure).
3937 // NOTE: We create a proxy and resolve it here so that in the 3967 // NOTE: We create a proxy and resolve it here so that in the
3938 // future we can change the AST to only refer to VariableProxies 3968 // future we can change the AST to only refer to VariableProxies
3939 // instead of Variables and Proxis as is the case now. 3969 // instead of Variables and Proxis as is the case now.
3940 if (type == FunctionLiteral::NAMED_EXPRESSION) { 3970 if (type == FunctionLiteral::NAMED_EXPRESSION) {
3941 Variable* fvar = top_scope_->DeclareFunctionVar(function_name); 3971 VariableMode fvar_mode;
3972 Token::Value fvar_init_op;
3973 if (harmony_scoping_) {
3974 fvar_mode = CONST_HARMONY;
3975 fvar_init_op = Token::INIT_CONST_HARMONY;
3976 } else {
3977 fvar_mode = CONST;
3978 fvar_init_op = Token::INIT_CONST;
3979 }
3980 Variable* fvar = top_scope_->DeclareFunctionVar(function_name, fvar_mode);
3942 VariableProxy* fproxy = top_scope_->NewUnresolved(function_name); 3981 VariableProxy* fproxy = top_scope_->NewUnresolved(function_name);
3943 fproxy->BindTo(fvar); 3982 fproxy->BindTo(fvar);
3944 body->Add(new(zone()) ExpressionStatement( 3983 body->Add(new(zone()) ExpressionStatement(
3945 new(zone()) Assignment(isolate(), 3984 new(zone()) Assignment(isolate(),
3946 Token::INIT_CONST, 3985 fvar_init_op,
3947 fproxy, 3986 fproxy,
3948 new(zone()) ThisFunction(isolate()), 3987 new(zone()) ThisFunction(isolate()),
3949 RelocInfo::kNoPosition))); 3988 RelocInfo::kNoPosition)));
3950 } 3989 }
3951 3990
3952 // Determine if the function will be lazily compiled. The mode can only 3991 // Determine if the function will be lazily compiled. The mode can only
3953 // be PARSE_LAZILY if the --lazy flag is true. We will not lazily 3992 // be PARSE_LAZILY if the --lazy flag is true. We will not lazily
3954 // compile if we do not have preparser data for the function. 3993 // compile if we do not have preparser data for the function.
3955 bool is_lazily_compiled = (mode() == PARSE_LAZILY && 3994 bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
3956 top_scope_->outer_scope()->is_global_scope() && 3995 top_scope_->outer_scope()->is_global_scope() &&
(...skipping 1434 matching lines...) Expand 10 before | Expand all | Expand 10 after
5391 result = parser.ParseProgram(source, 5430 result = parser.ParseProgram(source,
5392 info->is_global(), 5431 info->is_global(),
5393 info->StrictMode()); 5432 info->StrictMode());
5394 } 5433 }
5395 } 5434 }
5396 info->SetFunction(result); 5435 info->SetFunction(result);
5397 return (result != NULL); 5436 return (result != NULL);
5398 } 5437 }
5399 5438
5400 } } // namespace v8::internal 5439 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698