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(scope_, 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 |
1255 // probably not a win. | 1211 // probably not a win. |
1256 if (scope_->is_eval_scope()) mode_ = PARSE_EAGERLY; | 1212 if (scope_->is_eval_scope()) mode_ = PARSE_EAGERLY; |
1257 } else if (literal->raw_value()->AsString() == | 1213 } else if (literal->raw_value()->AsString() == |
1258 ast_value_factory()->use_asm_string() && | 1214 ast_value_factory()->use_asm_string() && |
1259 token_loc.end_pos - token_loc.beg_pos == | 1215 token_loc.end_pos - token_loc.beg_pos == |
1260 ast_value_factory()->use_asm_string()->length() + 2) { | 1216 ast_value_factory()->use_asm_string()->length() + 2) { |
1261 // Store the usage count; The actual use counter on the isolate is | 1217 // Store the usage count; The actual use counter on the isolate is |
1262 // incremented after parsing is done. | 1218 // incremented after parsing is done. |
1263 ++use_counts_[v8::Isolate::kUseAsm]; | 1219 ++use_counts_[v8::Isolate::kUseAsm]; |
1264 scope_->SetAsmModule(); | 1220 scope_->SetAsmModule(); |
1265 } else { | 1221 } else { |
1266 // Should not change mode, but will increment UseCounter | 1222 // Should not change mode, but will increment UseCounter |
1267 // if appropriate. Ditto usages below. | 1223 // if appropriate. Ditto usages below. |
1268 RaiseLanguageMode(SLOPPY); | 1224 RaiseLanguageMode(scope_, SLOPPY); |
1269 } | 1225 } |
1270 } else { | 1226 } else { |
1271 // End of the directive prologue. | 1227 // End of the directive prologue. |
1272 directive_prologue = false; | 1228 directive_prologue = false; |
1273 RaiseLanguageMode(SLOPPY); | 1229 RaiseLanguageMode(scope_, SLOPPY); |
1274 } | 1230 } |
1275 } else { | 1231 } else { |
1276 RaiseLanguageMode(SLOPPY); | 1232 RaiseLanguageMode(scope_, SLOPPY); |
1277 } | 1233 } |
1278 | 1234 |
1279 body->Add(stat, zone()); | 1235 body->Add(stat, zone()); |
1280 } | 1236 } |
1281 | 1237 |
1282 return 0; | 1238 return 0; |
1283 } | 1239 } |
1284 | 1240 |
1285 | 1241 |
1286 Statement* Parser::ParseStatementListItem(bool* ok) { | 1242 Statement* Parser::ParseStatementListItem(bool* ok) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1334 | 1290 |
1335 void* Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) { | 1291 void* Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) { |
1336 // (Ecma 262 6th Edition, 15.2): | 1292 // (Ecma 262 6th Edition, 15.2): |
1337 // Module : | 1293 // Module : |
1338 // ModuleBody? | 1294 // ModuleBody? |
1339 // | 1295 // |
1340 // ModuleBody : | 1296 // ModuleBody : |
1341 // ModuleItem* | 1297 // ModuleItem* |
1342 | 1298 |
1343 DCHECK(scope_->is_module_scope()); | 1299 DCHECK(scope_->is_module_scope()); |
1344 RaiseLanguageMode(STRICT); | 1300 RaiseLanguageMode(scope_, STRICT); |
1345 | 1301 |
1346 while (peek() != Token::EOS) { | 1302 while (peek() != Token::EOS) { |
1347 Statement* stat = ParseModuleItem(CHECK_OK); | 1303 Statement* stat = ParseModuleItem(CHECK_OK); |
1348 if (stat && !stat->IsEmpty()) { | 1304 if (stat && !stat->IsEmpty()) { |
1349 body->Add(stat, zone()); | 1305 body->Add(stat, zone()); |
1350 } | 1306 } |
1351 } | 1307 } |
1352 | 1308 |
1353 // Check that all exports are bound. | 1309 // Check that all exports are bound. |
1354 ModuleDescriptor* descriptor = scope_->module(); | 1310 ModuleDescriptor* descriptor = scope_->module(); |
(...skipping 99 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 1468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4359 if (use_temp_zone) { | 4244 if (use_temp_zone) { |
4360 // If the preconditions are correct the function body should never be | 4245 // If the preconditions are correct the function body should never be |
4361 // accessed, but do this anyway for better behaviour if they're wrong. | 4246 // accessed, but do this anyway for better behaviour if they're wrong. |
4362 body = NULL; | 4247 body = NULL; |
4363 } | 4248 } |
4364 } | 4249 } |
4365 | 4250 |
4366 // Parsing the body may change the language mode in our scope. | 4251 // Parsing the body may change the language mode in our scope. |
4367 language_mode = scope->language_mode(); | 4252 language_mode = scope->language_mode(); |
4368 | 4253 |
4369 if (is_strong(language_mode) && IsSubclassConstructor(kind)) { | |
4370 if (!function_state.super_location().IsValid()) { | |
4371 ReportMessageAt(function_name_location, | |
4372 MessageTemplate::kStrongSuperCallMissing, | |
4373 kReferenceError); | |
4374 *ok = false; | |
4375 return nullptr; | |
4376 } | |
4377 } | |
4378 | |
4379 // Validate name and parameter names. We can do this only after parsing the | 4254 // Validate name and parameter names. We can do this only after parsing the |
4380 // function, since the function can declare itself strict. | 4255 // function, since the function can declare itself strict. |
4381 CheckFunctionName(language_mode, function_name, function_name_validity, | 4256 CheckFunctionName(language_mode, function_name, function_name_validity, |
4382 function_name_location, CHECK_OK); | 4257 function_name_location, CHECK_OK); |
4383 const bool allow_duplicate_parameters = | 4258 const bool allow_duplicate_parameters = |
4384 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); | 4259 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); |
4385 ValidateFormalParameters(&formals_classifier, language_mode, | 4260 ValidateFormalParameters(&formals_classifier, language_mode, |
4386 allow_duplicate_parameters, CHECK_OK); | 4261 allow_duplicate_parameters, CHECK_OK); |
4387 | 4262 |
4388 if (is_strict(language_mode)) { | 4263 if (is_strict(language_mode)) { |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4810 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), | 4685 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), |
4811 NULL, stack_limit_); | 4686 NULL, stack_limit_); |
4812 reusable_preparser_->set_allow_lazy(true); | 4687 reusable_preparser_->set_allow_lazy(true); |
4813 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); | 4688 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); |
4814 SET_ALLOW(natives); | 4689 SET_ALLOW(natives); |
4815 SET_ALLOW(harmony_sloppy); | 4690 SET_ALLOW(harmony_sloppy); |
4816 SET_ALLOW(harmony_sloppy_let); | 4691 SET_ALLOW(harmony_sloppy_let); |
4817 SET_ALLOW(harmony_default_parameters); | 4692 SET_ALLOW(harmony_default_parameters); |
4818 SET_ALLOW(harmony_destructuring_bind); | 4693 SET_ALLOW(harmony_destructuring_bind); |
4819 SET_ALLOW(harmony_destructuring_assignment); | 4694 SET_ALLOW(harmony_destructuring_assignment); |
4820 SET_ALLOW(strong_mode); | |
4821 SET_ALLOW(harmony_do_expressions); | 4695 SET_ALLOW(harmony_do_expressions); |
4822 SET_ALLOW(harmony_function_name); | 4696 SET_ALLOW(harmony_function_name); |
4823 SET_ALLOW(harmony_function_sent); | 4697 SET_ALLOW(harmony_function_sent); |
4824 #undef SET_ALLOW | 4698 #undef SET_ALLOW |
4825 } | 4699 } |
4826 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( | 4700 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( |
4827 language_mode(), function_state_->kind(), scope_->has_simple_parameters(), | 4701 language_mode(), function_state_->kind(), scope_->has_simple_parameters(), |
4828 logger, bookmark); | 4702 logger, bookmark); |
4829 if (pre_parse_timer_ != NULL) { | 4703 if (pre_parse_timer_ != NULL) { |
4830 pre_parse_timer_->Stop(); | 4704 pre_parse_timer_->Stop(); |
(...skipping 11 matching lines...) Expand all Loading... | |
4842 ReportMessageAt(class_name_location, | 4716 ReportMessageAt(class_name_location, |
4843 MessageTemplate::kUnexpectedStrictReserved); | 4717 MessageTemplate::kUnexpectedStrictReserved); |
4844 *ok = false; | 4718 *ok = false; |
4845 return NULL; | 4719 return NULL; |
4846 } | 4720 } |
4847 if (IsEvalOrArguments(name)) { | 4721 if (IsEvalOrArguments(name)) { |
4848 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments); | 4722 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments); |
4849 *ok = false; | 4723 *ok = false; |
4850 return NULL; | 4724 return NULL; |
4851 } | 4725 } |
4852 if (is_strong(language_mode()) && IsUndefined(name)) { | |
4853 ReportMessageAt(class_name_location, MessageTemplate::kStrongUndefined); | |
4854 *ok = false; | |
4855 return NULL; | |
4856 } | |
4857 | 4726 |
4858 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); | 4727 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); |
4859 BlockState block_state(&scope_, block_scope); | 4728 BlockState block_state(&scope_, block_scope); |
4860 RaiseLanguageMode(STRICT); | 4729 RaiseLanguageMode(scope_, STRICT); |
4861 scope_->SetScopeName(name); | 4730 scope_->SetScopeName(name); |
4862 | 4731 |
4863 VariableProxy* proxy = NULL; | 4732 VariableProxy* proxy = NULL; |
4864 if (name != NULL) { | 4733 if (name != NULL) { |
4865 proxy = NewUnresolved(name, CONST); | 4734 proxy = NewUnresolved(name, CONST); |
4866 Declaration* declaration = | 4735 Declaration* declaration = |
4867 factory()->NewVariableDeclaration(proxy, CONST, block_scope, pos); | 4736 factory()->NewVariableDeclaration(proxy, CONST, block_scope, pos); |
4868 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 4737 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
4869 } | 4738 } |
4870 | 4739 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4919 } | 4788 } |
4920 | 4789 |
4921 Expect(Token::RBRACE, CHECK_OK); | 4790 Expect(Token::RBRACE, CHECK_OK); |
4922 int end_pos = scanner()->location().end_pos; | 4791 int end_pos = scanner()->location().end_pos; |
4923 | 4792 |
4924 if (constructor == NULL) { | 4793 if (constructor == NULL) { |
4925 constructor = DefaultConstructor(name, extends != NULL, block_scope, pos, | 4794 constructor = DefaultConstructor(name, extends != NULL, block_scope, pos, |
4926 end_pos, block_scope->language_mode()); | 4795 end_pos, block_scope->language_mode()); |
4927 } | 4796 } |
4928 | 4797 |
4929 // Note that we do not finalize this block scope because strong | 4798 // Note that we do not finalize this block scope because it is |
4930 // mode uses it as a sentinel value indicating an anonymous class. | 4799 // used as a sentinel value indicating an anonymous class. |
4931 block_scope->set_end_position(end_pos); | 4800 block_scope->set_end_position(end_pos); |
4932 | 4801 |
4933 if (name != NULL) { | 4802 if (name != NULL) { |
4934 DCHECK_NOT_NULL(proxy); | 4803 DCHECK_NOT_NULL(proxy); |
4935 proxy->var()->set_initializer_position(end_pos); | 4804 proxy->var()->set_initializer_position(end_pos); |
4936 } | 4805 } |
4937 | 4806 |
4938 return factory()->NewClassLiteral(block_scope, proxy, extends, constructor, | 4807 return factory()->NewClassLiteral(block_scope, proxy, extends, constructor, |
4939 properties, pos, end_pos); | 4808 properties, pos, end_pos); |
4940 } | 4809 } |
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5490 args->InsertAt(0, function, zone()); | 5359 args->InsertAt(0, function, zone()); |
5491 | 5360 |
5492 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos); | 5361 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos); |
5493 } | 5362 } |
5494 | 5363 |
5495 | 5364 |
5496 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) { | 5365 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) { |
5497 v8::Isolate::UseCounterFeature feature; | 5366 v8::Isolate::UseCounterFeature feature; |
5498 if (is_sloppy(mode)) | 5367 if (is_sloppy(mode)) |
5499 feature = v8::Isolate::kSloppyMode; | 5368 feature = v8::Isolate::kSloppyMode; |
5500 else if (is_strong(mode)) | |
5501 feature = v8::Isolate::kStrongMode; | |
5502 else if (is_strict(mode)) | 5369 else if (is_strict(mode)) |
5503 feature = v8::Isolate::kStrictMode; | 5370 feature = v8::Isolate::kStrictMode; |
5504 else | 5371 else |
5505 UNREACHABLE(); | 5372 UNREACHABLE(); |
5506 ++use_counts_[feature]; | 5373 ++use_counts_[feature]; |
5507 scope->SetLanguageMode(mode); | 5374 scope->SetLanguageMode(mode); |
5508 } | 5375 } |
5509 | 5376 |
5510 | 5377 |
5511 void Parser::RaiseLanguageMode(LanguageMode mode) { | 5378 void Parser::RaiseLanguageMode(Scope* scope, LanguageMode mode) { |
adamk
2016/03/08 17:53:22
Not clear why this needed to change at all in this
rossberg
2016/03/10 10:41:19
Was supposed to be a clean-up to be consistent wit
adamk
2016/03/10 18:46:49
Yeah, I can see that, just my inclination in gener
| |
5512 SetLanguageMode(scope_, | 5379 LanguageMode old = scope->language_mode(); |
5513 static_cast<LanguageMode>(scope_->language_mode() | mode)); | 5380 SetLanguageMode(scope, old > mode ? old : mode); |
adamk
2016/03/08 17:53:22
Seems bad to rely on STRICT > SLOPPY (mathematical
rossberg
2016/03/10 10:41:19
That would be more brittle, and silently break if
| |
5514 } | 5381 } |
5515 | 5382 |
5516 | 5383 |
5517 void ParserTraits::RewriteDestructuringAssignments() { | 5384 void ParserTraits::RewriteDestructuringAssignments() { |
5518 parser_->RewriteDestructuringAssignments(); | 5385 parser_->RewriteDestructuringAssignments(); |
5519 } | 5386 } |
5520 | 5387 |
5521 | 5388 |
5522 void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, | 5389 void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, |
5523 bool* ok) { | 5390 bool* ok) { |
(...skipping 1406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6930 Expression* do_each = | 6797 Expression* do_each = |
6931 factory->NewDoExpression(new_assign_each, var_each, nopos); | 6798 factory->NewDoExpression(new_assign_each, var_each, nopos); |
6932 loop->set_assign_each(do_each); | 6799 loop->set_assign_each(do_each); |
6933 | 6800 |
6934 return final_loop; | 6801 return final_loop; |
6935 } | 6802 } |
6936 | 6803 |
6937 | 6804 |
6938 } // namespace internal | 6805 } // namespace internal |
6939 } // namespace v8 | 6806 } // namespace v8 |
OLD | NEW |