| 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 |