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/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
(...skipping 2461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2472 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL && | 2472 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL && |
2473 expr->AsVariableProxy() != NULL && | 2473 expr->AsVariableProxy() != NULL && |
2474 expr->AsVariableProxy()->raw_name() == | 2474 expr->AsVariableProxy()->raw_name() == |
2475 ast_value_factory()->native_string() && | 2475 ast_value_factory()->native_string() && |
2476 !scanner()->literal_contains_escapes()) { | 2476 !scanner()->literal_contains_escapes()) { |
2477 return ParseNativeDeclaration(ok); | 2477 return ParseNativeDeclaration(ok); |
2478 } | 2478 } |
2479 | 2479 |
2480 // Parsed expression statement, or the context-sensitive 'module' keyword. | 2480 // Parsed expression statement, or the context-sensitive 'module' keyword. |
2481 // Only expect semicolon in the former case. | 2481 // Only expect semicolon in the former case. |
| 2482 // Also detect attempts at 'let' declarations in sloppy mode. |
2482 if (!FLAG_harmony_modules || peek() != Token::IDENTIFIER || | 2483 if (!FLAG_harmony_modules || peek() != Token::IDENTIFIER || |
2483 scanner()->HasAnyLineTerminatorBeforeNext() || | 2484 scanner()->HasAnyLineTerminatorBeforeNext() || |
2484 expr->AsVariableProxy() == NULL || | 2485 expr->AsVariableProxy() == NULL || |
2485 expr->AsVariableProxy()->raw_name() != | 2486 expr->AsVariableProxy()->raw_name() != |
2486 ast_value_factory()->module_string() || | 2487 ast_value_factory()->module_string() || |
2487 scanner()->literal_contains_escapes()) { | 2488 scanner()->literal_contains_escapes()) { |
| 2489 if (peek() == Token::IDENTIFIER && expr->AsVariableProxy() != NULL && |
| 2490 expr->AsVariableProxy()->raw_name() == |
| 2491 ast_value_factory()->let_string()) { |
| 2492 ReportMessage("lexical_strict_mode", NULL); |
| 2493 *ok = false; |
| 2494 return NULL; |
| 2495 } |
2488 ExpectSemicolon(CHECK_OK); | 2496 ExpectSemicolon(CHECK_OK); |
2489 } | 2497 } |
2490 return factory()->NewExpressionStatement(expr, pos); | 2498 return factory()->NewExpressionStatement(expr, pos); |
2491 } | 2499 } |
2492 | 2500 |
2493 | 2501 |
2494 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels, | 2502 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels, |
2495 bool* ok) { | 2503 bool* ok) { |
2496 // IfStatement :: | 2504 // IfStatement :: |
2497 // 'if' '(' Expression ')' Statement ('else' Statement)? | 2505 // 'if' '(' Expression ')' Statement ('else' Statement)? |
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3207 ZoneList<const AstRawString*> let_bindings(1, zone()); | 3215 ZoneList<const AstRawString*> let_bindings(1, zone()); |
3208 | 3216 |
3209 // Create an in-between scope for let-bound iteration variables. | 3217 // Create an in-between scope for let-bound iteration variables. |
3210 Scope* saved_scope = scope_; | 3218 Scope* saved_scope = scope_; |
3211 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); | 3219 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); |
3212 scope_ = for_scope; | 3220 scope_ = for_scope; |
3213 | 3221 |
3214 Expect(Token::FOR, CHECK_OK); | 3222 Expect(Token::FOR, CHECK_OK); |
3215 Expect(Token::LPAREN, CHECK_OK); | 3223 Expect(Token::LPAREN, CHECK_OK); |
3216 for_scope->set_start_position(scanner()->location().beg_pos); | 3224 for_scope->set_start_position(scanner()->location().beg_pos); |
| 3225 bool is_let_identifier_expression = false; |
3217 if (peek() != Token::SEMICOLON) { | 3226 if (peek() != Token::SEMICOLON) { |
3218 if (peek() == Token::VAR || | 3227 if (peek() == Token::VAR || |
3219 (peek() == Token::CONST && strict_mode() == SLOPPY)) { | 3228 (peek() == Token::CONST && strict_mode() == SLOPPY)) { |
3220 bool is_const = peek() == Token::CONST; | 3229 bool is_const = peek() == Token::CONST; |
3221 const AstRawString* name = NULL; | 3230 const AstRawString* name = NULL; |
3222 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3231 VariableDeclarationProperties decl_props = kHasNoInitializers; |
3223 Block* variable_statement = | 3232 Block* variable_statement = |
3224 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 3233 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
3225 CHECK_OK); | 3234 CHECK_OK); |
3226 bool accept_OF = decl_props == kHasNoInitializers; | 3235 bool accept_OF = decl_props == kHasNoInitializers; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3318 return loop; | 3327 return loop; |
3319 | 3328 |
3320 } else { | 3329 } else { |
3321 init = variable_statement; | 3330 init = variable_statement; |
3322 } | 3331 } |
3323 } else { | 3332 } else { |
3324 Scanner::Location lhs_location = scanner()->peek_location(); | 3333 Scanner::Location lhs_location = scanner()->peek_location(); |
3325 Expression* expression = ParseExpression(false, CHECK_OK); | 3334 Expression* expression = ParseExpression(false, CHECK_OK); |
3326 ForEachStatement::VisitMode mode; | 3335 ForEachStatement::VisitMode mode; |
3327 bool accept_OF = expression->IsVariableProxy(); | 3336 bool accept_OF = expression->IsVariableProxy(); |
| 3337 is_let_identifier_expression = |
| 3338 expression->IsVariableProxy() && |
| 3339 expression->AsVariableProxy()->raw_name() == |
| 3340 ast_value_factory()->let_string(); |
3328 | 3341 |
3329 if (CheckInOrOf(accept_OF, &mode)) { | 3342 if (CheckInOrOf(accept_OF, &mode)) { |
3330 expression = this->CheckAndRewriteReferenceExpression( | 3343 expression = this->CheckAndRewriteReferenceExpression( |
3331 expression, lhs_location, "invalid_lhs_in_for", CHECK_OK); | 3344 expression, lhs_location, "invalid_lhs_in_for", CHECK_OK); |
3332 | 3345 |
3333 ForEachStatement* loop = | 3346 ForEachStatement* loop = |
3334 factory()->NewForEachStatement(mode, labels, stmt_pos); | 3347 factory()->NewForEachStatement(mode, labels, stmt_pos); |
3335 Target target(&this->target_stack_, loop); | 3348 Target target(&this->target_stack_, loop); |
3336 | 3349 |
3337 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3350 Expression* enumerable = ParseExpression(true, CHECK_OK); |
(...skipping 12 matching lines...) Expand all Loading... |
3350 init = factory()->NewExpressionStatement(expression, position()); | 3363 init = factory()->NewExpressionStatement(expression, position()); |
3351 } | 3364 } |
3352 } | 3365 } |
3353 } | 3366 } |
3354 | 3367 |
3355 // Standard 'for' loop | 3368 // Standard 'for' loop |
3356 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); | 3369 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); |
3357 Target target(&this->target_stack_, loop); | 3370 Target target(&this->target_stack_, loop); |
3358 | 3371 |
3359 // Parsed initializer at this point. | 3372 // Parsed initializer at this point. |
| 3373 // Detect attempts at 'let' declarations in sloppy mode. |
| 3374 if (peek() == Token::IDENTIFIER && strict_mode() == SLOPPY && |
| 3375 is_let_identifier_expression) { |
| 3376 ReportMessage("lexical_strict_mode", NULL); |
| 3377 *ok = false; |
| 3378 return NULL; |
| 3379 } |
3360 Expect(Token::SEMICOLON, CHECK_OK); | 3380 Expect(Token::SEMICOLON, CHECK_OK); |
3361 | 3381 |
3362 // If there are let bindings, then condition and the next statement of the | 3382 // If there are let bindings, then condition and the next statement of the |
3363 // for loop must be parsed in a new scope. | 3383 // for loop must be parsed in a new scope. |
3364 Scope* inner_scope = NULL; | 3384 Scope* inner_scope = NULL; |
3365 if (let_bindings.length() > 0) { | 3385 if (let_bindings.length() > 0) { |
3366 inner_scope = NewScope(for_scope, BLOCK_SCOPE); | 3386 inner_scope = NewScope(for_scope, BLOCK_SCOPE); |
3367 inner_scope->set_start_position(scanner()->location().beg_pos); | 3387 inner_scope->set_start_position(scanner()->location().beg_pos); |
3368 scope_ = inner_scope; | 3388 scope_ = inner_scope; |
3369 } | 3389 } |
(...skipping 1916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5286 | 5306 |
5287 const AstRawString* raw_str = ast_value_factory()->GetOneByteString( | 5307 const AstRawString* raw_str = ast_value_factory()->GetOneByteString( |
5288 OneByteVector(raw_chars.get(), to_index)); | 5308 OneByteVector(raw_chars.get(), to_index)); |
5289 Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1); | 5309 Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1); |
5290 raw_strings->Add(raw_lit, zone()); | 5310 raw_strings->Add(raw_lit, zone()); |
5291 } | 5311 } |
5292 | 5312 |
5293 return raw_strings; | 5313 return raw_strings; |
5294 } | 5314 } |
5295 } } // namespace v8::internal | 5315 } } // namespace v8::internal |
OLD | NEW |