OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |