Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 617 // Compute the parsing mode. | 617 // Compute the parsing mode. |
| 618 Mode mode = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY; | 618 Mode mode = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY; |
| 619 if (allow_natives_syntax_ || extension_ != NULL) mode = PARSE_EAGERLY; | 619 if (allow_natives_syntax_ || extension_ != NULL) mode = PARSE_EAGERLY; |
| 620 ParsingModeScope parsing_mode(this, mode); | 620 ParsingModeScope parsing_mode(this, mode); |
| 621 | 621 |
| 622 Handle<String> no_name = isolate()->factory()->empty_symbol(); | 622 Handle<String> no_name = isolate()->factory()->empty_symbol(); |
| 623 | 623 |
| 624 FunctionLiteral* result = NULL; | 624 FunctionLiteral* result = NULL; |
| 625 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); | 625 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); |
| 626 info->SetGlobalScope(scope); | 626 info->SetGlobalScope(scope); |
| 627 if (!info->context().is_null()) { | |
| 628 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); | |
| 629 } | |
| 627 if (info->is_eval()) { | 630 if (info->is_eval()) { |
| 628 Handle<SharedFunctionInfo> shared = info->shared_info(); | |
| 629 if (!info->is_global() && (shared.is_null() || shared->is_function())) { | |
| 630 scope = Scope::DeserializeScopeChain(*info->calling_context(), scope, | |
| 631 zone()); | |
| 632 } | |
| 633 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { | 631 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { |
| 634 scope = NewScope(scope, EVAL_SCOPE); | 632 scope = NewScope(scope, EVAL_SCOPE); |
| 635 } | 633 } |
| 634 } else if (info->is_global()) { | |
| 635 scope = NewScope(scope, GLOBAL_SCOPE); | |
| 636 } | 636 } |
| 637 scope->set_start_position(0); | 637 scope->set_start_position(0); |
| 638 scope->set_end_position(source->length()); | 638 scope->set_end_position(source->length()); |
| 639 FunctionState function_state(this, scope, isolate()); | 639 |
| 640 FunctionState function_state(this, scope, isolate()); // Enters 'scope'. | |
| 640 top_scope_->SetLanguageMode(info->language_mode()); | 641 top_scope_->SetLanguageMode(info->language_mode()); |
| 641 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 642 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
| 642 bool ok = true; | 643 bool ok = true; |
| 643 int beg_loc = scanner().location().beg_pos; | 644 int beg_loc = scanner().location().beg_pos; |
| 644 ParseSourceElements(body, Token::EOS, info->is_eval(), &ok); | 645 ParseSourceElements(body, Token::EOS, info->is_eval(), &ok); |
| 645 if (ok && !top_scope_->is_classic_mode()) { | 646 if (ok && !top_scope_->is_classic_mode()) { |
| 646 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); | 647 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); |
| 647 } | 648 } |
| 648 | 649 |
| 649 if (ok && is_extended_mode()) { | 650 if (ok && is_extended_mode()) { |
| (...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1780 // will be added to the scope so that the declaration can be added | 1781 // will be added to the scope so that the declaration can be added |
| 1781 // to the corresponding activation frame at runtime if necessary. | 1782 // to the corresponding activation frame at runtime if necessary. |
| 1782 // For instance declarations inside an eval scope need to be added | 1783 // For instance declarations inside an eval scope need to be added |
| 1783 // to the calling function context. | 1784 // to the calling function context. |
| 1784 // Similarly, strict mode eval scope does not leak variable declarations to | 1785 // Similarly, strict mode eval scope does not leak variable declarations to |
| 1785 // the caller's scope so we declare all locals, too. | 1786 // the caller's scope so we declare all locals, too. |
| 1786 if (declaration_scope->is_function_scope() || | 1787 if (declaration_scope->is_function_scope() || |
| 1787 declaration_scope->is_strict_or_extended_eval_scope() || | 1788 declaration_scope->is_strict_or_extended_eval_scope() || |
| 1788 declaration_scope->is_block_scope() || | 1789 declaration_scope->is_block_scope() || |
| 1789 declaration_scope->is_module_scope() || | 1790 declaration_scope->is_module_scope() || |
| 1790 declaration->AsModuleDeclaration() != NULL) { | 1791 declaration_scope->is_global_scope()) { |
| 1791 // Declare the variable in the declaration scope. | 1792 // Declare the variable in the declaration scope. |
| 1792 var = declaration_scope->LocalLookup(name); | 1793 // For the global scope, we have to check for collisions with earlier |
| 1794 // (i.e., enclosing) global scopes, to maintain the illusion of a single | |
| 1795 // global scope. | |
| 1796 var = declaration_scope->is_global_scope() | |
| 1797 ? declaration_scope->Lookup(name) | |
| 1798 : declaration_scope->LocalLookup(name); | |
| 1793 if (var == NULL) { | 1799 if (var == NULL) { |
| 1794 // Declare the name. | 1800 // Declare the name. |
| 1795 var = declaration_scope->DeclareLocal( | 1801 var = declaration_scope->DeclareLocal( |
| 1796 name, mode, declaration->initialization(), proxy->interface()); | 1802 name, mode, declaration->initialization(), proxy->interface()); |
| 1797 } else { | 1803 } else if ((mode != VAR || var->mode() != VAR) && |
| 1804 (!declaration_scope->is_global_scope() || | |
| 1805 (mode != VAR && mode != CONST) || | |
|
Sven Panne
2012/08/28 07:35:00
o_O
rossberg
2012/08/28 11:09:39
You gotta love the beauty of semantic incoherence
| |
| 1806 (var->mode() != VAR && var->mode() != CONST))) { | |
| 1798 // The name was declared in this scope before; check for conflicting | 1807 // The name was declared in this scope before; check for conflicting |
| 1799 // re-declarations. We have a conflict if either of the declarations is | 1808 // re-declarations. We have a conflict if either of the declarations is |
| 1800 // not a var. There is similar code in runtime.cc in the Declare | 1809 // not a var (in the global scope, we also have to ignore legacy const for |
| 1810 // compatibility). There is similar code in runtime.cc in the Declare | |
| 1801 // functions. The function CheckNonConflictingScope checks for conflicting | 1811 // functions. The function CheckNonConflictingScope checks for conflicting |
| 1802 // var and let bindings from different scopes whereas this is a check for | 1812 // var and let bindings from different scopes whereas this is a check for |
| 1803 // conflicting declarations within the same scope. This check also covers | 1813 // conflicting declarations within the same scope. This check also covers |
| 1814 // the special case | |
| 1804 // | 1815 // |
| 1805 // function () { let x; { var x; } } | 1816 // function () { let x; { var x; } } |
| 1806 // | 1817 // |
| 1807 // because the var declaration is hoisted to the function scope where 'x' | 1818 // because the var declaration is hoisted to the function scope where 'x' |
| 1808 // is already bound. | 1819 // is already bound. |
| 1809 if ((mode != VAR) || (var->mode() != VAR)) { | 1820 // We only have vars, consts and lets in declarations. |
| 1810 // We only have vars, consts and lets in declarations. | 1821 ASSERT(var->mode() == VAR || |
| 1811 ASSERT(var->mode() == VAR || | 1822 var->mode() == CONST || |
| 1812 var->mode() == CONST || | 1823 var->mode() == CONST_HARMONY || |
| 1813 var->mode() == CONST_HARMONY || | 1824 var->mode() == LET); |
| 1814 var->mode() == LET); | 1825 if (is_extended_mode()) { |
| 1815 if (is_extended_mode()) { | 1826 // In harmony mode we treat re-declarations as early errors. See |
| 1816 // In harmony mode we treat re-declarations as early errors. See | 1827 // ES5 16 for a definition of early errors. |
| 1817 // ES5 16 for a definition of early errors. | 1828 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
| 1818 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | 1829 const char* elms[2] = { "Variable", *c_string }; |
| 1819 const char* elms[2] = { "Variable", *c_string }; | 1830 Vector<const char*> args(elms, 2); |
| 1820 Vector<const char*> args(elms, 2); | 1831 ReportMessage("redeclaration", args); |
| 1821 ReportMessage("redeclaration", args); | 1832 *ok = false; |
| 1822 *ok = false; | 1833 return; |
| 1823 return; | |
| 1824 } | |
| 1825 const char* type = (var->mode() == VAR) | |
| 1826 ? "var" : var->is_const_mode() ? "const" : "let"; | |
| 1827 Handle<String> type_string = | |
| 1828 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); | |
| 1829 Expression* expression = | |
| 1830 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), | |
| 1831 type_string, name); | |
| 1832 declaration_scope->SetIllegalRedeclaration(expression); | |
| 1833 } | 1834 } |
| 1835 const char* type = | |
| 1836 (var->mode() == VAR) ? "var" : var->is_const_mode() ? "const" : "let"; | |
| 1837 Handle<String> type_string = | |
| 1838 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); | |
| 1839 Expression* expression = | |
| 1840 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), | |
| 1841 type_string, name); | |
| 1842 declaration_scope->SetIllegalRedeclaration(expression); | |
| 1834 } | 1843 } |
| 1835 } | 1844 } |
| 1836 | 1845 |
| 1837 // We add a declaration node for every declaration. The compiler | 1846 // We add a declaration node for every declaration. The compiler |
| 1838 // will only generate code if necessary. In particular, declarations | 1847 // will only generate code if necessary. In particular, declarations |
| 1839 // for inner local variables that do not represent functions won't | 1848 // for inner local variables that do not represent functions won't |
| 1840 // result in any generated code. | 1849 // result in any generated code. |
| 1841 // | 1850 // |
| 1842 // Note that we always add an unresolved proxy even if it's not | 1851 // Note that we always add an unresolved proxy even if it's not |
| 1843 // used, simply because we don't know in this method (w/o extra | 1852 // used, simply because we don't know in this method (w/o extra |
| 1844 // parameters) if the proxy is needed or not. The proxy will be | 1853 // parameters) if the proxy is needed or not. The proxy will be |
| 1845 // bound during variable resolution time unless it was pre-bound | 1854 // bound during variable resolution time unless it was pre-bound |
| 1846 // below. | 1855 // below. |
| 1847 // | 1856 // |
| 1848 // WARNING: This will lead to multiple declaration nodes for the | 1857 // WARNING: This will lead to multiple declaration nodes for the |
| 1849 // same variable if it is declared several times. This is not a | 1858 // same variable if it is declared several times. This is not a |
| 1850 // semantic issue as long as we keep the source order, but it may be | 1859 // semantic issue as long as we keep the source order, but it may be |
| 1851 // a performance issue since it may lead to repeated | 1860 // a performance issue since it may lead to repeated |
| 1852 // Runtime::DeclareContextSlot() calls. | 1861 // Runtime::DeclareContextSlot() calls. |
| 1853 declaration_scope->AddDeclaration(declaration); | 1862 declaration_scope->AddDeclaration(declaration); |
| 1854 | 1863 |
| 1855 if ((mode == CONST || mode == CONST_HARMONY) && | 1864 if (mode == CONST && declaration_scope->is_global_scope()) { |
| 1856 declaration_scope->is_global_scope()) { | |
| 1857 // For global const variables we bind the proxy to a variable. | 1865 // For global const variables we bind the proxy to a variable. |
| 1858 ASSERT(resolve); // should be set by all callers | 1866 ASSERT(resolve); // should be set by all callers |
| 1859 Variable::Kind kind = Variable::NORMAL; | 1867 Variable::Kind kind = Variable::NORMAL; |
| 1860 var = new(zone()) Variable(declaration_scope, | 1868 var = new(zone()) Variable(declaration_scope, |
| 1861 name, | 1869 name, |
| 1862 mode, | 1870 mode, |
| 1863 true, | 1871 true, |
| 1864 kind, | 1872 kind, |
| 1865 kNeedsInitialization); | 1873 kNeedsInitialization); |
| 1866 } else if (declaration_scope->is_eval_scope() && | 1874 } else if (declaration_scope->is_eval_scope() && |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1997 int function_token_position = scanner().location().beg_pos; | 2005 int function_token_position = scanner().location().beg_pos; |
| 1998 bool is_strict_reserved = false; | 2006 bool is_strict_reserved = false; |
| 1999 Handle<String> name = ParseIdentifierOrStrictReservedWord( | 2007 Handle<String> name = ParseIdentifierOrStrictReservedWord( |
| 2000 &is_strict_reserved, CHECK_OK); | 2008 &is_strict_reserved, CHECK_OK); |
| 2001 FunctionLiteral* fun = ParseFunctionLiteral(name, | 2009 FunctionLiteral* fun = ParseFunctionLiteral(name, |
| 2002 is_strict_reserved, | 2010 is_strict_reserved, |
| 2003 function_token_position, | 2011 function_token_position, |
| 2004 FunctionLiteral::DECLARATION, | 2012 FunctionLiteral::DECLARATION, |
| 2005 CHECK_OK); | 2013 CHECK_OK); |
| 2006 // Even if we're not at the top-level of the global or a function | 2014 // Even if we're not at the top-level of the global or a function |
| 2007 // scope, we treat is as such and introduce the function with it's | 2015 // scope, we treat it as such and introduce the function with its |
| 2008 // initial value upon entering the corresponding scope. | 2016 // initial value upon entering the corresponding scope. |
| 2009 VariableMode mode = is_extended_mode() ? LET : VAR; | 2017 // In extended mode, a function behaves as a lexical binding, except in the |
| 2018 // global scope. | |
| 2019 VariableMode mode = | |
| 2020 is_extended_mode() && !top_scope_->is_global_scope() ? LET : VAR; | |
| 2010 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); | 2021 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); |
| 2011 Declaration* declaration = | 2022 Declaration* declaration = |
| 2012 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_); | 2023 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_); |
| 2013 Declare(declaration, true, CHECK_OK); | 2024 Declare(declaration, true, CHECK_OK); |
| 2014 if (names) names->Add(name, zone()); | 2025 if (names) names->Add(name, zone()); |
| 2015 return factory()->NewEmptyStatement(); | 2026 return factory()->NewEmptyStatement(); |
| 2016 } | 2027 } |
| 2017 | 2028 |
| 2018 | 2029 |
| 2019 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 2030 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2322 // executed. | 2333 // executed. |
| 2323 // | 2334 // |
| 2324 // Executing the variable declaration statement will always | 2335 // Executing the variable declaration statement will always |
| 2325 // guarantee to give the global object a "local" variable; a | 2336 // guarantee to give the global object a "local" variable; a |
| 2326 // variable defined in the global object and not in any | 2337 // variable defined in the global object and not in any |
| 2327 // prototype. This way, global variable declarations can shadow | 2338 // prototype. This way, global variable declarations can shadow |
| 2328 // properties in the prototype chain, but only after the variable | 2339 // properties in the prototype chain, but only after the variable |
| 2329 // declaration statement has been executed. This is important in | 2340 // declaration statement has been executed. This is important in |
| 2330 // browsers where the global object (window) has lots of | 2341 // browsers where the global object (window) has lots of |
| 2331 // properties defined in prototype objects. | 2342 // properties defined in prototype objects. |
| 2332 if (initialization_scope->is_global_scope()) { | 2343 if (initialization_scope->is_global_scope() && |
| 2344 mode != LET && mode != CONST_HARMONY) { | |
| 2333 // Compute the arguments for the runtime call. | 2345 // Compute the arguments for the runtime call. |
| 2334 ZoneList<Expression*>* arguments = | 2346 ZoneList<Expression*>* arguments = |
| 2335 new(zone()) ZoneList<Expression*>(3, zone()); | 2347 new(zone()) ZoneList<Expression*>(3, zone()); |
| 2336 // We have at least 1 parameter. | 2348 // We have at least 1 parameter. |
| 2337 arguments->Add(factory()->NewLiteral(name), zone()); | 2349 arguments->Add(factory()->NewLiteral(name), zone()); |
| 2338 CallRuntime* initialize; | 2350 CallRuntime* initialize; |
| 2339 | 2351 |
| 2340 if (is_const) { | 2352 if (is_const) { |
| 2341 arguments->Add(value, zone()); | 2353 arguments->Add(value, zone()); |
| 2342 value = NULL; // zap the value to avoid the unnecessary assignment | 2354 value = NULL; // zap the value to avoid the unnecessary assignment |
| (...skipping 3753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6096 ASSERT(info->isolate()->has_pending_exception()); | 6108 ASSERT(info->isolate()->has_pending_exception()); |
| 6097 } else { | 6109 } else { |
| 6098 result = parser.ParseProgram(); | 6110 result = parser.ParseProgram(); |
| 6099 } | 6111 } |
| 6100 } | 6112 } |
| 6101 info->SetFunction(result); | 6113 info->SetFunction(result); |
| 6102 return (result != NULL); | 6114 return (result != NULL); |
| 6103 } | 6115 } |
| 6104 | 6116 |
| 6105 } } // namespace v8::internal | 6117 } } // namespace v8::internal |
| OLD | NEW |