| 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 |