OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 <cmath> | 5 #include <cmath> |
6 | 6 |
7 #include "src/allocation.h" | 7 #include "src/allocation.h" |
8 #include "src/base/logging.h" | 8 #include "src/base/logging.h" |
9 #include "src/conversions-inl.h" | 9 #include "src/conversions-inl.h" |
10 #include "src/conversions.h" | 10 #include "src/conversions.h" |
11 #include "src/globals.h" | 11 #include "src/globals.h" |
12 #include "src/list.h" | 12 #include "src/list.h" |
13 #include "src/parsing/parser-base.h" | 13 #include "src/parsing/parser-base.h" |
14 #include "src/parsing/preparse-data-format.h" | 14 #include "src/parsing/preparse-data-format.h" |
15 #include "src/parsing/preparse-data.h" | 15 #include "src/parsing/preparse-data.h" |
16 #include "src/parsing/preparser.h" | 16 #include "src/parsing/preparser.h" |
17 #include "src/unicode.h" | 17 #include "src/unicode.h" |
18 #include "src/utils.h" | 18 #include "src/utils.h" |
19 | 19 |
20 namespace v8 { | 20 namespace v8 { |
21 namespace internal { | 21 namespace internal { |
22 | 22 |
| 23 // ---------------------------------------------------------------------------- |
| 24 // The CHECK_OK macro is a convenient macro to enforce error |
| 25 // handling for functions that may fail (by returning !*ok). |
| 26 // |
| 27 // CAUTION: This macro appends extra statements after a call, |
| 28 // thus it must never be used where only a single statement |
| 29 // is correct (e.g. an if statement branch w/o braces)! |
| 30 |
| 31 #define CHECK_OK ok); \ |
| 32 if (!*ok) return Statement::Default(); \ |
| 33 ((void)0 |
| 34 #define DUMMY ) // to make indentation work |
| 35 #undef DUMMY |
| 36 |
| 37 // Used in functions where the return type is not ExpressionT. |
| 38 #define CHECK_OK_CUSTOM(x) ok); \ |
| 39 if (!*ok) return this->x(); \ |
| 40 ((void)0 |
| 41 #define DUMMY ) // to make indentation work |
| 42 #undef DUMMY |
| 43 |
23 void PreParserTraits::ReportMessageAt(Scanner::Location location, | 44 void PreParserTraits::ReportMessageAt(Scanner::Location location, |
24 MessageTemplate::Template message, | 45 MessageTemplate::Template message, |
25 const char* arg, | 46 const char* arg, |
26 ParseErrorType error_type) { | 47 ParseErrorType error_type) { |
27 ReportMessageAt(location.beg_pos, location.end_pos, message, arg, error_type); | 48 ReportMessageAt(location.beg_pos, location.end_pos, message, arg, error_type); |
28 } | 49 } |
29 | 50 |
30 | 51 |
31 void PreParserTraits::ReportMessageAt(int start_pos, int end_pos, | 52 void PreParserTraits::ReportMessageAt(int start_pos, int end_pos, |
32 MessageTemplate::Template message, | 53 MessageTemplate::Template message, |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 bool maybe_reset = bookmark != nullptr; | 240 bool maybe_reset = bookmark != nullptr; |
220 int count_statements = 0; | 241 int count_statements = 0; |
221 | 242 |
222 bool directive_prologue = true; | 243 bool directive_prologue = true; |
223 while (peek() != end_token) { | 244 while (peek() != end_token) { |
224 if (directive_prologue && peek() != Token::STRING) { | 245 if (directive_prologue && peek() != Token::STRING) { |
225 directive_prologue = false; | 246 directive_prologue = false; |
226 } | 247 } |
227 bool starts_with_identifier = peek() == Token::IDENTIFIER; | 248 bool starts_with_identifier = peek() == Token::IDENTIFIER; |
228 Scanner::Location token_loc = scanner()->peek_location(); | 249 Scanner::Location token_loc = scanner()->peek_location(); |
229 Statement statement = ParseStatementListItem(ok); | 250 Statement statement = ParseStatementListItem(CHECK_OK_CUSTOM(Void)); |
230 if (!*ok) return; | |
231 | 251 |
232 if (directive_prologue) { | 252 if (directive_prologue) { |
233 bool use_strict_found = statement.IsUseStrictLiteral(); | 253 bool use_strict_found = statement.IsUseStrictLiteral(); |
234 | 254 |
235 if (use_strict_found) { | 255 if (use_strict_found) { |
236 scope_->SetLanguageMode( | 256 scope_->SetLanguageMode( |
237 static_cast<LanguageMode>(scope_->language_mode() | STRICT)); | 257 static_cast<LanguageMode>(scope_->language_mode() | STRICT)); |
238 } else if (!statement.IsStringLiteral()) { | 258 } else if (!statement.IsStringLiteral()) { |
239 directive_prologue = false; | 259 directive_prologue = false; |
240 } | 260 } |
(...skipping 20 matching lines...) Expand all Loading... |
261 if (count_statements > kLazyParseTrialLimit) { | 281 if (count_statements > kLazyParseTrialLimit) { |
262 bookmark->Reset(); | 282 bookmark->Reset(); |
263 return; | 283 return; |
264 } | 284 } |
265 maybe_reset = false; | 285 maybe_reset = false; |
266 } | 286 } |
267 } | 287 } |
268 } | 288 } |
269 | 289 |
270 | 290 |
271 #define CHECK_OK ok); \ | |
272 if (!*ok) return Statement::Default(); \ | |
273 ((void)0 | |
274 #define DUMMY ) // to make indentation work | |
275 #undef DUMMY | |
276 | |
277 PreParser::Statement PreParser::ParseStatement( | 291 PreParser::Statement PreParser::ParseStatement( |
278 AllowLabelledFunctionStatement allow_function, bool* ok) { | 292 AllowLabelledFunctionStatement allow_function, bool* ok) { |
279 // Statement :: | 293 // Statement :: |
280 // EmptyStatement | 294 // EmptyStatement |
281 // ... | 295 // ... |
282 | 296 |
283 if (peek() == Token::SEMICOLON) { | 297 if (peek() == Token::SEMICOLON) { |
284 Next(); | 298 Next(); |
285 return Statement::Default(); | 299 return Statement::Default(); |
286 } | 300 } |
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
911 ReturnExprContext::kInsideForInOfBody); | 925 ReturnExprContext::kInsideForInOfBody); |
912 ParseScopedStatement(true, CHECK_OK); | 926 ParseScopedStatement(true, CHECK_OK); |
913 } | 927 } |
914 return Statement::Default(); | 928 return Statement::Default(); |
915 } | 929 } |
916 } else { | 930 } else { |
917 int lhs_beg_pos = peek_position(); | 931 int lhs_beg_pos = peek_position(); |
918 ExpressionClassifier classifier(this); | 932 ExpressionClassifier classifier(this); |
919 Expression lhs = ParseExpression(false, &classifier, CHECK_OK); | 933 Expression lhs = ParseExpression(false, &classifier, CHECK_OK); |
920 int lhs_end_pos = scanner()->location().end_pos; | 934 int lhs_end_pos = scanner()->location().end_pos; |
921 bool is_for_each = CheckInOrOf(&mode, ok); | 935 bool is_for_each = CheckInOrOf(&mode, CHECK_OK); |
922 if (!*ok) return Statement::Default(); | |
923 bool is_destructuring = is_for_each && | 936 bool is_destructuring = is_for_each && |
924 (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()); | 937 (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()); |
925 | 938 |
926 if (is_destructuring) { | 939 if (is_destructuring) { |
927 ValidateAssignmentPattern(&classifier, CHECK_OK); | 940 ValidateAssignmentPattern(&classifier, CHECK_OK); |
928 } else { | 941 } else { |
929 ValidateExpression(&classifier, CHECK_OK); | 942 ValidateExpression(&classifier, CHECK_OK); |
930 } | 943 } |
931 | 944 |
932 if (is_for_each) { | 945 if (is_for_each) { |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1071 // break point is present. | 1084 // break point is present. |
1072 // DebuggerStatement :: | 1085 // DebuggerStatement :: |
1073 // 'debugger' ';' | 1086 // 'debugger' ';' |
1074 | 1087 |
1075 Expect(Token::DEBUGGER, CHECK_OK); | 1088 Expect(Token::DEBUGGER, CHECK_OK); |
1076 ExpectSemicolon(ok); | 1089 ExpectSemicolon(ok); |
1077 return Statement::Default(); | 1090 return Statement::Default(); |
1078 } | 1091 } |
1079 | 1092 |
1080 | 1093 |
| 1094 // Redefinition of CHECK_OK for parsing expressions. |
1081 #undef CHECK_OK | 1095 #undef CHECK_OK |
1082 #define CHECK_OK ok); \ | 1096 #define CHECK_OK ok); \ |
1083 if (!*ok) return Expression::Default(); \ | 1097 if (!*ok) return Expression::Default(); \ |
1084 ((void)0 | 1098 ((void)0 |
1085 #define DUMMY ) // to make indentation work | 1099 #define DUMMY ) // to make indentation work |
1086 #undef DUMMY | 1100 #undef DUMMY |
1087 | 1101 |
1088 | 1102 |
1089 PreParser::Expression PreParser::ParseFunctionLiteral( | 1103 PreParser::Expression PreParser::ParseFunctionLiteral( |
1090 Identifier function_name, Scanner::Location function_name_location, | 1104 Identifier function_name, Scanner::Location function_name_location, |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1294 Expect(Token::RBRACE, CHECK_OK); | 1308 Expect(Token::RBRACE, CHECK_OK); |
1295 return PreParserExpression::Default(); | 1309 return PreParserExpression::Default(); |
1296 } | 1310 } |
1297 | 1311 |
1298 void PreParserTraits::ParseAsyncArrowSingleExpressionBody( | 1312 void PreParserTraits::ParseAsyncArrowSingleExpressionBody( |
1299 PreParserStatementList body, bool accept_IN, | 1313 PreParserStatementList body, bool accept_IN, |
1300 Type::ExpressionClassifier* classifier, int pos, bool* ok) { | 1314 Type::ExpressionClassifier* classifier, int pos, bool* ok) { |
1301 Scope* scope = pre_parser_->scope_; | 1315 Scope* scope = pre_parser_->scope_; |
1302 scope->ForceContextAllocation(); | 1316 scope->ForceContextAllocation(); |
1303 | 1317 |
1304 PreParserExpression return_value = | 1318 PreParserExpression return_value = pre_parser_->ParseAssignmentExpression( |
1305 pre_parser_->ParseAssignmentExpression(accept_IN, classifier, ok); | 1319 accept_IN, classifier, CHECK_OK_CUSTOM(Void)); |
1306 if (!*ok) return; | |
1307 | 1320 |
1308 body->Add(PreParserStatement::ExpressionStatement(return_value), zone()); | 1321 body->Add(PreParserStatement::ExpressionStatement(return_value), zone()); |
1309 } | 1322 } |
1310 | 1323 |
1311 #undef CHECK_OK | 1324 #undef CHECK_OK |
| 1325 #undef CHECK_OK_CUSTOM |
1312 | 1326 |
1313 | 1327 |
1314 } // namespace internal | 1328 } // namespace internal |
1315 } // namespace v8 | 1329 } // namespace v8 |
OLD | NEW |