| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/ast.h" | 8 #include "src/ast.h" |
| 9 #include "src/ast-literal-reindexer.h" | 9 #include "src/ast-literal-reindexer.h" |
| 10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
| (...skipping 1369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1380 } | 1380 } |
| 1381 return ParseClassDeclaration(NULL, ok); | 1381 return ParseClassDeclaration(NULL, ok); |
| 1382 case Token::CONST: | 1382 case Token::CONST: |
| 1383 if (allow_const()) { | 1383 if (allow_const()) { |
| 1384 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1384 return ParseVariableStatement(kStatementListItem, NULL, ok); |
| 1385 } | 1385 } |
| 1386 break; | 1386 break; |
| 1387 case Token::VAR: | 1387 case Token::VAR: |
| 1388 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1388 return ParseVariableStatement(kStatementListItem, NULL, ok); |
| 1389 case Token::LET: | 1389 case Token::LET: |
| 1390 if (is_strict(language_mode())) { | 1390 if (allow_let()) { |
| 1391 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1391 return ParseVariableStatement(kStatementListItem, NULL, ok); |
| 1392 } | 1392 } |
| 1393 break; | 1393 break; |
| 1394 default: | 1394 default: |
| 1395 break; | 1395 break; |
| 1396 } | 1396 } |
| 1397 return ParseStatement(NULL, ok); | 1397 return ParseStatement(NULL, ok); |
| 1398 } | 1398 } |
| 1399 | 1399 |
| 1400 | 1400 |
| (...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2042 // functions. The function CheckConflictingVarDeclarations checks for | 2042 // functions. The function CheckConflictingVarDeclarations checks for |
| 2043 // var and let bindings from different scopes whereas this is a check for | 2043 // var and let bindings from different scopes whereas this is a check for |
| 2044 // conflicting declarations within the same scope. This check also covers | 2044 // conflicting declarations within the same scope. This check also covers |
| 2045 // the special case | 2045 // the special case |
| 2046 // | 2046 // |
| 2047 // function () { let x; { var x; } } | 2047 // function () { let x; { var x; } } |
| 2048 // | 2048 // |
| 2049 // because the var declaration is hoisted to the function scope where 'x' | 2049 // because the var declaration is hoisted to the function scope where 'x' |
| 2050 // is already bound. | 2050 // is already bound. |
| 2051 DCHECK(IsDeclaredVariableMode(var->mode())); | 2051 DCHECK(IsDeclaredVariableMode(var->mode())); |
| 2052 if (is_strict(language_mode())) { | 2052 if (is_strict(language_mode()) || allow_harmony_sloppy()) { |
| 2053 // In harmony we treat re-declarations as early errors. See | 2053 // In harmony we treat re-declarations as early errors. See |
| 2054 // ES5 16 for a definition of early errors. | 2054 // ES5 16 for a definition of early errors. |
| 2055 if (declaration_kind == DeclarationDescriptor::NORMAL) { | 2055 if (declaration_kind == DeclarationDescriptor::NORMAL) { |
| 2056 ParserTraits::ReportMessage(MessageTemplate::kVarRedeclaration, name); | 2056 ParserTraits::ReportMessage(MessageTemplate::kVarRedeclaration, name); |
| 2057 } else { | 2057 } else { |
| 2058 ParserTraits::ReportMessage(MessageTemplate::kStrictParamDupe); | 2058 ParserTraits::ReportMessage(MessageTemplate::kStrictParamDupe); |
| 2059 } | 2059 } |
| 2060 *ok = false; | 2060 *ok = false; |
| 2061 return nullptr; | 2061 return nullptr; |
| 2062 } | 2062 } |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2200 pos, FunctionLiteral::DECLARATION, | 2200 pos, FunctionLiteral::DECLARATION, |
| 2201 FunctionLiteral::NORMAL_ARITY, CHECK_OK); | 2201 FunctionLiteral::NORMAL_ARITY, CHECK_OK); |
| 2202 // Even if we're not at the top-level of the global or a function | 2202 // Even if we're not at the top-level of the global or a function |
| 2203 // scope, we treat it as such and introduce the function with its | 2203 // scope, we treat it as such and introduce the function with its |
| 2204 // initial value upon entering the corresponding scope. | 2204 // initial value upon entering the corresponding scope. |
| 2205 // In ES6, a function behaves as a lexical binding, except in | 2205 // In ES6, a function behaves as a lexical binding, except in |
| 2206 // a script scope, or the initial scope of eval or another function. | 2206 // a script scope, or the initial scope of eval or another function. |
| 2207 VariableMode mode = | 2207 VariableMode mode = |
| 2208 is_strong(language_mode()) | 2208 is_strong(language_mode()) |
| 2209 ? CONST | 2209 ? CONST |
| 2210 : is_strict(language_mode()) && | 2210 : (is_strict(language_mode()) || allow_harmony_sloppy()) && |
| 2211 !(scope_->is_script_scope() || scope_->is_eval_scope() || | 2211 !(scope_->is_script_scope() || scope_->is_eval_scope() || |
| 2212 scope_->is_function_scope()) | 2212 scope_->is_function_scope()) |
| 2213 ? LET | 2213 ? LET |
| 2214 : VAR; | 2214 : VAR; |
| 2215 VariableProxy* proxy = NewUnresolved(name, mode); | 2215 VariableProxy* proxy = NewUnresolved(name, mode); |
| 2216 Declaration* declaration = | 2216 Declaration* declaration = |
| 2217 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); | 2217 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); |
| 2218 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 2218 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
| 2219 if (names) names->Add(name, zone()); | 2219 if (names) names->Add(name, zone()); |
| 2220 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 2220 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2280 is_strong(language_mode()) ? Token::INIT_CONST : Token::INIT_LET; | 2280 is_strong(language_mode()) ? Token::INIT_CONST : Token::INIT_LET; |
| 2281 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos); | 2281 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos); |
| 2282 Statement* assignment_statement = | 2282 Statement* assignment_statement = |
| 2283 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); | 2283 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); |
| 2284 if (names) names->Add(name, zone()); | 2284 if (names) names->Add(name, zone()); |
| 2285 return assignment_statement; | 2285 return assignment_statement; |
| 2286 } | 2286 } |
| 2287 | 2287 |
| 2288 | 2288 |
| 2289 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) { | 2289 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) { |
| 2290 if (is_strict(language_mode())) { | 2290 if (is_strict(language_mode()) || allow_harmony_sloppy()) { |
| 2291 return ParseScopedBlock(labels, ok); | 2291 return ParseScopedBlock(labels, ok); |
| 2292 } | 2292 } |
| 2293 | 2293 |
| 2294 // Block :: | 2294 // Block :: |
| 2295 // '{' Statement* '}' | 2295 // '{' Statement* '}' |
| 2296 | 2296 |
| 2297 // Note that a Block does not introduce a new execution scope! | 2297 // Note that a Block does not introduce a new execution scope! |
| 2298 // (ECMA-262, 3rd, 12.2) | 2298 // (ECMA-262, 3rd, 12.2) |
| 2299 // | 2299 // |
| 2300 // Construct block expecting 16 statements. | 2300 // Construct block expecting 16 statements. |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2432 return; | 2432 return; |
| 2433 } | 2433 } |
| 2434 Consume(Token::VAR); | 2434 Consume(Token::VAR); |
| 2435 } else if (peek() == Token::CONST && allow_const()) { | 2435 } else if (peek() == Token::CONST && allow_const()) { |
| 2436 Consume(Token::CONST); | 2436 Consume(Token::CONST); |
| 2437 if (is_sloppy(language_mode()) && allow_legacy_const()) { | 2437 if (is_sloppy(language_mode()) && allow_legacy_const()) { |
| 2438 parsing_result->descriptor.mode = CONST_LEGACY; | 2438 parsing_result->descriptor.mode = CONST_LEGACY; |
| 2439 parsing_result->descriptor.init_op = Token::INIT_CONST_LEGACY; | 2439 parsing_result->descriptor.init_op = Token::INIT_CONST_LEGACY; |
| 2440 ++use_counts_[v8::Isolate::kLegacyConst]; | 2440 ++use_counts_[v8::Isolate::kLegacyConst]; |
| 2441 } else { | 2441 } else { |
| 2442 DCHECK(is_strict(language_mode())); | 2442 DCHECK(is_strict(language_mode()) || allow_harmony_sloppy()); |
| 2443 DCHECK(var_context != kStatement); | 2443 DCHECK(var_context != kStatement); |
| 2444 parsing_result->descriptor.mode = CONST; | 2444 parsing_result->descriptor.mode = CONST; |
| 2445 parsing_result->descriptor.init_op = Token::INIT_CONST; | 2445 parsing_result->descriptor.init_op = Token::INIT_CONST; |
| 2446 } | 2446 } |
| 2447 parsing_result->descriptor.is_const = true; | 2447 parsing_result->descriptor.is_const = true; |
| 2448 parsing_result->descriptor.needs_init = true; | 2448 parsing_result->descriptor.needs_init = true; |
| 2449 } else if (peek() == Token::LET && is_strict(language_mode())) { | 2449 } else if (peek() == Token::LET && allow_let()) { |
| 2450 Consume(Token::LET); | 2450 Consume(Token::LET); |
| 2451 DCHECK(var_context != kStatement); | 2451 DCHECK(var_context != kStatement); |
| 2452 parsing_result->descriptor.mode = LET; | 2452 parsing_result->descriptor.mode = LET; |
| 2453 parsing_result->descriptor.needs_init = true; | 2453 parsing_result->descriptor.needs_init = true; |
| 2454 parsing_result->descriptor.init_op = Token::INIT_LET; | 2454 parsing_result->descriptor.init_op = Token::INIT_LET; |
| 2455 } else { | 2455 } else { |
| 2456 UNREACHABLE(); // by current callers | 2456 UNREACHABLE(); // by current callers |
| 2457 } | 2457 } |
| 2458 | 2458 |
| 2459 parsing_result->descriptor.declaration_scope = | 2459 parsing_result->descriptor.declaration_scope = |
| (...skipping 1031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3491 Scope* saved_scope = scope_; | 3491 Scope* saved_scope = scope_; |
| 3492 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); | 3492 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); |
| 3493 scope_ = for_scope; | 3493 scope_ = for_scope; |
| 3494 Expect(Token::FOR, CHECK_OK); | 3494 Expect(Token::FOR, CHECK_OK); |
| 3495 Expect(Token::LPAREN, CHECK_OK); | 3495 Expect(Token::LPAREN, CHECK_OK); |
| 3496 for_scope->set_start_position(scanner()->location().beg_pos); | 3496 for_scope->set_start_position(scanner()->location().beg_pos); |
| 3497 bool is_let_identifier_expression = false; | 3497 bool is_let_identifier_expression = false; |
| 3498 DeclarationParsingResult parsing_result; | 3498 DeclarationParsingResult parsing_result; |
| 3499 if (peek() != Token::SEMICOLON) { | 3499 if (peek() != Token::SEMICOLON) { |
| 3500 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) || | 3500 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) || |
| 3501 (peek() == Token::LET && is_strict(language_mode()))) { | 3501 (peek() == Token::LET && allow_let())) { |
| 3502 ParseVariableDeclarations(kForStatement, &parsing_result, CHECK_OK); | 3502 ParseVariableDeclarations(kForStatement, &parsing_result, CHECK_OK); |
| 3503 is_const = parsing_result.descriptor.mode == CONST; | 3503 is_const = parsing_result.descriptor.mode == CONST; |
| 3504 | 3504 |
| 3505 int num_decl = parsing_result.declarations.length(); | 3505 int num_decl = parsing_result.declarations.length(); |
| 3506 bool accept_IN = num_decl >= 1; | 3506 bool accept_IN = num_decl >= 1; |
| 3507 bool accept_OF = true; | 3507 bool accept_OF = true; |
| 3508 ForEachStatement::VisitMode mode; | 3508 ForEachStatement::VisitMode mode; |
| 3509 int each_beg_pos = scanner()->location().beg_pos; | 3509 int each_beg_pos = scanner()->location().beg_pos; |
| 3510 int each_end_pos = scanner()->location().end_pos; | 3510 int each_end_pos = scanner()->location().end_pos; |
| 3511 | 3511 |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3966 // in all normal cases, function declarations are fully hoisted to a | 3966 // in all normal cases, function declarations are fully hoisted to a |
| 3967 // declaration scope and compiled relative to that. | 3967 // declaration scope and compiled relative to that. |
| 3968 // - (2) is the case iff the current declaration scope is still the original | 3968 // - (2) is the case iff the current declaration scope is still the original |
| 3969 // one relative to the deserialized scope chain. Otherwise we must be | 3969 // one relative to the deserialized scope chain. Otherwise we must be |
| 3970 // compiling a function in an inner declaration scope in the eval, e.g. a | 3970 // compiling a function in an inner declaration scope in the eval, e.g. a |
| 3971 // nested function, and hoisting works normally relative to that. | 3971 // nested function, and hoisting works normally relative to that. |
| 3972 Scope* declaration_scope = scope_->DeclarationScope(); | 3972 Scope* declaration_scope = scope_->DeclarationScope(); |
| 3973 Scope* original_declaration_scope = original_scope_->DeclarationScope(); | 3973 Scope* original_declaration_scope = original_scope_->DeclarationScope(); |
| 3974 Scope* scope = function_type == FunctionLiteral::DECLARATION && | 3974 Scope* scope = function_type == FunctionLiteral::DECLARATION && |
| 3975 is_sloppy(language_mode()) && | 3975 is_sloppy(language_mode()) && |
| 3976 !allow_harmony_sloppy() && |
| 3976 (original_scope_ == original_declaration_scope || | 3977 (original_scope_ == original_declaration_scope || |
| 3977 declaration_scope != original_declaration_scope) | 3978 declaration_scope != original_declaration_scope) |
| 3978 ? NewScope(declaration_scope, FUNCTION_SCOPE, kind) | 3979 ? NewScope(declaration_scope, FUNCTION_SCOPE, kind) |
| 3979 : NewScope(scope_, FUNCTION_SCOPE, kind); | 3980 : NewScope(scope_, FUNCTION_SCOPE, kind); |
| 3980 ZoneList<Statement*>* body = NULL; | 3981 ZoneList<Statement*>* body = NULL; |
| 3981 int materialized_literal_count = -1; | 3982 int materialized_literal_count = -1; |
| 3982 int expected_property_count = -1; | 3983 int expected_property_count = -1; |
| 3983 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); | 3984 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); |
| 3984 ExpressionClassifier formals_classifier(&duplicate_finder); | 3985 ExpressionClassifier formals_classifier(&duplicate_finder); |
| 3985 FunctionLiteral::EagerCompileHint eager_compile_hint = | 3986 FunctionLiteral::EagerCompileHint eager_compile_hint = |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4023 | 4024 |
| 4024 // If we have a named function expression, we add a local variable | 4025 // If we have a named function expression, we add a local variable |
| 4025 // declaration to the body of the function with the name of the | 4026 // declaration to the body of the function with the name of the |
| 4026 // function and let it refer to the function itself (closure). | 4027 // function and let it refer to the function itself (closure). |
| 4027 // NOTE: We create a proxy and resolve it here so that in the | 4028 // NOTE: We create a proxy and resolve it here so that in the |
| 4028 // future we can change the AST to only refer to VariableProxies | 4029 // future we can change the AST to only refer to VariableProxies |
| 4029 // instead of Variables and Proxis as is the case now. | 4030 // instead of Variables and Proxis as is the case now. |
| 4030 Variable* fvar = NULL; | 4031 Variable* fvar = NULL; |
| 4031 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; | 4032 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; |
| 4032 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 4033 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
| 4033 if (is_strict(language_mode())) { | 4034 bool use_strict_const = is_strict(language_mode()) || |
| 4035 (!allow_legacy_const() && allow_harmony_sloppy()); |
| 4036 if (use_strict_const) { |
| 4034 fvar_init_op = Token::INIT_CONST; | 4037 fvar_init_op = Token::INIT_CONST; |
| 4035 } | 4038 } |
| 4036 VariableMode fvar_mode = | 4039 VariableMode fvar_mode = use_strict_const ? CONST : CONST_LEGACY; |
| 4037 is_strict(language_mode()) ? CONST : CONST_LEGACY; | |
| 4038 DCHECK(function_name != NULL); | 4040 DCHECK(function_name != NULL); |
| 4039 fvar = new (zone()) | 4041 fvar = new (zone()) |
| 4040 Variable(scope_, function_name, fvar_mode, Variable::NORMAL, | 4042 Variable(scope_, function_name, fvar_mode, Variable::NORMAL, |
| 4041 kCreatedInitialized, kNotAssigned); | 4043 kCreatedInitialized, kNotAssigned); |
| 4042 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 4044 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
| 4043 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( | 4045 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
| 4044 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); | 4046 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); |
| 4045 scope_->DeclareFunctionVar(fvar_declaration); | 4047 scope_->DeclareFunctionVar(fvar_declaration); |
| 4046 } | 4048 } |
| 4047 | 4049 |
| (...skipping 1894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5942 Expression* Parser::SpreadCallNew(Expression* function, | 5944 Expression* Parser::SpreadCallNew(Expression* function, |
| 5943 ZoneList<v8::internal::Expression*>* args, | 5945 ZoneList<v8::internal::Expression*>* args, |
| 5944 int pos) { | 5946 int pos) { |
| 5945 args->InsertAt(0, function, zone()); | 5947 args->InsertAt(0, function, zone()); |
| 5946 | 5948 |
| 5947 return factory()->NewCallRuntime( | 5949 return factory()->NewCallRuntime( |
| 5948 ast_value_factory()->reflect_construct_string(), NULL, args, pos); | 5950 ast_value_factory()->reflect_construct_string(), NULL, args, pos); |
| 5949 } | 5951 } |
| 5950 } // namespace internal | 5952 } // namespace internal |
| 5951 } // namespace v8 | 5953 } // namespace v8 |
| OLD | NEW |