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 777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 target_stack_(NULL), | 788 target_stack_(NULL), |
789 cached_parse_data_(NULL), | 789 cached_parse_data_(NULL), |
790 info_(info), | 790 info_(info), |
791 has_pending_error_(false), | 791 has_pending_error_(false), |
792 pending_error_message_(NULL), | 792 pending_error_message_(NULL), |
793 pending_error_arg_(NULL), | 793 pending_error_arg_(NULL), |
794 pending_error_char_arg_(NULL), | 794 pending_error_char_arg_(NULL), |
795 total_preparse_skipped_(0), | 795 total_preparse_skipped_(0), |
796 pre_parse_timer_(NULL) { | 796 pre_parse_timer_(NULL) { |
797 DCHECK(!script().is_null() || info->source_stream() != NULL); | 797 DCHECK(!script().is_null() || info->source_stream() != NULL); |
| 798 set_allow_lazy(false); // Must be explicitly enabled. |
| 799 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); |
798 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 800 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
799 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 801 set_allow_harmony_modules(!info->is_native() && FLAG_harmony_modules); |
800 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 802 set_allow_harmony_arrow_functions(FLAG_harmony_arrow_functions); |
801 set_allow_lazy(false); // Must be explicitly enabled. | |
802 set_allow_arrow_functions(FLAG_harmony_arrow_functions); | |
803 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 803 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
804 set_allow_classes(FLAG_harmony_classes); | 804 set_allow_harmony_classes(FLAG_harmony_classes); |
805 set_allow_harmony_object_literals(FLAG_harmony_object_literals); | 805 set_allow_harmony_object_literals(FLAG_harmony_object_literals); |
806 set_allow_harmony_templates(FLAG_harmony_templates); | 806 set_allow_harmony_templates(FLAG_harmony_templates); |
| 807 set_allow_harmony_sloppy(FLAG_harmony_sloppy); |
807 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 808 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
808 ++feature) { | 809 ++feature) { |
809 use_counts_[feature] = 0; | 810 use_counts_[feature] = 0; |
810 } | 811 } |
811 if (info->ast_value_factory() == NULL) { | 812 if (info->ast_value_factory() == NULL) { |
812 // info takes ownership of AstValueFactory. | 813 // info takes ownership of AstValueFactory. |
813 info->SetAstValueFactory( | 814 info->SetAstValueFactory( |
814 new AstValueFactory(zone(), parse_info->hash_seed)); | 815 new AstValueFactory(zone(), parse_info->hash_seed)); |
815 } | 816 } |
816 } | 817 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
909 *scope = NewScope(*scope, EVAL_SCOPE); | 910 *scope = NewScope(*scope, EVAL_SCOPE); |
910 } | 911 } |
911 } else if (info->is_global()) { | 912 } else if (info->is_global()) { |
912 *scope = NewScope(*scope, SCRIPT_SCOPE); | 913 *scope = NewScope(*scope, SCRIPT_SCOPE); |
913 } | 914 } |
914 (*scope)->set_start_position(0); | 915 (*scope)->set_start_position(0); |
915 // End position will be set by the caller. | 916 // End position will be set by the caller. |
916 | 917 |
917 // Compute the parsing mode. | 918 // Compute the parsing mode. |
918 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; | 919 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; |
919 if (allow_natives_syntax() || extension_ != NULL || | 920 if (allow_natives() || extension_ != NULL || |
920 (*scope)->is_eval_scope()) { | 921 (*scope)->is_eval_scope()) { |
921 mode = PARSE_EAGERLY; | 922 mode = PARSE_EAGERLY; |
922 } | 923 } |
923 ParsingModeScope parsing_mode(this, mode); | 924 ParsingModeScope parsing_mode(this, mode); |
924 | 925 |
925 // Enters 'scope'. | 926 // Enters 'scope'. |
926 AstNodeFactory function_factory(ast_value_factory()); | 927 AstNodeFactory function_factory(ast_value_factory()); |
927 FunctionState function_state(&function_state_, &scope_, *scope, | 928 FunctionState function_state(&function_state_, &scope_, *scope, |
928 &function_factory); | 929 &function_factory); |
929 | 930 |
(...skipping 1055 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1985 // | 1986 // |
1986 // class C { ... } | 1987 // class C { ... } |
1987 // | 1988 // |
1988 // has the same semantics as: | 1989 // has the same semantics as: |
1989 // | 1990 // |
1990 // let C = class C { ... }; | 1991 // let C = class C { ... }; |
1991 // | 1992 // |
1992 // so rewrite it as such. | 1993 // so rewrite it as such. |
1993 | 1994 |
1994 Expect(Token::CLASS, CHECK_OK); | 1995 Expect(Token::CLASS, CHECK_OK); |
| 1996 if (!allow_harmony_sloppy() && strict_mode() == SLOPPY) { |
| 1997 ReportMessage("sloppy_lexical"); |
| 1998 *ok = false; |
| 1999 return NULL; |
| 2000 } |
| 2001 |
1995 int pos = position(); | 2002 int pos = position(); |
1996 bool is_strict_reserved = false; | 2003 bool is_strict_reserved = false; |
1997 const AstRawString* name = | 2004 const AstRawString* name = |
1998 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 2005 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
1999 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(), | 2006 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(), |
2000 is_strict_reserved, pos, CHECK_OK); | 2007 is_strict_reserved, pos, CHECK_OK); |
2001 | 2008 |
2002 VariableProxy* proxy = NewUnresolved(name, LET, Interface::NewValue()); | 2009 VariableProxy* proxy = NewUnresolved(name, LET, Interface::NewValue()); |
2003 Declaration* declaration = | 2010 Declaration* declaration = |
2004 factory()->NewVariableDeclaration(proxy, LET, scope_, pos); | 2011 factory()->NewVariableDeclaration(proxy, LET, scope_, pos); |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2472 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL && | 2479 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL && |
2473 expr->AsVariableProxy() != NULL && | 2480 expr->AsVariableProxy() != NULL && |
2474 expr->AsVariableProxy()->raw_name() == | 2481 expr->AsVariableProxy()->raw_name() == |
2475 ast_value_factory()->native_string() && | 2482 ast_value_factory()->native_string() && |
2476 !scanner()->literal_contains_escapes()) { | 2483 !scanner()->literal_contains_escapes()) { |
2477 return ParseNativeDeclaration(ok); | 2484 return ParseNativeDeclaration(ok); |
2478 } | 2485 } |
2479 | 2486 |
2480 // Parsed expression statement, or the context-sensitive 'module' keyword. | 2487 // Parsed expression statement, or the context-sensitive 'module' keyword. |
2481 // Only expect semicolon in the former case. | 2488 // Only expect semicolon in the former case. |
| 2489 // Also detect attempts at 'let' declarations in sloppy mode. |
2482 if (!FLAG_harmony_modules || peek() != Token::IDENTIFIER || | 2490 if (!FLAG_harmony_modules || peek() != Token::IDENTIFIER || |
2483 scanner()->HasAnyLineTerminatorBeforeNext() || | 2491 scanner()->HasAnyLineTerminatorBeforeNext() || |
2484 expr->AsVariableProxy() == NULL || | 2492 expr->AsVariableProxy() == NULL || |
2485 expr->AsVariableProxy()->raw_name() != | 2493 expr->AsVariableProxy()->raw_name() != |
2486 ast_value_factory()->module_string() || | 2494 ast_value_factory()->module_string() || |
2487 scanner()->literal_contains_escapes()) { | 2495 scanner()->literal_contains_escapes()) { |
| 2496 if (peek() == Token::IDENTIFIER && expr->AsVariableProxy() != NULL && |
| 2497 expr->AsVariableProxy()->raw_name() == |
| 2498 ast_value_factory()->let_string()) { |
| 2499 ReportMessage("sloppy_lexical", NULL); |
| 2500 *ok = false; |
| 2501 return NULL; |
| 2502 } |
2488 ExpectSemicolon(CHECK_OK); | 2503 ExpectSemicolon(CHECK_OK); |
2489 } | 2504 } |
2490 return factory()->NewExpressionStatement(expr, pos); | 2505 return factory()->NewExpressionStatement(expr, pos); |
2491 } | 2506 } |
2492 | 2507 |
2493 | 2508 |
2494 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels, | 2509 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels, |
2495 bool* ok) { | 2510 bool* ok) { |
2496 // IfStatement :: | 2511 // IfStatement :: |
2497 // 'if' '(' Expression ')' Statement ('else' Statement)? | 2512 // '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()); | 3222 ZoneList<const AstRawString*> let_bindings(1, zone()); |
3208 | 3223 |
3209 // Create an in-between scope for let-bound iteration variables. | 3224 // Create an in-between scope for let-bound iteration variables. |
3210 Scope* saved_scope = scope_; | 3225 Scope* saved_scope = scope_; |
3211 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); | 3226 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); |
3212 scope_ = for_scope; | 3227 scope_ = for_scope; |
3213 | 3228 |
3214 Expect(Token::FOR, CHECK_OK); | 3229 Expect(Token::FOR, CHECK_OK); |
3215 Expect(Token::LPAREN, CHECK_OK); | 3230 Expect(Token::LPAREN, CHECK_OK); |
3216 for_scope->set_start_position(scanner()->location().beg_pos); | 3231 for_scope->set_start_position(scanner()->location().beg_pos); |
| 3232 bool is_let_identifier_expression = false; |
3217 if (peek() != Token::SEMICOLON) { | 3233 if (peek() != Token::SEMICOLON) { |
3218 if (peek() == Token::VAR || | 3234 if (peek() == Token::VAR || |
3219 (peek() == Token::CONST && strict_mode() == SLOPPY)) { | 3235 (peek() == Token::CONST && strict_mode() == SLOPPY)) { |
3220 bool is_const = peek() == Token::CONST; | 3236 bool is_const = peek() == Token::CONST; |
3221 const AstRawString* name = NULL; | 3237 const AstRawString* name = NULL; |
3222 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3238 VariableDeclarationProperties decl_props = kHasNoInitializers; |
3223 Block* variable_statement = | 3239 Block* variable_statement = |
3224 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 3240 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
3225 CHECK_OK); | 3241 CHECK_OK); |
3226 bool accept_OF = decl_props == kHasNoInitializers; | 3242 bool accept_OF = decl_props == kHasNoInitializers; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3318 return loop; | 3334 return loop; |
3319 | 3335 |
3320 } else { | 3336 } else { |
3321 init = variable_statement; | 3337 init = variable_statement; |
3322 } | 3338 } |
3323 } else { | 3339 } else { |
3324 Scanner::Location lhs_location = scanner()->peek_location(); | 3340 Scanner::Location lhs_location = scanner()->peek_location(); |
3325 Expression* expression = ParseExpression(false, CHECK_OK); | 3341 Expression* expression = ParseExpression(false, CHECK_OK); |
3326 ForEachStatement::VisitMode mode; | 3342 ForEachStatement::VisitMode mode; |
3327 bool accept_OF = expression->IsVariableProxy(); | 3343 bool accept_OF = expression->IsVariableProxy(); |
| 3344 is_let_identifier_expression = |
| 3345 expression->IsVariableProxy() && |
| 3346 expression->AsVariableProxy()->raw_name() == |
| 3347 ast_value_factory()->let_string(); |
3328 | 3348 |
3329 if (CheckInOrOf(accept_OF, &mode)) { | 3349 if (CheckInOrOf(accept_OF, &mode)) { |
3330 expression = this->CheckAndRewriteReferenceExpression( | 3350 expression = this->CheckAndRewriteReferenceExpression( |
3331 expression, lhs_location, "invalid_lhs_in_for", CHECK_OK); | 3351 expression, lhs_location, "invalid_lhs_in_for", CHECK_OK); |
3332 | 3352 |
3333 ForEachStatement* loop = | 3353 ForEachStatement* loop = |
3334 factory()->NewForEachStatement(mode, labels, stmt_pos); | 3354 factory()->NewForEachStatement(mode, labels, stmt_pos); |
3335 Target target(&this->target_stack_, loop); | 3355 Target target(&this->target_stack_, loop); |
3336 | 3356 |
3337 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3357 Expression* enumerable = ParseExpression(true, CHECK_OK); |
(...skipping 12 matching lines...) Expand all Loading... |
3350 init = factory()->NewExpressionStatement(expression, position()); | 3370 init = factory()->NewExpressionStatement(expression, position()); |
3351 } | 3371 } |
3352 } | 3372 } |
3353 } | 3373 } |
3354 | 3374 |
3355 // Standard 'for' loop | 3375 // Standard 'for' loop |
3356 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); | 3376 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); |
3357 Target target(&this->target_stack_, loop); | 3377 Target target(&this->target_stack_, loop); |
3358 | 3378 |
3359 // Parsed initializer at this point. | 3379 // Parsed initializer at this point. |
| 3380 // Detect attempts at 'let' declarations in sloppy mode. |
| 3381 if (peek() == Token::IDENTIFIER && strict_mode() == SLOPPY && |
| 3382 is_let_identifier_expression) { |
| 3383 ReportMessage("sloppy_lexical", NULL); |
| 3384 *ok = false; |
| 3385 return NULL; |
| 3386 } |
3360 Expect(Token::SEMICOLON, CHECK_OK); | 3387 Expect(Token::SEMICOLON, CHECK_OK); |
3361 | 3388 |
3362 // If there are let bindings, then condition and the next statement of the | 3389 // If there are let bindings, then condition and the next statement of the |
3363 // for loop must be parsed in a new scope. | 3390 // for loop must be parsed in a new scope. |
3364 Scope* inner_scope = NULL; | 3391 Scope* inner_scope = NULL; |
3365 if (let_bindings.length() > 0) { | 3392 if (let_bindings.length() > 0) { |
3366 inner_scope = NewScope(for_scope, BLOCK_SCOPE); | 3393 inner_scope = NewScope(for_scope, BLOCK_SCOPE); |
3367 inner_scope->set_start_position(scanner()->location().beg_pos); | 3394 inner_scope->set_start_position(scanner()->location().beg_pos); |
3368 scope_ = inner_scope; | 3395 scope_ = inner_scope; |
3369 } | 3396 } |
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3937 SingletonLogger* logger) { | 3964 SingletonLogger* logger) { |
3938 // This function may be called on a background thread too; record only the | 3965 // This function may be called on a background thread too; record only the |
3939 // main thread preparse times. | 3966 // main thread preparse times. |
3940 if (pre_parse_timer_ != NULL) { | 3967 if (pre_parse_timer_ != NULL) { |
3941 pre_parse_timer_->Start(); | 3968 pre_parse_timer_->Start(); |
3942 } | 3969 } |
3943 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); | 3970 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); |
3944 | 3971 |
3945 if (reusable_preparser_ == NULL) { | 3972 if (reusable_preparser_ == NULL) { |
3946 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit_); | 3973 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit_); |
| 3974 reusable_preparser_->set_allow_lazy(true); |
| 3975 reusable_preparser_->set_allow_natives(allow_natives()); |
3947 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 3976 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
3948 reusable_preparser_->set_allow_modules(allow_modules()); | 3977 reusable_preparser_->set_allow_harmony_modules(allow_harmony_modules()); |
3949 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); | 3978 reusable_preparser_->set_allow_harmony_arrow_functions( |
3950 reusable_preparser_->set_allow_lazy(true); | 3979 allow_harmony_arrow_functions()); |
3951 reusable_preparser_->set_allow_arrow_functions(allow_arrow_functions()); | |
3952 reusable_preparser_->set_allow_harmony_numeric_literals( | 3980 reusable_preparser_->set_allow_harmony_numeric_literals( |
3953 allow_harmony_numeric_literals()); | 3981 allow_harmony_numeric_literals()); |
3954 reusable_preparser_->set_allow_classes(allow_classes()); | 3982 reusable_preparser_->set_allow_harmony_classes(allow_harmony_classes()); |
3955 reusable_preparser_->set_allow_harmony_object_literals( | 3983 reusable_preparser_->set_allow_harmony_object_literals( |
3956 allow_harmony_object_literals()); | 3984 allow_harmony_object_literals()); |
3957 reusable_preparser_->set_allow_harmony_templates(allow_harmony_templates()); | 3985 reusable_preparser_->set_allow_harmony_templates(allow_harmony_templates()); |
| 3986 reusable_preparser_->set_allow_harmony_sloppy(allow_harmony_sloppy()); |
3958 } | 3987 } |
3959 PreParser::PreParseResult result = | 3988 PreParser::PreParseResult result = |
3960 reusable_preparser_->PreParseLazyFunction(strict_mode(), | 3989 reusable_preparser_->PreParseLazyFunction(strict_mode(), |
3961 is_generator(), | 3990 is_generator(), |
3962 logger); | 3991 logger); |
3963 if (pre_parse_timer_ != NULL) { | 3992 if (pre_parse_timer_ != NULL) { |
3964 pre_parse_timer_->Stop(); | 3993 pre_parse_timer_->Stop(); |
3965 } | 3994 } |
3966 return result; | 3995 return result; |
3967 } | 3996 } |
(...skipping 1114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5082 result->capture_count = capture_count; | 5111 result->capture_count = capture_count; |
5083 } | 5112 } |
5084 return !parser.failed(); | 5113 return !parser.failed(); |
5085 } | 5114 } |
5086 | 5115 |
5087 | 5116 |
5088 bool Parser::Parse() { | 5117 bool Parser::Parse() { |
5089 DCHECK(info()->function() == NULL); | 5118 DCHECK(info()->function() == NULL); |
5090 FunctionLiteral* result = NULL; | 5119 FunctionLiteral* result = NULL; |
5091 pre_parse_timer_ = isolate()->counters()->pre_parse(); | 5120 pre_parse_timer_ = isolate()->counters()->pre_parse(); |
5092 if (FLAG_trace_parse || allow_natives_syntax() || extension_ != NULL) { | 5121 if (FLAG_trace_parse || allow_natives() || extension_ != NULL) { |
5093 // If intrinsics are allowed, the Parser cannot operate independent of the | 5122 // If intrinsics are allowed, the Parser cannot operate independent of the |
5094 // V8 heap because of Runtime. Tell the string table to internalize strings | 5123 // V8 heap because of Runtime. Tell the string table to internalize strings |
5095 // and values right after they're created. | 5124 // and values right after they're created. |
5096 ast_value_factory()->Internalize(isolate()); | 5125 ast_value_factory()->Internalize(isolate()); |
5097 } | 5126 } |
5098 | 5127 |
5099 if (info()->is_lazy()) { | 5128 if (info()->is_lazy()) { |
5100 DCHECK(!info()->is_eval()); | 5129 DCHECK(!info()->is_eval()); |
5101 if (info()->shared_info()->is_function()) { | 5130 if (info()->shared_info()->is_function()) { |
5102 result = ParseLazy(); | 5131 result = ParseLazy(); |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5286 | 5315 |
5287 const AstRawString* raw_str = ast_value_factory()->GetOneByteString( | 5316 const AstRawString* raw_str = ast_value_factory()->GetOneByteString( |
5288 OneByteVector(raw_chars.get(), to_index)); | 5317 OneByteVector(raw_chars.get(), to_index)); |
5289 Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1); | 5318 Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1); |
5290 raw_strings->Add(raw_lit, zone()); | 5319 raw_strings->Add(raw_lit, zone()); |
5291 } | 5320 } |
5292 | 5321 |
5293 return raw_strings; | 5322 return raw_strings; |
5294 } | 5323 } |
5295 } } // namespace v8::internal | 5324 } } // namespace v8::internal |
OLD | NEW |