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/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/ast-expression-rewriter.h" | 9 #include "src/ast/ast-expression-rewriter.h" |
10 #include "src/ast/ast-expression-visitor.h" | 10 #include "src/ast/ast-expression-visitor.h" |
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
776 DCHECK(!info->script().is_null() || info->source_stream() != NULL); | 776 DCHECK(!info->script().is_null() || info->source_stream() != NULL); |
777 set_allow_lazy(info->allow_lazy_parsing()); | 777 set_allow_lazy(info->allow_lazy_parsing()); |
778 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); | 778 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); |
779 set_allow_harmony_sloppy(FLAG_harmony_sloppy); | 779 set_allow_harmony_sloppy(FLAG_harmony_sloppy); |
780 set_allow_harmony_sloppy_function(FLAG_harmony_sloppy_function); | 780 set_allow_harmony_sloppy_function(FLAG_harmony_sloppy_function); |
781 set_allow_harmony_sloppy_let(FLAG_harmony_sloppy_let); | 781 set_allow_harmony_sloppy_let(FLAG_harmony_sloppy_let); |
782 set_allow_harmony_default_parameters(FLAG_harmony_default_parameters); | 782 set_allow_harmony_default_parameters(FLAG_harmony_default_parameters); |
783 set_allow_harmony_destructuring_bind(FLAG_harmony_destructuring_bind); | 783 set_allow_harmony_destructuring_bind(FLAG_harmony_destructuring_bind); |
784 set_allow_harmony_destructuring_assignment( | 784 set_allow_harmony_destructuring_assignment( |
785 FLAG_harmony_destructuring_assignment); | 785 FLAG_harmony_destructuring_assignment); |
786 set_allow_strong_mode(FLAG_strong_mode); | |
787 set_allow_legacy_const(FLAG_legacy_const); | 786 set_allow_legacy_const(FLAG_legacy_const); |
788 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); | 787 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); |
789 set_allow_harmony_function_name(FLAG_harmony_function_name); | 788 set_allow_harmony_function_name(FLAG_harmony_function_name); |
790 set_allow_harmony_function_sent(FLAG_harmony_function_sent); | 789 set_allow_harmony_function_sent(FLAG_harmony_function_sent); |
791 set_allow_harmony_restrictive_declarations( | 790 set_allow_harmony_restrictive_declarations( |
792 FLAG_harmony_restrictive_declarations); | 791 FLAG_harmony_restrictive_declarations); |
793 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 792 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
794 ++feature) { | 793 ++feature) { |
795 use_counts_[feature] = 0; | 794 use_counts_[feature] = 0; |
796 } | 795 } |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
910 | 909 |
911 scope->set_start_position(0); | 910 scope->set_start_position(0); |
912 | 911 |
913 // Enter 'scope' with the given parsing mode. | 912 // Enter 'scope' with the given parsing mode. |
914 ParsingModeScope parsing_mode_scope(this, parsing_mode); | 913 ParsingModeScope parsing_mode_scope(this, parsing_mode); |
915 AstNodeFactory function_factory(ast_value_factory()); | 914 AstNodeFactory function_factory(ast_value_factory()); |
916 FunctionState function_state(&function_state_, &scope_, scope, | 915 FunctionState function_state(&function_state_, &scope_, scope, |
917 kNormalFunction, &function_factory); | 916 kNormalFunction, &function_factory); |
918 | 917 |
919 // Don't count the mode in the use counters--give the program a chance | 918 // Don't count the mode in the use counters--give the program a chance |
920 // to enable script/module-wide strict/strong mode below. | 919 // to enable script/module-wide strict mode below. |
921 scope_->SetLanguageMode(info->language_mode()); | 920 scope_->SetLanguageMode(info->language_mode()); |
922 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 921 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
923 bool ok = true; | 922 bool ok = true; |
924 int beg_pos = scanner()->location().beg_pos; | 923 int beg_pos = scanner()->location().beg_pos; |
925 if (info->is_module()) { | 924 if (info->is_module()) { |
926 ParseModuleItemList(body, &ok); | 925 ParseModuleItemList(body, &ok); |
927 } else { | 926 } else { |
928 ParseStatementList(body, Token::EOS, &ok); | 927 ParseStatementList(body, Token::EOS, &ok); |
929 } | 928 } |
930 | 929 |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1163 | 1162 |
1164 DCHECK(body != NULL); | 1163 DCHECK(body != NULL); |
1165 bool directive_prologue = true; // Parsing directive prologue. | 1164 bool directive_prologue = true; // Parsing directive prologue. |
1166 | 1165 |
1167 while (peek() != end_token) { | 1166 while (peek() != end_token) { |
1168 if (directive_prologue && peek() != Token::STRING) { | 1167 if (directive_prologue && peek() != Token::STRING) { |
1169 directive_prologue = false; | 1168 directive_prologue = false; |
1170 } | 1169 } |
1171 | 1170 |
1172 Scanner::Location token_loc = scanner()->peek_location(); | 1171 Scanner::Location token_loc = scanner()->peek_location(); |
1173 Scanner::Location old_this_loc = function_state_->this_location(); | |
1174 Scanner::Location old_super_loc = function_state_->super_location(); | |
1175 Statement* stat = ParseStatementListItem(CHECK_OK); | 1172 Statement* stat = ParseStatementListItem(CHECK_OK); |
1176 | |
1177 if (is_strong(language_mode()) && scope_->is_function_scope() && | |
1178 IsClassConstructor(function_state_->kind())) { | |
1179 Scanner::Location this_loc = function_state_->this_location(); | |
1180 Scanner::Location super_loc = function_state_->super_location(); | |
1181 if (this_loc.beg_pos != old_this_loc.beg_pos && | |
1182 this_loc.beg_pos != token_loc.beg_pos) { | |
1183 ReportMessageAt(this_loc, MessageTemplate::kStrongConstructorThis); | |
1184 *ok = false; | |
1185 return nullptr; | |
1186 } | |
1187 if (super_loc.beg_pos != old_super_loc.beg_pos && | |
1188 super_loc.beg_pos != token_loc.beg_pos) { | |
1189 ReportMessageAt(super_loc, MessageTemplate::kStrongConstructorSuper); | |
1190 *ok = false; | |
1191 return nullptr; | |
1192 } | |
1193 } | |
1194 | |
1195 if (stat == NULL || stat->IsEmpty()) { | 1173 if (stat == NULL || stat->IsEmpty()) { |
1196 directive_prologue = false; // End of directive prologue. | 1174 directive_prologue = false; // End of directive prologue. |
1197 continue; | 1175 continue; |
1198 } | 1176 } |
1199 | 1177 |
1200 if (directive_prologue) { | 1178 if (directive_prologue) { |
1201 // A shot at a directive. | 1179 // A shot at a directive. |
1202 ExpressionStatement* e_stat; | 1180 ExpressionStatement* e_stat; |
1203 Literal* literal; | 1181 Literal* literal; |
1204 // Still processing directive prologue? | 1182 // Still processing directive prologue? |
1205 if ((e_stat = stat->AsExpressionStatement()) != NULL && | 1183 if ((e_stat = stat->AsExpressionStatement()) != NULL && |
1206 (literal = e_stat->expression()->AsLiteral()) != NULL && | 1184 (literal = e_stat->expression()->AsLiteral()) != NULL && |
1207 literal->raw_value()->IsString()) { | 1185 literal->raw_value()->IsString()) { |
1208 // Check "use strict" directive (ES5 14.1), "use asm" directive, and | 1186 // Check "use strict" directive (ES5 14.1), "use asm" directive. |
1209 // "use strong" directive (experimental). | |
1210 bool use_strict_found = | 1187 bool use_strict_found = |
1211 literal->raw_value()->AsString() == | 1188 literal->raw_value()->AsString() == |
1212 ast_value_factory()->use_strict_string() && | 1189 ast_value_factory()->use_strict_string() && |
1213 token_loc.end_pos - token_loc.beg_pos == | 1190 token_loc.end_pos - token_loc.beg_pos == |
1214 ast_value_factory()->use_strict_string()->length() + 2; | 1191 ast_value_factory()->use_strict_string()->length() + 2; |
1215 bool use_strong_found = | 1192 if (use_strict_found) { |
1216 allow_strong_mode() && | |
1217 literal->raw_value()->AsString() == | |
1218 ast_value_factory()->use_strong_string() && | |
1219 token_loc.end_pos - token_loc.beg_pos == | |
1220 ast_value_factory()->use_strong_string()->length() + 2; | |
1221 if (use_strict_found || use_strong_found) { | |
1222 // Strong mode implies strict mode. If there are several "use strict" | |
1223 // / "use strong" directives, do the strict mode changes only once. | |
1224 if (is_sloppy(scope_->language_mode())) { | 1193 if (is_sloppy(scope_->language_mode())) { |
1225 RaiseLanguageMode(STRICT); | 1194 RaiseLanguageMode(STRICT); |
1226 } | 1195 } |
1227 | 1196 |
1228 if (use_strong_found) { | |
1229 RaiseLanguageMode(STRONG); | |
1230 if (IsClassConstructor(function_state_->kind())) { | |
1231 // "use strong" cannot occur in a class constructor body, to avoid | |
1232 // unintuitive strong class object semantics. | |
1233 ParserTraits::ReportMessageAt( | |
1234 token_loc, MessageTemplate::kStrongConstructorDirective); | |
1235 *ok = false; | |
1236 return nullptr; | |
1237 } | |
1238 } | |
1239 if (!scope_->HasSimpleParameters()) { | 1197 if (!scope_->HasSimpleParameters()) { |
1240 // TC39 deemed "use strict" directives to be an error when occurring | 1198 // TC39 deemed "use strict" directives to be an error when occurring |
1241 // in the body of a function with non-simple parameter list, on | 1199 // in the body of a function with non-simple parameter list, on |
1242 // 29/7/2015. https://goo.gl/ueA7Ln | 1200 // 29/7/2015. https://goo.gl/ueA7Ln |
1243 // | |
1244 // In V8, this also applies to "use strong " directives. | |
1245 const AstRawString* string = literal->raw_value()->AsString(); | 1201 const AstRawString* string = literal->raw_value()->AsString(); |
1246 ParserTraits::ReportMessageAt( | 1202 ParserTraits::ReportMessageAt( |
1247 token_loc, MessageTemplate::kIllegalLanguageModeDirective, | 1203 token_loc, MessageTemplate::kIllegalLanguageModeDirective, |
1248 string); | 1204 string); |
1249 *ok = false; | 1205 *ok = false; |
1250 return nullptr; | 1206 return nullptr; |
1251 } | 1207 } |
1252 // Because declarations in strict eval code don't leak into the scope | 1208 // Because declarations in strict eval code don't leak into the scope |
1253 // of the eval call, it is likely that functions declared in strict | 1209 // of the eval call, it is likely that functions declared in strict |
1254 // eval code will be used within the eval code, so lazy parsing is | 1210 // eval code will be used within the eval code, so lazy parsing is |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1454 local_name = ParseIdentifierName(CHECK_OK); | 1410 local_name = ParseIdentifierName(CHECK_OK); |
1455 } | 1411 } |
1456 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false)) { | 1412 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false)) { |
1457 *ok = false; | 1413 *ok = false; |
1458 ReportMessage(MessageTemplate::kUnexpectedReserved); | 1414 ReportMessage(MessageTemplate::kUnexpectedReserved); |
1459 return NULL; | 1415 return NULL; |
1460 } else if (IsEvalOrArguments(local_name)) { | 1416 } else if (IsEvalOrArguments(local_name)) { |
1461 *ok = false; | 1417 *ok = false; |
1462 ReportMessage(MessageTemplate::kStrictEvalArguments); | 1418 ReportMessage(MessageTemplate::kStrictEvalArguments); |
1463 return NULL; | 1419 return NULL; |
1464 } else if (is_strong(language_mode()) && IsUndefined(local_name)) { | |
1465 *ok = false; | |
1466 ReportMessage(MessageTemplate::kStrongUndefined); | |
1467 return NULL; | |
1468 } | 1420 } |
1469 VariableProxy* proxy = NewUnresolved(local_name, IMPORT); | 1421 VariableProxy* proxy = NewUnresolved(local_name, IMPORT); |
1470 ImportDeclaration* declaration = | 1422 ImportDeclaration* declaration = |
1471 factory()->NewImportDeclaration(proxy, import_name, NULL, scope_, pos); | 1423 factory()->NewImportDeclaration(proxy, import_name, NULL, scope_, pos); |
1472 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 1424 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
1473 result->Add(declaration, zone()); | 1425 result->Add(declaration, zone()); |
1474 if (peek() == Token::RBRACE) break; | 1426 if (peek() == Token::RBRACE) break; |
1475 Expect(Token::COMMA, CHECK_OK); | 1427 Expect(Token::COMMA, CHECK_OK); |
1476 } | 1428 } |
1477 | 1429 |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1802 // statements, which themselves are only valid within blocks, | 1754 // statements, which themselves are only valid within blocks, |
1803 // iterations or 'switch' statements (i.e., BreakableStatements), | 1755 // iterations or 'switch' statements (i.e., BreakableStatements), |
1804 // labels can be simply ignored in all other cases; except for | 1756 // labels can be simply ignored in all other cases; except for |
1805 // trivial labeled break statements 'label: break label' which is | 1757 // trivial labeled break statements 'label: break label' which is |
1806 // parsed into an empty statement. | 1758 // parsed into an empty statement. |
1807 switch (peek()) { | 1759 switch (peek()) { |
1808 case Token::LBRACE: | 1760 case Token::LBRACE: |
1809 return ParseBlock(labels, ok); | 1761 return ParseBlock(labels, ok); |
1810 | 1762 |
1811 case Token::SEMICOLON: | 1763 case Token::SEMICOLON: |
1812 if (is_strong(language_mode())) { | |
1813 ReportMessageAt(scanner()->peek_location(), | |
1814 MessageTemplate::kStrongEmpty); | |
1815 *ok = false; | |
1816 return NULL; | |
1817 } | |
1818 Next(); | 1764 Next(); |
1819 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 1765 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
1820 | 1766 |
1821 case Token::IF: | 1767 case Token::IF: |
1822 return ParseIfStatement(labels, ok); | 1768 return ParseIfStatement(labels, ok); |
1823 | 1769 |
1824 case Token::DO: | 1770 case Token::DO: |
1825 return ParseDoWhileStatement(labels, ok); | 1771 return ParseDoWhileStatement(labels, ok); |
1826 | 1772 |
1827 case Token::WHILE: | 1773 case Token::WHILE: |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2161 is_generator ? FunctionKind::kGeneratorFunction | 2107 is_generator ? FunctionKind::kGeneratorFunction |
2162 : FunctionKind::kNormalFunction, | 2108 : FunctionKind::kNormalFunction, |
2163 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); | 2109 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); |
2164 | 2110 |
2165 // Even if we're not at the top-level of the global or a function | 2111 // Even if we're not at the top-level of the global or a function |
2166 // scope, we treat it as such and introduce the function with its | 2112 // scope, we treat it as such and introduce the function with its |
2167 // initial value upon entering the corresponding scope. | 2113 // initial value upon entering the corresponding scope. |
2168 // In ES6, a function behaves as a lexical binding, except in | 2114 // In ES6, a function behaves as a lexical binding, except in |
2169 // a script scope, or the initial scope of eval or another function. | 2115 // a script scope, or the initial scope of eval or another function. |
2170 VariableMode mode = | 2116 VariableMode mode = |
2171 is_strong(language_mode()) | 2117 (is_strict(language_mode()) || allow_harmony_sloppy_function()) && |
2172 ? CONST | 2118 !scope_->is_declaration_scope() |
2173 : (is_strict(language_mode()) || allow_harmony_sloppy_function()) && | 2119 ? LET |
2174 !scope_->is_declaration_scope() | 2120 : VAR; |
2175 ? LET | |
2176 : VAR; | |
2177 VariableProxy* proxy = NewUnresolved(name, mode); | 2121 VariableProxy* proxy = NewUnresolved(name, mode); |
2178 Declaration* declaration = | 2122 Declaration* declaration = |
2179 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); | 2123 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); |
2180 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 2124 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
2181 if (names) names->Add(name, zone()); | 2125 if (names) names->Add(name, zone()); |
2182 EmptyStatement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 2126 EmptyStatement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
2183 if (is_sloppy(language_mode()) && allow_harmony_sloppy_function() && | 2127 if (is_sloppy(language_mode()) && allow_harmony_sloppy_function() && |
2184 !scope_->is_declaration_scope()) { | 2128 !scope_->is_declaration_scope()) { |
2185 SloppyBlockFunctionStatement* delegate = | 2129 SloppyBlockFunctionStatement* delegate = |
2186 factory()->NewSloppyBlockFunctionStatement(empty, scope_); | 2130 factory()->NewSloppyBlockFunctionStatement(empty, scope_); |
(...skipping 28 matching lines...) Expand all Loading... |
2215 return NULL; | 2159 return NULL; |
2216 } | 2160 } |
2217 | 2161 |
2218 int pos = position(); | 2162 int pos = position(); |
2219 bool is_strict_reserved = false; | 2163 bool is_strict_reserved = false; |
2220 const AstRawString* name = | 2164 const AstRawString* name = |
2221 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 2165 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
2222 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(), | 2166 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(), |
2223 is_strict_reserved, pos, CHECK_OK); | 2167 is_strict_reserved, pos, CHECK_OK); |
2224 | 2168 |
2225 VariableMode mode = is_strong(language_mode()) ? CONST : LET; | 2169 VariableProxy* proxy = NewUnresolved(name, LET); |
2226 VariableProxy* proxy = NewUnresolved(name, mode); | |
2227 Declaration* declaration = | 2170 Declaration* declaration = |
2228 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); | 2171 factory()->NewVariableDeclaration(proxy, LET, scope_, pos); |
2229 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 2172 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
2230 proxy->var()->set_initializer_position(position()); | 2173 proxy->var()->set_initializer_position(position()); |
2231 Assignment* assignment = | 2174 Assignment* assignment = |
2232 factory()->NewAssignment(Token::INIT, proxy, value, pos); | 2175 factory()->NewAssignment(Token::INIT, proxy, value, pos); |
2233 Statement* assignment_statement = | 2176 Statement* assignment_statement = |
2234 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); | 2177 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); |
2235 if (names) names->Add(name, zone()); | 2178 if (names) names->Add(name, zone()); |
2236 return assignment_statement; | 2179 return assignment_statement; |
2237 } | 2180 } |
2238 | 2181 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2338 parsing_result->descriptor.initialization_pos = peek_position(); | 2281 parsing_result->descriptor.initialization_pos = peek_position(); |
2339 parsing_result->descriptor.mode = VAR; | 2282 parsing_result->descriptor.mode = VAR; |
2340 | 2283 |
2341 Block* init_block = nullptr; | 2284 Block* init_block = nullptr; |
2342 if (var_context != kForStatement) { | 2285 if (var_context != kForStatement) { |
2343 init_block = factory()->NewBlock( | 2286 init_block = factory()->NewBlock( |
2344 NULL, 1, true, parsing_result->descriptor.declaration_pos); | 2287 NULL, 1, true, parsing_result->descriptor.declaration_pos); |
2345 } | 2288 } |
2346 | 2289 |
2347 if (peek() == Token::VAR) { | 2290 if (peek() == Token::VAR) { |
2348 if (is_strong(language_mode())) { | |
2349 Scanner::Location location = scanner()->peek_location(); | |
2350 ReportMessageAt(location, MessageTemplate::kStrongVar); | |
2351 *ok = false; | |
2352 return nullptr; | |
2353 } | |
2354 Consume(Token::VAR); | 2291 Consume(Token::VAR); |
2355 } else if (peek() == Token::CONST && allow_const()) { | 2292 } else if (peek() == Token::CONST && allow_const()) { |
2356 Consume(Token::CONST); | 2293 Consume(Token::CONST); |
2357 if (is_sloppy(language_mode()) && allow_legacy_const()) { | 2294 if (is_sloppy(language_mode()) && allow_legacy_const()) { |
2358 parsing_result->descriptor.mode = CONST_LEGACY; | 2295 parsing_result->descriptor.mode = CONST_LEGACY; |
2359 ++use_counts_[v8::Isolate::kLegacyConst]; | 2296 ++use_counts_[v8::Isolate::kLegacyConst]; |
2360 } else { | 2297 } else { |
2361 DCHECK(is_strict(language_mode()) || allow_harmony_sloppy()); | 2298 DCHECK(is_strict(language_mode()) || allow_harmony_sloppy()); |
2362 DCHECK(var_context != kStatement); | 2299 DCHECK(var_context != kStatement); |
2363 parsing_result->descriptor.mode = CONST; | 2300 parsing_result->descriptor.mode = CONST; |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2514 | 2451 |
2515 switch (peek()) { | 2452 switch (peek()) { |
2516 case Token::FUNCTION: | 2453 case Token::FUNCTION: |
2517 case Token::LBRACE: | 2454 case Token::LBRACE: |
2518 UNREACHABLE(); // Always handled by the callers. | 2455 UNREACHABLE(); // Always handled by the callers. |
2519 case Token::CLASS: | 2456 case Token::CLASS: |
2520 ReportUnexpectedToken(Next()); | 2457 ReportUnexpectedToken(Next()); |
2521 *ok = false; | 2458 *ok = false; |
2522 return nullptr; | 2459 return nullptr; |
2523 | 2460 |
2524 case Token::THIS: | |
2525 if (!FLAG_strong_this) break; | |
2526 // Fall through. | |
2527 case Token::SUPER: | |
2528 if (is_strong(language_mode()) && | |
2529 IsClassConstructor(function_state_->kind())) { | |
2530 bool is_this = peek() == Token::THIS; | |
2531 Expression* expr; | |
2532 ExpressionClassifier classifier(this); | |
2533 if (is_this) { | |
2534 expr = ParseStrongInitializationExpression(&classifier, CHECK_OK); | |
2535 } else { | |
2536 expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK); | |
2537 } | |
2538 RewriteNonPattern(&classifier, CHECK_OK); | |
2539 switch (peek()) { | |
2540 case Token::SEMICOLON: | |
2541 Consume(Token::SEMICOLON); | |
2542 break; | |
2543 case Token::RBRACE: | |
2544 case Token::EOS: | |
2545 break; | |
2546 default: | |
2547 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { | |
2548 ReportMessageAt(function_state_->this_location(), | |
2549 is_this | |
2550 ? MessageTemplate::kStrongConstructorThis | |
2551 : MessageTemplate::kStrongConstructorSuper); | |
2552 *ok = false; | |
2553 return nullptr; | |
2554 } | |
2555 } | |
2556 return factory()->NewExpressionStatement(expr, pos); | |
2557 } | |
2558 break; | |
2559 | |
2560 default: | 2461 default: |
2561 break; | 2462 break; |
2562 } | 2463 } |
2563 | 2464 |
2564 bool starts_with_idenfifier = peek_any_identifier(); | 2465 bool starts_with_idenfifier = peek_any_identifier(); |
2565 Expression* expr = ParseExpression(true, CHECK_OK); | 2466 Expression* expr = ParseExpression(true, CHECK_OK); |
2566 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && | 2467 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && |
2567 expr->AsVariableProxy() != NULL && | 2468 expr->AsVariableProxy() != NULL && |
2568 !expr->AsVariableProxy()->is_this()) { | 2469 !expr->AsVariableProxy()->is_this()) { |
2569 // Expression is a single identifier, and not, e.g., a parenthesized | 2470 // Expression is a single identifier, and not, e.g., a parenthesized |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2729 if (scanner()->HasAnyLineTerminatorBeforeNext() || | 2630 if (scanner()->HasAnyLineTerminatorBeforeNext() || |
2730 tok == Token::SEMICOLON || | 2631 tok == Token::SEMICOLON || |
2731 tok == Token::RBRACE || | 2632 tok == Token::RBRACE || |
2732 tok == Token::EOS) { | 2633 tok == Token::EOS) { |
2733 if (IsSubclassConstructor(function_state_->kind())) { | 2634 if (IsSubclassConstructor(function_state_->kind())) { |
2734 return_value = ThisExpression(scope_, factory(), loc.beg_pos); | 2635 return_value = ThisExpression(scope_, factory(), loc.beg_pos); |
2735 } else { | 2636 } else { |
2736 return_value = GetLiteralUndefined(position()); | 2637 return_value = GetLiteralUndefined(position()); |
2737 } | 2638 } |
2738 } else { | 2639 } else { |
2739 if (is_strong(language_mode()) && | |
2740 IsClassConstructor(function_state_->kind())) { | |
2741 int pos = peek_position(); | |
2742 ReportMessageAt(Scanner::Location(pos, pos + 1), | |
2743 MessageTemplate::kStrongConstructorReturnValue); | |
2744 *ok = false; | |
2745 return NULL; | |
2746 } | |
2747 | |
2748 int pos = peek_position(); | 2640 int pos = peek_position(); |
2749 return_value = ParseExpression(true, CHECK_OK); | 2641 return_value = ParseExpression(true, CHECK_OK); |
2750 | 2642 |
2751 if (IsSubclassConstructor(function_state_->kind())) { | 2643 if (IsSubclassConstructor(function_state_->kind())) { |
2752 // For subclass constructors we need to return this in case of undefined | 2644 // For subclass constructors we need to return this in case of undefined |
2753 // return a Smi (transformed into an exception in the ConstructStub) | 2645 // return a Smi (transformed into an exception in the ConstructStub) |
2754 // for a non object. | 2646 // for a non object. |
2755 // | 2647 // |
2756 // return expr; | 2648 // return expr; |
2757 // | 2649 // |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2864 int pos = position(); | 2756 int pos = position(); |
2865 ZoneList<Statement*>* statements = | 2757 ZoneList<Statement*>* statements = |
2866 new(zone()) ZoneList<Statement*>(5, zone()); | 2758 new(zone()) ZoneList<Statement*>(5, zone()); |
2867 Statement* stat = NULL; | 2759 Statement* stat = NULL; |
2868 while (peek() != Token::CASE && | 2760 while (peek() != Token::CASE && |
2869 peek() != Token::DEFAULT && | 2761 peek() != Token::DEFAULT && |
2870 peek() != Token::RBRACE) { | 2762 peek() != Token::RBRACE) { |
2871 stat = ParseStatementListItem(CHECK_OK); | 2763 stat = ParseStatementListItem(CHECK_OK); |
2872 statements->Add(stat, zone()); | 2764 statements->Add(stat, zone()); |
2873 } | 2765 } |
2874 if (is_strong(language_mode()) && stat != NULL && !stat->IsJump() && | |
2875 peek() != Token::RBRACE) { | |
2876 ReportMessageAt(scanner()->location(), | |
2877 MessageTemplate::kStrongSwitchFallthrough); | |
2878 *ok = false; | |
2879 return NULL; | |
2880 } | |
2881 return factory()->NewCaseClause(label, statements, pos); | 2766 return factory()->NewCaseClause(label, statements, pos); |
2882 } | 2767 } |
2883 | 2768 |
2884 | 2769 |
2885 Statement* Parser::ParseSwitchStatement(ZoneList<const AstRawString*>* labels, | 2770 Statement* Parser::ParseSwitchStatement(ZoneList<const AstRawString*>* labels, |
2886 bool* ok) { | 2771 bool* ok) { |
2887 // SwitchStatement :: | 2772 // SwitchStatement :: |
2888 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 2773 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
2889 // In order to get the CaseClauses to execute in their own lexical scope, | 2774 // In order to get the CaseClauses to execute in their own lexical scope, |
2890 // but without requiring downstream code to have special scope handling | 2775 // but without requiring downstream code to have special scope handling |
(...skipping 1474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4365 if (use_temp_zone) { | 4250 if (use_temp_zone) { |
4366 // If the preconditions are correct the function body should never be | 4251 // If the preconditions are correct the function body should never be |
4367 // accessed, but do this anyway for better behaviour if they're wrong. | 4252 // accessed, but do this anyway for better behaviour if they're wrong. |
4368 body = NULL; | 4253 body = NULL; |
4369 } | 4254 } |
4370 } | 4255 } |
4371 | 4256 |
4372 // Parsing the body may change the language mode in our scope. | 4257 // Parsing the body may change the language mode in our scope. |
4373 language_mode = scope->language_mode(); | 4258 language_mode = scope->language_mode(); |
4374 | 4259 |
4375 if (is_strong(language_mode) && IsSubclassConstructor(kind)) { | |
4376 if (!function_state.super_location().IsValid()) { | |
4377 ReportMessageAt(function_name_location, | |
4378 MessageTemplate::kStrongSuperCallMissing, | |
4379 kReferenceError); | |
4380 *ok = false; | |
4381 return nullptr; | |
4382 } | |
4383 } | |
4384 | |
4385 // Validate name and parameter names. We can do this only after parsing the | 4260 // Validate name and parameter names. We can do this only after parsing the |
4386 // function, since the function can declare itself strict. | 4261 // function, since the function can declare itself strict. |
4387 CheckFunctionName(language_mode, function_name, function_name_validity, | 4262 CheckFunctionName(language_mode, function_name, function_name_validity, |
4388 function_name_location, CHECK_OK); | 4263 function_name_location, CHECK_OK); |
4389 const bool allow_duplicate_parameters = | 4264 const bool allow_duplicate_parameters = |
4390 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); | 4265 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); |
4391 ValidateFormalParameters(&formals_classifier, language_mode, | 4266 ValidateFormalParameters(&formals_classifier, language_mode, |
4392 allow_duplicate_parameters, CHECK_OK); | 4267 allow_duplicate_parameters, CHECK_OK); |
4393 | 4268 |
4394 if (is_strict(language_mode)) { | 4269 if (is_strict(language_mode)) { |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4816 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), | 4691 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), |
4817 NULL, stack_limit_); | 4692 NULL, stack_limit_); |
4818 reusable_preparser_->set_allow_lazy(true); | 4693 reusable_preparser_->set_allow_lazy(true); |
4819 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); | 4694 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); |
4820 SET_ALLOW(natives); | 4695 SET_ALLOW(natives); |
4821 SET_ALLOW(harmony_sloppy); | 4696 SET_ALLOW(harmony_sloppy); |
4822 SET_ALLOW(harmony_sloppy_let); | 4697 SET_ALLOW(harmony_sloppy_let); |
4823 SET_ALLOW(harmony_default_parameters); | 4698 SET_ALLOW(harmony_default_parameters); |
4824 SET_ALLOW(harmony_destructuring_bind); | 4699 SET_ALLOW(harmony_destructuring_bind); |
4825 SET_ALLOW(harmony_destructuring_assignment); | 4700 SET_ALLOW(harmony_destructuring_assignment); |
4826 SET_ALLOW(strong_mode); | |
4827 SET_ALLOW(harmony_do_expressions); | 4701 SET_ALLOW(harmony_do_expressions); |
4828 SET_ALLOW(harmony_function_name); | 4702 SET_ALLOW(harmony_function_name); |
4829 SET_ALLOW(harmony_function_sent); | 4703 SET_ALLOW(harmony_function_sent); |
4830 #undef SET_ALLOW | 4704 #undef SET_ALLOW |
4831 } | 4705 } |
4832 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( | 4706 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( |
4833 language_mode(), function_state_->kind(), scope_->has_simple_parameters(), | 4707 language_mode(), function_state_->kind(), scope_->has_simple_parameters(), |
4834 logger, bookmark); | 4708 logger, bookmark); |
4835 if (pre_parse_timer_ != NULL) { | 4709 if (pre_parse_timer_ != NULL) { |
4836 pre_parse_timer_->Stop(); | 4710 pre_parse_timer_->Stop(); |
(...skipping 11 matching lines...) Expand all Loading... |
4848 ReportMessageAt(class_name_location, | 4722 ReportMessageAt(class_name_location, |
4849 MessageTemplate::kUnexpectedStrictReserved); | 4723 MessageTemplate::kUnexpectedStrictReserved); |
4850 *ok = false; | 4724 *ok = false; |
4851 return NULL; | 4725 return NULL; |
4852 } | 4726 } |
4853 if (IsEvalOrArguments(name)) { | 4727 if (IsEvalOrArguments(name)) { |
4854 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments); | 4728 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments); |
4855 *ok = false; | 4729 *ok = false; |
4856 return NULL; | 4730 return NULL; |
4857 } | 4731 } |
4858 if (is_strong(language_mode()) && IsUndefined(name)) { | |
4859 ReportMessageAt(class_name_location, MessageTemplate::kStrongUndefined); | |
4860 *ok = false; | |
4861 return NULL; | |
4862 } | |
4863 | 4732 |
4864 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); | 4733 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); |
4865 BlockState block_state(&scope_, block_scope); | 4734 BlockState block_state(&scope_, block_scope); |
4866 RaiseLanguageMode(STRICT); | 4735 RaiseLanguageMode(STRICT); |
4867 scope_->SetScopeName(name); | 4736 scope_->SetScopeName(name); |
4868 | 4737 |
4869 VariableProxy* proxy = NULL; | 4738 VariableProxy* proxy = NULL; |
4870 if (name != NULL) { | 4739 if (name != NULL) { |
4871 proxy = NewUnresolved(name, CONST); | 4740 proxy = NewUnresolved(name, CONST); |
4872 Declaration* declaration = | 4741 Declaration* declaration = |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4925 } | 4794 } |
4926 | 4795 |
4927 Expect(Token::RBRACE, CHECK_OK); | 4796 Expect(Token::RBRACE, CHECK_OK); |
4928 int end_pos = scanner()->location().end_pos; | 4797 int end_pos = scanner()->location().end_pos; |
4929 | 4798 |
4930 if (constructor == NULL) { | 4799 if (constructor == NULL) { |
4931 constructor = DefaultConstructor(name, extends != NULL, block_scope, pos, | 4800 constructor = DefaultConstructor(name, extends != NULL, block_scope, pos, |
4932 end_pos, block_scope->language_mode()); | 4801 end_pos, block_scope->language_mode()); |
4933 } | 4802 } |
4934 | 4803 |
4935 // Note that we do not finalize this block scope because strong | 4804 // Note that we do not finalize this block scope because it is |
4936 // mode uses it as a sentinel value indicating an anonymous class. | 4805 // used as a sentinel value indicating an anonymous class. |
4937 block_scope->set_end_position(end_pos); | 4806 block_scope->set_end_position(end_pos); |
4938 | 4807 |
4939 if (name != NULL) { | 4808 if (name != NULL) { |
4940 DCHECK_NOT_NULL(proxy); | 4809 DCHECK_NOT_NULL(proxy); |
4941 proxy->var()->set_initializer_position(end_pos); | 4810 proxy->var()->set_initializer_position(end_pos); |
4942 } | 4811 } |
4943 | 4812 |
4944 return factory()->NewClassLiteral(block_scope, proxy, extends, constructor, | 4813 return factory()->NewClassLiteral(block_scope, proxy, extends, constructor, |
4945 properties, pos, end_pos); | 4814 properties, pos, end_pos); |
4946 } | 4815 } |
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5496 args->InsertAt(0, function, zone()); | 5365 args->InsertAt(0, function, zone()); |
5497 | 5366 |
5498 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos); | 5367 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos); |
5499 } | 5368 } |
5500 | 5369 |
5501 | 5370 |
5502 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) { | 5371 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) { |
5503 v8::Isolate::UseCounterFeature feature; | 5372 v8::Isolate::UseCounterFeature feature; |
5504 if (is_sloppy(mode)) | 5373 if (is_sloppy(mode)) |
5505 feature = v8::Isolate::kSloppyMode; | 5374 feature = v8::Isolate::kSloppyMode; |
5506 else if (is_strong(mode)) | |
5507 feature = v8::Isolate::kStrongMode; | |
5508 else if (is_strict(mode)) | 5375 else if (is_strict(mode)) |
5509 feature = v8::Isolate::kStrictMode; | 5376 feature = v8::Isolate::kStrictMode; |
5510 else | 5377 else |
5511 UNREACHABLE(); | 5378 UNREACHABLE(); |
5512 ++use_counts_[feature]; | 5379 ++use_counts_[feature]; |
5513 scope->SetLanguageMode(mode); | 5380 scope->SetLanguageMode(mode); |
5514 } | 5381 } |
5515 | 5382 |
5516 | 5383 |
5517 void Parser::RaiseLanguageMode(LanguageMode mode) { | 5384 void Parser::RaiseLanguageMode(LanguageMode mode) { |
5518 SetLanguageMode(scope_, | 5385 LanguageMode old = scope_->language_mode(); |
5519 static_cast<LanguageMode>(scope_->language_mode() | mode)); | 5386 SetLanguageMode(scope_, old > mode ? old : mode); |
5520 } | 5387 } |
5521 | 5388 |
5522 | 5389 |
5523 void ParserTraits::RewriteDestructuringAssignments() { | 5390 void ParserTraits::RewriteDestructuringAssignments() { |
5524 parser_->RewriteDestructuringAssignments(); | 5391 parser_->RewriteDestructuringAssignments(); |
5525 } | 5392 } |
5526 | 5393 |
5527 | 5394 |
5528 void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, | 5395 void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, |
5529 bool* ok) { | 5396 bool* ok) { |
(...skipping 1408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6938 try_block, target); | 6805 try_block, target); |
6939 final_loop = target; | 6806 final_loop = target; |
6940 } | 6807 } |
6941 | 6808 |
6942 return final_loop; | 6809 return final_loop; |
6943 } | 6810 } |
6944 | 6811 |
6945 | 6812 |
6946 } // namespace internal | 6813 } // namespace internal |
6947 } // namespace v8 | 6814 } // namespace v8 |
OLD | NEW |