| 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 875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 886 | 886 |
| 887 scope_->SetStrictMode(info->strict_mode()); | 887 scope_->SetStrictMode(info->strict_mode()); |
| 888 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 888 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
| 889 bool ok = true; | 889 bool ok = true; |
| 890 int beg_pos = scanner()->location().beg_pos; | 890 int beg_pos = scanner()->location().beg_pos; |
| 891 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); | 891 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); |
| 892 if (ok && strict_mode() == STRICT) { | 892 if (ok && strict_mode() == STRICT) { |
| 893 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); | 893 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); |
| 894 } | 894 } |
| 895 | 895 |
| 896 if (ok && FLAG_harmony_scoping && strict_mode() == STRICT) { | 896 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { |
| 897 CheckConflictingVarDeclarations(scope_, &ok); | 897 CheckConflictingVarDeclarations(scope_, &ok); |
| 898 } | 898 } |
| 899 | 899 |
| 900 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 900 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
| 901 if (body->length() != 1 || | 901 if (body->length() != 1 || |
| 902 !body->at(0)->IsExpressionStatement() || | 902 !body->at(0)->IsExpressionStatement() || |
| 903 !body->at(0)->AsExpressionStatement()-> | 903 !body->at(0)->AsExpressionStatement()-> |
| 904 expression()->IsFunctionLiteral()) { | 904 expression()->IsFunctionLiteral()) { |
| 905 ReportMessage("single_function_literal", Vector<const char*>::empty()); | 905 ReportMessage("single_function_literal", Vector<const char*>::empty()); |
| 906 ok = false; | 906 ok = false; |
| (...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1691 // functions. The function CheckNonConflictingScope checks for conflicting | 1691 // functions. The function CheckNonConflictingScope checks for conflicting |
| 1692 // var and let bindings from different scopes whereas this is a check for | 1692 // var and let bindings from different scopes whereas this is a check for |
| 1693 // conflicting declarations within the same scope. This check also covers | 1693 // conflicting declarations within the same scope. This check also covers |
| 1694 // the special case | 1694 // the special case |
| 1695 // | 1695 // |
| 1696 // function () { let x; { var x; } } | 1696 // function () { let x; { var x; } } |
| 1697 // | 1697 // |
| 1698 // because the var declaration is hoisted to the function scope where 'x' | 1698 // because the var declaration is hoisted to the function scope where 'x' |
| 1699 // is already bound. | 1699 // is already bound. |
| 1700 ASSERT(IsDeclaredVariableMode(var->mode())); | 1700 ASSERT(IsDeclaredVariableMode(var->mode())); |
| 1701 if (FLAG_harmony_scoping && strict_mode() == STRICT) { | 1701 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
| 1702 // In harmony we treat re-declarations as early errors. See | 1702 // In harmony we treat re-declarations as early errors. See |
| 1703 // ES5 16 for a definition of early errors. | 1703 // ES5 16 for a definition of early errors. |
| 1704 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | 1704 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
| 1705 const char* elms[2] = { "Variable", c_string.get() }; | 1705 const char* elms[2] = { "Variable", c_string.get() }; |
| 1706 Vector<const char*> args(elms, 2); | 1706 Vector<const char*> args(elms, 2); |
| 1707 ReportMessage("redeclaration", args); | 1707 ReportMessage("redeclaration", args); |
| 1708 *ok = false; | 1708 *ok = false; |
| 1709 return; | 1709 return; |
| 1710 } | 1710 } |
| 1711 Handle<String> message_string = | 1711 Handle<String> message_string = |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1869 is_generator, | 1869 is_generator, |
| 1870 pos, | 1870 pos, |
| 1871 FunctionLiteral::DECLARATION, | 1871 FunctionLiteral::DECLARATION, |
| 1872 CHECK_OK); | 1872 CHECK_OK); |
| 1873 // Even if we're not at the top-level of the global or a function | 1873 // Even if we're not at the top-level of the global or a function |
| 1874 // scope, we treat it as such and introduce the function with its | 1874 // scope, we treat it as such and introduce the function with its |
| 1875 // initial value upon entering the corresponding scope. | 1875 // initial value upon entering the corresponding scope. |
| 1876 // In extended mode, a function behaves as a lexical binding, except in the | 1876 // In extended mode, a function behaves as a lexical binding, except in the |
| 1877 // global scope. | 1877 // global scope. |
| 1878 VariableMode mode = | 1878 VariableMode mode = |
| 1879 FLAG_harmony_scoping && | 1879 allow_harmony_scoping() && |
| 1880 strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR; | 1880 strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR; |
| 1881 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); | 1881 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); |
| 1882 Declaration* declaration = | 1882 Declaration* declaration = |
| 1883 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); | 1883 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); |
| 1884 Declare(declaration, true, CHECK_OK); | 1884 Declare(declaration, true, CHECK_OK); |
| 1885 if (names) names->Add(name, zone()); | 1885 if (names) names->Add(name, zone()); |
| 1886 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 1886 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 1887 } | 1887 } |
| 1888 | 1888 |
| 1889 | 1889 |
| 1890 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1890 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
| 1891 if (FLAG_harmony_scoping && strict_mode() == STRICT) { | 1891 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
| 1892 return ParseScopedBlock(labels, ok); | 1892 return ParseScopedBlock(labels, ok); |
| 1893 } | 1893 } |
| 1894 | 1894 |
| 1895 // Block :: | 1895 // Block :: |
| 1896 // '{' Statement* '}' | 1896 // '{' Statement* '}' |
| 1897 | 1897 |
| 1898 // Note that a Block does not introduce a new execution scope! | 1898 // Note that a Block does not introduce a new execution scope! |
| 1899 // (ECMA-262, 3rd, 12.2) | 1899 // (ECMA-262, 3rd, 12.2) |
| 1900 // | 1900 // |
| 1901 // Construct block expecting 16 statements. | 1901 // Construct block expecting 16 statements. |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2009 // However disallowing const in sloppy mode will break compatibility with | 2009 // However disallowing const in sloppy mode will break compatibility with |
| 2010 // existing pages. Therefore we keep allowing const with the old | 2010 // existing pages. Therefore we keep allowing const with the old |
| 2011 // non-harmony semantics in sloppy mode. | 2011 // non-harmony semantics in sloppy mode. |
| 2012 Consume(Token::CONST); | 2012 Consume(Token::CONST); |
| 2013 switch (strict_mode()) { | 2013 switch (strict_mode()) { |
| 2014 case SLOPPY: | 2014 case SLOPPY: |
| 2015 mode = CONST_LEGACY; | 2015 mode = CONST_LEGACY; |
| 2016 init_op = Token::INIT_CONST_LEGACY; | 2016 init_op = Token::INIT_CONST_LEGACY; |
| 2017 break; | 2017 break; |
| 2018 case STRICT: | 2018 case STRICT: |
| 2019 if (FLAG_harmony_scoping) { | 2019 if (allow_harmony_scoping()) { |
| 2020 if (var_context == kStatement) { | 2020 if (var_context == kStatement) { |
| 2021 // In strict mode 'const' declarations are only allowed in source | 2021 // In strict mode 'const' declarations are only allowed in source |
| 2022 // element positions. | 2022 // element positions. |
| 2023 ReportMessage("unprotected_const", Vector<const char*>::empty()); | 2023 ReportMessage("unprotected_const", Vector<const char*>::empty()); |
| 2024 *ok = false; | 2024 *ok = false; |
| 2025 return NULL; | 2025 return NULL; |
| 2026 } | 2026 } |
| 2027 mode = CONST; | 2027 mode = CONST; |
| 2028 init_op = Token::INIT_CONST; | 2028 init_op = Token::INIT_CONST; |
| 2029 } else { | 2029 } else { |
| 2030 ReportMessage("strict_const", Vector<const char*>::empty()); | 2030 ReportMessage("strict_const", Vector<const char*>::empty()); |
| 2031 *ok = false; | 2031 *ok = false; |
| 2032 return NULL; | 2032 return NULL; |
| 2033 } | 2033 } |
| 2034 } | 2034 } |
| 2035 is_const = true; | 2035 is_const = true; |
| 2036 needs_init = true; | 2036 needs_init = true; |
| 2037 } else if (peek() == Token::LET) { | 2037 } else if (peek() == Token::LET) { |
| 2038 // ES6 Draft Rev4 section 12.2.1: | 2038 // ES6 Draft Rev4 section 12.2.1: |
| 2039 // | 2039 // |
| 2040 // LetDeclaration : let LetBindingList ; | 2040 // LetDeclaration : let LetBindingList ; |
| 2041 // | 2041 // |
| 2042 // * It is a Syntax Error if the code that matches this production is not | 2042 // * It is a Syntax Error if the code that matches this production is not |
| 2043 // contained in extended code. | 2043 // contained in extended code. |
| 2044 // | 2044 // |
| 2045 // TODO(rossberg): make 'let' a legal identifier in sloppy mode. | 2045 // TODO(rossberg): make 'let' a legal identifier in sloppy mode. |
| 2046 if (!FLAG_harmony_scoping || strict_mode() == SLOPPY) { | 2046 if (!allow_harmony_scoping() || strict_mode() == SLOPPY) { |
| 2047 ReportMessage("illegal_let", Vector<const char*>::empty()); | 2047 ReportMessage("illegal_let", Vector<const char*>::empty()); |
| 2048 *ok = false; | 2048 *ok = false; |
| 2049 return NULL; | 2049 return NULL; |
| 2050 } | 2050 } |
| 2051 Consume(Token::LET); | 2051 Consume(Token::LET); |
| 2052 if (var_context == kStatement) { | 2052 if (var_context == kStatement) { |
| 2053 // Let declarations are only allowed in source element positions. | 2053 // Let declarations are only allowed in source element positions. |
| 2054 ReportMessage("unprotected_let", Vector<const char*>::empty()); | 2054 ReportMessage("unprotected_let", Vector<const char*>::empty()); |
| 2055 *ok = false; | 2055 *ok = false; |
| 2056 return NULL; | 2056 return NULL; |
| (...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2663 | 2663 |
| 2664 Expect(Token::LPAREN, CHECK_OK); | 2664 Expect(Token::LPAREN, CHECK_OK); |
| 2665 catch_scope = NewScope(scope_, CATCH_SCOPE); | 2665 catch_scope = NewScope(scope_, CATCH_SCOPE); |
| 2666 catch_scope->set_start_position(scanner()->location().beg_pos); | 2666 catch_scope->set_start_position(scanner()->location().beg_pos); |
| 2667 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2667 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 2668 | 2668 |
| 2669 Expect(Token::RPAREN, CHECK_OK); | 2669 Expect(Token::RPAREN, CHECK_OK); |
| 2670 | 2670 |
| 2671 Target target(&this->target_stack_, &catch_collector); | 2671 Target target(&this->target_stack_, &catch_collector); |
| 2672 VariableMode mode = | 2672 VariableMode mode = |
| 2673 FLAG_harmony_scoping && strict_mode() == STRICT ? LET : VAR; | 2673 allow_harmony_scoping() && strict_mode() == STRICT ? LET : VAR; |
| 2674 catch_variable = | 2674 catch_variable = |
| 2675 catch_scope->DeclareLocal(name, mode, kCreatedInitialized); | 2675 catch_scope->DeclareLocal(name, mode, kCreatedInitialized); |
| 2676 | 2676 |
| 2677 BlockState block_state(&scope_, catch_scope); | 2677 BlockState block_state(&scope_, catch_scope); |
| 2678 catch_block = ParseBlock(NULL, CHECK_OK); | 2678 catch_block = ParseBlock(NULL, CHECK_OK); |
| 2679 | 2679 |
| 2680 catch_scope->set_end_position(scanner()->location().end_pos); | 2680 catch_scope->set_end_position(scanner()->location().end_pos); |
| 2681 tok = peek(); | 2681 tok = peek(); |
| 2682 } | 2682 } |
| 2683 | 2683 |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3174 // in all normal cases, function declarations are fully hoisted to a | 3174 // in all normal cases, function declarations are fully hoisted to a |
| 3175 // declaration scope and compiled relative to that. | 3175 // declaration scope and compiled relative to that. |
| 3176 // - (2) is the case iff the current declaration scope is still the original | 3176 // - (2) is the case iff the current declaration scope is still the original |
| 3177 // one relative to the deserialized scope chain. Otherwise we must be | 3177 // one relative to the deserialized scope chain. Otherwise we must be |
| 3178 // compiling a function in an inner declaration scope in the eval, e.g. a | 3178 // compiling a function in an inner declaration scope in the eval, e.g. a |
| 3179 // nested function, and hoisting works normally relative to that. | 3179 // nested function, and hoisting works normally relative to that. |
| 3180 Scope* declaration_scope = scope_->DeclarationScope(); | 3180 Scope* declaration_scope = scope_->DeclarationScope(); |
| 3181 Scope* original_declaration_scope = original_scope_->DeclarationScope(); | 3181 Scope* original_declaration_scope = original_scope_->DeclarationScope(); |
| 3182 Scope* scope = | 3182 Scope* scope = |
| 3183 function_type == FunctionLiteral::DECLARATION && | 3183 function_type == FunctionLiteral::DECLARATION && |
| 3184 (!FLAG_harmony_scoping || strict_mode() == SLOPPY) && | 3184 (!allow_harmony_scoping() || strict_mode() == SLOPPY) && |
| 3185 (original_scope_ == original_declaration_scope || | 3185 (original_scope_ == original_declaration_scope || |
| 3186 declaration_scope != original_declaration_scope) | 3186 declaration_scope != original_declaration_scope) |
| 3187 ? NewScope(declaration_scope, FUNCTION_SCOPE) | 3187 ? NewScope(declaration_scope, FUNCTION_SCOPE) |
| 3188 : NewScope(scope_, FUNCTION_SCOPE); | 3188 : NewScope(scope_, FUNCTION_SCOPE); |
| 3189 ZoneList<Statement*>* body = NULL; | 3189 ZoneList<Statement*>* body = NULL; |
| 3190 int materialized_literal_count = -1; | 3190 int materialized_literal_count = -1; |
| 3191 int expected_property_count = -1; | 3191 int expected_property_count = -1; |
| 3192 int handler_count = 0; | 3192 int handler_count = 0; |
| 3193 FunctionLiteral::ParameterFlag duplicate_parameters = | 3193 FunctionLiteral::ParameterFlag duplicate_parameters = |
| 3194 FunctionLiteral::kNoDuplicateParameters; | 3194 FunctionLiteral::kNoDuplicateParameters; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3265 | 3265 |
| 3266 // If we have a named function expression, we add a local variable | 3266 // If we have a named function expression, we add a local variable |
| 3267 // declaration to the body of the function with the name of the | 3267 // declaration to the body of the function with the name of the |
| 3268 // function and let it refer to the function itself (closure). | 3268 // function and let it refer to the function itself (closure). |
| 3269 // NOTE: We create a proxy and resolve it here so that in the | 3269 // NOTE: We create a proxy and resolve it here so that in the |
| 3270 // future we can change the AST to only refer to VariableProxies | 3270 // future we can change the AST to only refer to VariableProxies |
| 3271 // instead of Variables and Proxis as is the case now. | 3271 // instead of Variables and Proxis as is the case now. |
| 3272 Variable* fvar = NULL; | 3272 Variable* fvar = NULL; |
| 3273 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; | 3273 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; |
| 3274 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 3274 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
| 3275 if (FLAG_harmony_scoping && strict_mode() == STRICT) { | 3275 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
| 3276 fvar_init_op = Token::INIT_CONST; | 3276 fvar_init_op = Token::INIT_CONST; |
| 3277 } | 3277 } |
| 3278 VariableMode fvar_mode = FLAG_harmony_scoping && strict_mode() == STRICT | 3278 VariableMode fvar_mode = |
| 3279 ? CONST : CONST_LEGACY; | 3279 allow_harmony_scoping() && strict_mode() == STRICT ? CONST |
| 3280 : CONST_LEGACY; |
| 3280 fvar = new(zone()) Variable(scope_, | 3281 fvar = new(zone()) Variable(scope_, |
| 3281 function_name, fvar_mode, true /* is valid LHS */, | 3282 function_name, fvar_mode, true /* is valid LHS */, |
| 3282 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); | 3283 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); |
| 3283 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 3284 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
| 3284 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( | 3285 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
| 3285 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); | 3286 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); |
| 3286 scope_->DeclareFunctionVar(fvar_declaration); | 3287 scope_->DeclareFunctionVar(fvar_declaration); |
| 3287 } | 3288 } |
| 3288 | 3289 |
| 3289 // Determine if the function can be parsed lazily. Lazy parsing is different | 3290 // Determine if the function can be parsed lazily. Lazy parsing is different |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3491 } | 3492 } |
| 3492 CheckOctalLiteral(scope->start_position(), | 3493 CheckOctalLiteral(scope->start_position(), |
| 3493 scope->end_position(), | 3494 scope->end_position(), |
| 3494 CHECK_OK); | 3495 CHECK_OK); |
| 3495 } | 3496 } |
| 3496 ast_properties = *factory()->visitor()->ast_properties(); | 3497 ast_properties = *factory()->visitor()->ast_properties(); |
| 3497 slot_processor = factory()->visitor()->slot_processor(); | 3498 slot_processor = factory()->visitor()->slot_processor(); |
| 3498 dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); | 3499 dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); |
| 3499 } | 3500 } |
| 3500 | 3501 |
| 3501 if (FLAG_harmony_scoping && strict_mode() == STRICT) { | 3502 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
| 3502 CheckConflictingVarDeclarations(scope, CHECK_OK); | 3503 CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 3503 } | 3504 } |
| 3504 | 3505 |
| 3505 FunctionLiteral* function_literal = | 3506 FunctionLiteral* function_literal = |
| 3506 factory()->NewFunctionLiteral(function_name, | 3507 factory()->NewFunctionLiteral(function_name, |
| 3507 scope, | 3508 scope, |
| 3508 body, | 3509 body, |
| 3509 materialized_literal_count, | 3510 materialized_literal_count, |
| 3510 expected_property_count, | 3511 expected_property_count, |
| 3511 handler_count, | 3512 handler_count, |
| (...skipping 1178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4690 ASSERT(info()->isolate()->has_pending_exception()); | 4691 ASSERT(info()->isolate()->has_pending_exception()); |
| 4691 } else { | 4692 } else { |
| 4692 result = ParseProgram(); | 4693 result = ParseProgram(); |
| 4693 } | 4694 } |
| 4694 } | 4695 } |
| 4695 info()->SetFunction(result); | 4696 info()->SetFunction(result); |
| 4696 return (result != NULL); | 4697 return (result != NULL); |
| 4697 } | 4698 } |
| 4698 | 4699 |
| 4699 } } // namespace v8::internal | 4700 } } // namespace v8::internal |
| OLD | NEW |