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 |