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

Side by Side Diff: src/parser.cc

Issue 7671042: Temporal dead zone behaviour for let bindings. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Bailout in hydrogen and X64 and ARM code. Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
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 1591 matching lines...) Expand 10 before | Expand all | Expand 10 after
1602 // *var is untouched; in particular, it is the caller's responsibility 1602 // *var is untouched; in particular, it is the caller's responsibility
1603 // to initialize it properly. This mechanism is used for the parsing 1603 // to initialize it properly. This mechanism is used for the parsing
1604 // of 'for-in' loops. 1604 // of 'for-in' loops.
1605 Block* Parser::ParseVariableDeclarations(VariableDeclarationContext var_context, 1605 Block* Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
1606 Handle<String>* out, 1606 Handle<String>* out,
1607 bool* ok) { 1607 bool* ok) {
1608 // VariableDeclarations :: 1608 // VariableDeclarations ::
1609 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 1609 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
1610 1610
1611 Variable::Mode mode = Variable::VAR; 1611 Variable::Mode mode = Variable::VAR;
1612 // True if the binding needs initialization. 'let' and 'const' declared
1613 // bindings are created uninitialized by their declaration nodes and
1614 // need initialization. 'var' declared bindings are always initialized
1615 // immediately by their declaration nodes.
1616 bool needs_init = false;
1612 bool is_const = false; 1617 bool is_const = false;
1618 Token::Value init_op = Token::INIT_VAR;
1613 if (peek() == Token::VAR) { 1619 if (peek() == Token::VAR) {
1614 Consume(Token::VAR); 1620 Consume(Token::VAR);
1615 } else if (peek() == Token::CONST) { 1621 } else if (peek() == Token::CONST) {
1616 Consume(Token::CONST); 1622 Consume(Token::CONST);
1617 if (top_scope_->is_strict_mode()) { 1623 if (top_scope_->is_strict_mode()) {
1618 ReportMessage("strict_const", Vector<const char*>::empty()); 1624 ReportMessage("strict_const", Vector<const char*>::empty());
1619 *ok = false; 1625 *ok = false;
1620 return NULL; 1626 return NULL;
1621 } 1627 }
1622 mode = Variable::CONST; 1628 mode = Variable::CONST;
1623 is_const = true; 1629 is_const = true;
1630 needs_init = true;
1631 init_op = Token::INIT_CONST;
1624 } else if (peek() == Token::LET) { 1632 } else if (peek() == Token::LET) {
1625 Consume(Token::LET); 1633 Consume(Token::LET);
1626 if (var_context != kSourceElement && 1634 if (var_context != kSourceElement &&
1627 var_context != kForStatement) { 1635 var_context != kForStatement) {
1628 ASSERT(var_context == kStatement); 1636 ASSERT(var_context == kStatement);
1629 ReportMessage("unprotected_let", Vector<const char*>::empty()); 1637 ReportMessage("unprotected_let", Vector<const char*>::empty());
1630 *ok = false; 1638 *ok = false;
1631 return NULL; 1639 return NULL;
1632 } 1640 }
1633 mode = Variable::LET; 1641 mode = Variable::LET;
1642 needs_init = true;
1643 init_op = Token::INIT_LET;
1634 } else { 1644 } else {
1635 UNREACHABLE(); // by current callers 1645 UNREACHABLE(); // by current callers
1636 } 1646 }
1637 1647
1638 Scope* declaration_scope = mode == Variable::LET 1648 Scope* declaration_scope = mode == Variable::LET
1639 ? top_scope_ : top_scope_->DeclarationScope(); 1649 ? top_scope_ : top_scope_->DeclarationScope();
1640 // The scope of a var/const declared variable anywhere inside a function 1650 // The scope of a var/const declared variable anywhere inside a function
1641 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can 1651 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
1642 // transform a source-level var/const declaration into a (Function) 1652 // transform a source-level var/const declaration into a (Function)
1643 // Scope declaration, and rewrite the source-level initialization into an 1653 // Scope declaration, and rewrite the source-level initialization into an
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1725 position = scanner().location().beg_pos; 1735 position = scanner().location().beg_pos;
1726 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 1736 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
1727 // Don't infer if it is "a = function(){...}();"-like expression. 1737 // Don't infer if it is "a = function(){...}();"-like expression.
1728 if (fni_ != NULL && 1738 if (fni_ != NULL &&
1729 value->AsCall() == NULL && 1739 value->AsCall() == NULL &&
1730 value->AsCallNew() == NULL) { 1740 value->AsCallNew() == NULL) {
1731 fni_->Infer(); 1741 fni_->Infer();
1732 } 1742 }
1733 } 1743 }
1734 1744
1735 // Make sure that 'const c' actually initializes 'c' to undefined 1745 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
1736 // even though it seems like a stupid thing to do. 1746 if (value == NULL && needs_init) {
1737 if (value == NULL && is_const) {
1738 value = GetLiteralUndefined(); 1747 value = GetLiteralUndefined();
1739 } 1748 }
1740 1749
1741 // Global variable declarations must be compiled in a specific 1750 // Global variable declarations must be compiled in a specific
1742 // way. When the script containing the global variable declaration 1751 // way. When the script containing the global variable declaration
1743 // is entered, the global variable must be declared, so that if it 1752 // is entered, the global variable must be declared, so that if it
1744 // doesn't exist (not even in a prototype of the global object) it 1753 // doesn't exist (not even in a prototype of the global object) it
1745 // gets created with an initial undefined value. This is handled 1754 // gets created with an initial undefined value. This is handled
1746 // by the declarations part of the function representing the 1755 // by the declarations part of the function representing the
1747 // top-level global code; see Runtime::DeclareGlobalVariable. If 1756 // top-level global code; see Runtime::DeclareGlobalVariable. If
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1815 // we still have a pending initialization value. We must distinguish 1824 // we still have a pending initialization value. We must distinguish
1816 // between variables and constants: Variable initializations are simply 1825 // between variables and constants: Variable initializations are simply
1817 // assignments (with all the consequences if they are inside a 'with' 1826 // assignments (with all the consequences if they are inside a 'with'
1818 // statement - they may change a 'with' object property). Constant 1827 // statement - they may change a 'with' object property). Constant
1819 // initializations always assign to the declared constant which is 1828 // initializations always assign to the declared constant which is
1820 // always at the function scope level. This is only relevant for 1829 // always at the function scope level. This is only relevant for
1821 // dynamically looked-up variables and constants (the start context 1830 // dynamically looked-up variables and constants (the start context
1822 // for constant lookups is always the function context, while it is 1831 // for constant lookups is always the function context, while it is
1823 // the top context for variables). Sigh... 1832 // the top context for variables). Sigh...
1824 if (value != NULL) { 1833 if (value != NULL) {
1825 Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR);
1826 bool in_with = is_const ? false : inside_with(); 1834 bool in_with = is_const ? false : inside_with();
1827 VariableProxy* proxy = 1835 VariableProxy* proxy =
1828 initialization_scope->NewUnresolved(name, in_with); 1836 initialization_scope->NewUnresolved(name, in_with);
1829 Assignment* assignment = 1837 Assignment* assignment =
1830 new(zone()) Assignment(isolate(), op, proxy, value, position); 1838 new(zone()) Assignment(isolate(), init_op, proxy, value, position);
1831 if (block) { 1839 if (block) {
1832 block->AddStatement(new(zone()) ExpressionStatement(assignment)); 1840 block->AddStatement(new(zone()) ExpressionStatement(assignment));
1833 } 1841 }
1834 } 1842 }
1835 1843
1836 if (fni_ != NULL) fni_->Leave(); 1844 if (fni_ != NULL) fni_->Leave();
1837 } while (peek() == Token::COMMA); 1845 } while (peek() == Token::COMMA);
1838 1846
1839 // If there was a single non-const declaration, return it in the output 1847 // If there was a single non-const declaration, return it in the output
1840 // parameter for possible use by for/in. 1848 // parameter for possible use by for/in.
(...skipping 3334 matching lines...) Expand 10 before | Expand all | Expand 10 after
5175 result = parser.ParseProgram(source, 5183 result = parser.ParseProgram(source,
5176 info->is_global(), 5184 info->is_global(),
5177 info->StrictMode()); 5185 info->StrictMode());
5178 } 5186 }
5179 } 5187 }
5180 info->SetFunction(result); 5188 info->SetFunction(result);
5181 return (result != NULL); 5189 return (result != NULL);
5182 } 5190 }
5183 5191
5184 } } // namespace v8::internal 5192 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698