| 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" |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 *ok = false; | 157 *ok = false; |
| 158 return Statement::Default(); | 158 return Statement::Default(); |
| 159 } | 159 } |
| 160 } | 160 } |
| 161 // PreParser is not able to parse "export default" yet (since PreParser is | 161 // PreParser is not able to parse "export default" yet (since PreParser is |
| 162 // at the moment only used for functions, and it cannot occur | 162 // at the moment only used for functions, and it cannot occur |
| 163 // there). TODO(marja): update this when it is. | 163 // there). TODO(marja): update this when it is. |
| 164 return ParseHoistableDeclaration(pos, flags, nullptr, false, ok); | 164 return ParseHoistableDeclaration(pos, flags, nullptr, false, ok); |
| 165 } | 165 } |
| 166 | 166 |
| 167 PreParser::Statement PreParser::ParseForStatement( | |
| 168 ZoneList<const AstRawString*>* labels, bool* ok) { | |
| 169 // ForStatement :: | |
| 170 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | |
| 171 | |
| 172 // Create an in-between scope for let-bound iteration variables. | |
| 173 bool has_lexical = false; | |
| 174 | |
| 175 BlockState block_state(&scope_state_); | |
| 176 Expect(Token::FOR, CHECK_OK); | |
| 177 Expect(Token::LPAREN, CHECK_OK); | |
| 178 if (peek() != Token::SEMICOLON) { | |
| 179 ForEachStatement::VisitMode mode; | |
| 180 if (peek() == Token::VAR || peek() == Token::CONST || | |
| 181 (peek() == Token::LET && IsNextLetKeyword())) { | |
| 182 DeclarationParsingResult parsing_result; | |
| 183 | |
| 184 ParseVariableDeclarations(kForStatement, &parsing_result, nullptr, | |
| 185 CHECK_OK); | |
| 186 if (parsing_result.descriptor.mode == CONST || | |
| 187 parsing_result.descriptor.mode == LET) { | |
| 188 has_lexical = true; | |
| 189 } | |
| 190 if (CheckInOrOf(&mode)) { | |
| 191 if (!*ok) return Statement::Default(); | |
| 192 if (parsing_result.declarations.length() != 1) { | |
| 193 ReportMessageAt(parsing_result.bindings_loc, | |
| 194 MessageTemplate::kForInOfLoopMultiBindings, | |
| 195 ForEachStatement::VisitModeString(mode)); | |
| 196 *ok = false; | |
| 197 return Statement::Default(); | |
| 198 } | |
| 199 bool is_binding_pattern = | |
| 200 parsing_result.declarations[0].pattern.IsObjectLiteral() || | |
| 201 parsing_result.declarations[0].pattern.IsArrayLiteral(); | |
| 202 if (parsing_result.first_initializer_loc.IsValid() && | |
| 203 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE || | |
| 204 has_lexical || is_binding_pattern || allow_harmony_for_in())) { | |
| 205 // Only increment the use count if we would have let this through | |
| 206 // without the flag. | |
| 207 if (use_counts_ != nullptr && allow_harmony_for_in()) { | |
| 208 ++use_counts_[v8::Isolate::kForInInitializer]; | |
| 209 } | |
| 210 ReportMessageAt(parsing_result.first_initializer_loc, | |
| 211 MessageTemplate::kForInOfLoopInitializer, | |
| 212 ForEachStatement::VisitModeString(mode)); | |
| 213 *ok = false; | |
| 214 return Statement::Default(); | |
| 215 } | |
| 216 | |
| 217 if (mode == ForEachStatement::ITERATE) { | |
| 218 ExpressionClassifier classifier(this); | |
| 219 ParseAssignmentExpression(true, CHECK_OK); | |
| 220 RewriteNonPattern(CHECK_OK); | |
| 221 } else { | |
| 222 ParseExpression(true, CHECK_OK); | |
| 223 } | |
| 224 | |
| 225 Expect(Token::RPAREN, CHECK_OK); | |
| 226 { | |
| 227 ReturnExprScope no_tail_calls(function_state_, | |
| 228 ReturnExprContext::kInsideForInOfBody); | |
| 229 ParseScopedStatement(nullptr, true, CHECK_OK); | |
| 230 } | |
| 231 return Statement::Default(); | |
| 232 } | |
| 233 } else { | |
| 234 int lhs_beg_pos = peek_position(); | |
| 235 ExpressionClassifier classifier(this); | |
| 236 Expression lhs = ParseExpressionCoverGrammar(false, CHECK_OK); | |
| 237 int lhs_end_pos = scanner()->location().end_pos; | |
| 238 bool is_for_each = CheckInOrOf(&mode); | |
| 239 bool is_destructuring = is_for_each && | |
| 240 (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()); | |
| 241 | |
| 242 if (is_destructuring) { | |
| 243 ValidateAssignmentPattern(CHECK_OK); | |
| 244 } else { | |
| 245 ValidateExpression(CHECK_OK); | |
| 246 } | |
| 247 | |
| 248 if (is_for_each) { | |
| 249 if (!is_destructuring) { | |
| 250 lhs = CheckAndRewriteReferenceExpression( | |
| 251 lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor, | |
| 252 kSyntaxError, CHECK_OK); | |
| 253 } | |
| 254 | |
| 255 if (mode == ForEachStatement::ITERATE) { | |
| 256 ExpressionClassifier classifier(this); | |
| 257 ParseAssignmentExpression(true, CHECK_OK); | |
| 258 RewriteNonPattern(CHECK_OK); | |
| 259 } else { | |
| 260 ParseExpression(true, CHECK_OK); | |
| 261 } | |
| 262 | |
| 263 Expect(Token::RPAREN, CHECK_OK); | |
| 264 { | |
| 265 BlockState block_state(&scope_state_); | |
| 266 ParseScopedStatement(nullptr, true, CHECK_OK); | |
| 267 } | |
| 268 return Statement::Default(); | |
| 269 } | |
| 270 } | |
| 271 } | |
| 272 | |
| 273 // Parsed initializer at this point. | |
| 274 Expect(Token::SEMICOLON, CHECK_OK); | |
| 275 | |
| 276 // If there are let bindings, then condition and the next statement of the | |
| 277 // for loop must be parsed in a new scope. | |
| 278 Scope* inner_scope = scope(); | |
| 279 // TODO(verwaest): Allocate this through a ScopeState as well. | |
| 280 if (has_lexical) inner_scope = NewScopeWithParent(inner_scope, BLOCK_SCOPE); | |
| 281 | |
| 282 { | |
| 283 BlockState block_state(&scope_state_, inner_scope); | |
| 284 | |
| 285 if (peek() != Token::SEMICOLON) { | |
| 286 ParseExpression(true, CHECK_OK); | |
| 287 } | |
| 288 Expect(Token::SEMICOLON, CHECK_OK); | |
| 289 | |
| 290 if (peek() != Token::RPAREN) { | |
| 291 ParseExpression(true, CHECK_OK); | |
| 292 } | |
| 293 Expect(Token::RPAREN, CHECK_OK); | |
| 294 | |
| 295 ParseScopedStatement(nullptr, true, ok); | |
| 296 } | |
| 297 return Statement::Default(); | |
| 298 } | |
| 299 | |
| 300 | |
| 301 // Redefinition of CHECK_OK for parsing expressions. | 167 // Redefinition of CHECK_OK for parsing expressions. |
| 302 #undef CHECK_OK | 168 #undef CHECK_OK |
| 303 #define CHECK_OK CHECK_OK_VALUE(Expression::Default()) | 169 #define CHECK_OK CHECK_OK_VALUE(Expression::Default()) |
| 304 | 170 |
| 305 PreParser::Expression PreParser::ParseFunctionLiteral( | 171 PreParser::Expression PreParser::ParseFunctionLiteral( |
| 306 Identifier function_name, Scanner::Location function_name_location, | 172 Identifier function_name, Scanner::Location function_name_location, |
| 307 FunctionNameValidity function_name_validity, FunctionKind kind, | 173 FunctionNameValidity function_name_validity, FunctionKind kind, |
| 308 int function_token_pos, FunctionLiteral::FunctionType function_type, | 174 int function_token_pos, FunctionLiteral::FunctionType function_type, |
| 309 LanguageMode language_mode, bool* ok) { | 175 LanguageMode language_mode, bool* ok) { |
| 310 // Function :: | 176 // Function :: |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 | 339 |
| 474 body->Add(PreParserStatement::ExpressionStatement(return_value), zone()); | 340 body->Add(PreParserStatement::ExpressionStatement(return_value), zone()); |
| 475 } | 341 } |
| 476 | 342 |
| 477 #undef CHECK_OK | 343 #undef CHECK_OK |
| 478 #undef CHECK_OK_CUSTOM | 344 #undef CHECK_OK_CUSTOM |
| 479 | 345 |
| 480 | 346 |
| 481 } // namespace internal | 347 } // namespace internal |
| 482 } // namespace v8 | 348 } // namespace v8 |
| OLD | NEW |