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 |