Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: src/parsing/preparser.cc

Issue 2307073002: [parser] Refactor of Parse*Statement*, part 1 (Closed)
Patch Set: Fix weird compilation bug with line continuation in comment Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« src/parsing/parser-base.h ('K') | « src/parsing/preparser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 // The PreParser checks that the syntax follows the grammar for JavaScript, 115 // The PreParser checks that the syntax follows the grammar for JavaScript,
116 // and collects some information about the program along the way. 116 // and collects some information about the program along the way.
117 // The grammar check is only performed in order to understand the program 117 // The grammar check is only performed in order to understand the program
118 // sufficiently to deduce some information about it, that can be used 118 // sufficiently to deduce some information about it, that can be used
119 // to speed up later parsing. Finding errors is not the goal of pre-parsing, 119 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
120 // rather it is to speed up properly written and correct programs. 120 // rather it is to speed up properly written and correct programs.
121 // That means that contextual checks (like a label being declared where 121 // That means that contextual checks (like a label being declared where
122 // it is used) are generally omitted. 122 // it is used) are generally omitted.
123 123
124 124
125 PreParser::Statement PreParser::ParseStatementListItem(bool* ok) {
126 // ECMA 262 6th Edition
127 // StatementListItem[Yield, Return] :
128 // Statement[?Yield, ?Return]
129 // Declaration[?Yield]
130 //
131 // Declaration[Yield] :
132 // HoistableDeclaration[?Yield]
133 // ClassDeclaration[?Yield]
134 // LexicalDeclaration[In, ?Yield]
135 //
136 // HoistableDeclaration[Yield, Default] :
137 // FunctionDeclaration[?Yield, ?Default]
138 // GeneratorDeclaration[?Yield, ?Default]
139 //
140 // LexicalDeclaration[In, Yield] :
141 // LetOrConst BindingList[?In, ?Yield] ;
142
143 switch (peek()) {
144 case Token::FUNCTION:
145 return ParseHoistableDeclaration(ok);
146 case Token::CLASS:
147 return ParseClassDeclaration(ok);
148 case Token::CONST:
149 return ParseVariableStatement(kStatementListItem, ok);
150 case Token::LET:
151 if (IsNextLetKeyword()) {
152 return ParseVariableStatement(kStatementListItem, ok);
153 }
154 break;
155 case Token::ASYNC:
156 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION &&
157 !scanner()->HasAnyLineTerminatorAfterNext()) {
158 Consume(Token::ASYNC);
159 return ParseAsyncFunctionDeclaration(ok);
160 }
161 /* falls through */
162 default:
163 break;
164 }
165 return ParseStatement(kAllowLabelledFunctionStatement, ok);
166 }
167
168 PreParser::LazyParsingResult PreParser::ParseStatementList(int end_token,
169 bool may_abort,
170 bool* ok) {
171 // SourceElements ::
172 // (Statement)* <end_token>
173
174 int count_statements = 0;
175
176 bool directive_prologue = true;
177 while (peek() != end_token) {
178 if (directive_prologue && peek() != Token::STRING) {
179 directive_prologue = false;
180 }
181 bool starts_with_identifier = peek() == Token::IDENTIFIER;
182 Scanner::Location token_loc = scanner()->peek_location();
183 Statement statement =
184 ParseStatementListItem(CHECK_OK_VALUE(kLazyParsingComplete));
185
186 if (directive_prologue) {
187 bool use_strict_found = statement.IsUseStrictLiteral();
188
189 if (use_strict_found) {
190 scope()->SetLanguageMode(
191 static_cast<LanguageMode>(scope()->language_mode() | STRICT));
192 } else if (!statement.IsStringLiteral()) {
193 directive_prologue = false;
194 }
195
196 if (use_strict_found && !scope()->HasSimpleParameters()) {
197 // TC39 deemed "use strict" directives to be an error when occurring
198 // in the body of a function with non-simple parameter list, on
199 // 29/7/2015. https://goo.gl/ueA7Ln
200 ReportMessageAt(token_loc,
201 MessageTemplate::kIllegalLanguageModeDirective,
202 "use strict");
203 *ok = false;
204 return kLazyParsingComplete;
205 }
206 }
207
208 // If we're allowed to reset to a bookmark, we will do so when we see a long
209 // and trivial function.
210 // Our current definition of 'long and trivial' is:
211 // - over 200 statements
212 // - all starting with an identifier (i.e., no if, for, while, etc.)
213 if (may_abort) {
214 if (!starts_with_identifier) {
215 may_abort = false;
216 } else if (++count_statements > kLazyParseTrialLimit) {
217 return kLazyParsingAborted;
218 }
219 }
220 }
221 return kLazyParsingComplete;
222 }
223
224
225 PreParser::Statement PreParser::ParseStatement(
226 AllowLabelledFunctionStatement allow_function, bool* ok) {
227 // Statement ::
228 // EmptyStatement
229 // ...
230
231 if (peek() == Token::SEMICOLON) {
232 Next();
233 return Statement::Default();
234 }
235 return ParseSubStatement(allow_function, ok);
236 }
237
238 PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) { 125 PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) {
239 if (is_strict(language_mode()) || peek() != Token::FUNCTION || 126 if (is_strict(language_mode()) || peek() != Token::FUNCTION ||
240 (legacy && allow_harmony_restrictive_declarations())) { 127 (legacy && allow_harmony_restrictive_declarations())) {
241 return ParseSubStatement(kDisallowLabelledFunctionStatement, ok); 128 return ParseStatement(nullptr, kDisallowLabelledFunctionStatement, ok);
242 } else { 129 } else {
243 BlockState block_state(&scope_state_); 130 BlockState block_state(&scope_state_);
244 return ParseFunctionDeclaration(ok); 131 return ParseFunctionDeclaration(ok);
245 } 132 }
246 } 133 }
247 134
248 PreParser::Statement PreParser::ParseSubStatement(
249 AllowLabelledFunctionStatement allow_function, bool* ok) {
250 // Statement ::
251 // Block
252 // VariableStatement
253 // EmptyStatement
254 // ExpressionStatement
255 // IfStatement
256 // IterationStatement
257 // ContinueStatement
258 // BreakStatement
259 // ReturnStatement
260 // WithStatement
261 // LabelledStatement
262 // SwitchStatement
263 // ThrowStatement
264 // TryStatement
265 // DebuggerStatement
266
267 // Note: Since labels can only be used by 'break' and 'continue'
268 // statements, which themselves are only valid within blocks,
269 // iterations or 'switch' statements (i.e., BreakableStatements),
270 // labels can be simply ignored in all other cases; except for
271 // trivial labeled break statements 'label: break label' which is
272 // parsed into an empty statement.
273
274 // Keep the source position of the statement
275 switch (peek()) {
276 case Token::LBRACE:
277 return ParseBlock(ok);
278
279 case Token::SEMICOLON:
280 Next();
281 return Statement::Default();
282
283 case Token::IF:
284 return ParseIfStatement(ok);
285
286 case Token::DO:
287 return ParseDoWhileStatement(ok);
288
289 case Token::WHILE:
290 return ParseWhileStatement(ok);
291
292 case Token::FOR:
293 return ParseForStatement(ok);
294
295 case Token::CONTINUE:
296 return ParseContinueStatement(ok);
297
298 case Token::BREAK:
299 return ParseBreakStatement(ok);
300
301 case Token::RETURN:
302 return ParseReturnStatement(ok);
303
304 case Token::WITH:
305 return ParseWithStatement(ok);
306
307 case Token::SWITCH:
308 return ParseSwitchStatement(ok);
309
310 case Token::THROW:
311 return ParseThrowStatement(ok);
312
313 case Token::TRY:
314 return ParseTryStatement(ok);
315
316 case Token::FUNCTION:
317 // FunctionDeclaration only allowed as a StatementListItem, not in
318 // an arbitrary Statement position. Exceptions such as
319 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
320 // are handled by calling ParseScopedStatement rather than
321 // ParseSubStatement directly.
322 ReportMessageAt(scanner()->peek_location(),
323 is_strict(language_mode())
324 ? MessageTemplate::kStrictFunction
325 : MessageTemplate::kSloppyFunction);
326 *ok = false;
327 return Statement::Default();
328
329 case Token::DEBUGGER:
330 return ParseDebuggerStatement(ok);
331
332 case Token::VAR:
333 return ParseVariableStatement(kStatement, ok);
334
335 default:
336 return ParseExpressionOrLabelledStatement(allow_function, ok);
337 }
338 }
339
340 PreParser::Statement PreParser::ParseHoistableDeclaration( 135 PreParser::Statement PreParser::ParseHoistableDeclaration(
341 int pos, ParseFunctionFlags flags, bool* ok) { 136 int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names,
137 bool default_export, bool* ok) {
342 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator; 138 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator;
343 const bool is_async = flags & ParseFunctionFlags::kIsAsync; 139 const bool is_async = flags & ParseFunctionFlags::kIsAsync;
344 DCHECK(!is_generator || !is_async); 140 DCHECK(!is_generator || !is_async);
345 141
346 bool is_strict_reserved = false; 142 bool is_strict_reserved = false;
347 Identifier name = ParseIdentifierOrStrictReservedWord( 143 Identifier name = ParseIdentifierOrStrictReservedWord(
348 &is_strict_reserved, CHECK_OK); 144 &is_strict_reserved, CHECK_OK);
349 145
350 ParseFunctionLiteral(name, scanner()->location(), 146 ParseFunctionLiteral(name, scanner()->location(),
351 is_strict_reserved ? kFunctionNameIsStrictReserved 147 is_strict_reserved ? kFunctionNameIsStrictReserved
352 : kFunctionNameValidityUnknown, 148 : kFunctionNameValidityUnknown,
353 is_generator ? FunctionKind::kGeneratorFunction 149 is_generator ? FunctionKind::kGeneratorFunction
354 : is_async ? FunctionKind::kAsyncFunction 150 : is_async ? FunctionKind::kAsyncFunction
355 : FunctionKind::kNormalFunction, 151 : FunctionKind::kNormalFunction,
356 pos, FunctionLiteral::kDeclaration, language_mode(), 152 pos, FunctionLiteral::kDeclaration, language_mode(),
357 CHECK_OK); 153 CHECK_OK);
358 return Statement::FunctionDeclaration(); 154 return Statement::FunctionDeclaration();
359 } 155 }
360 156
361 PreParser::Statement PreParser::ParseAsyncFunctionDeclaration(bool* ok) { 157 PreParser::Statement PreParser::ParseAsyncFunctionDeclaration(
158 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
362 // AsyncFunctionDeclaration :: 159 // AsyncFunctionDeclaration ::
363 // async [no LineTerminator here] function BindingIdentifier[Await] 160 // async [no LineTerminator here] function BindingIdentifier[Await]
364 // ( FormalParameters[Await] ) { AsyncFunctionBody } 161 // ( FormalParameters[Await] ) { AsyncFunctionBody }
365 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); 162 DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
366 int pos = position(); 163 int pos = position();
367 Expect(Token::FUNCTION, CHECK_OK); 164 Expect(Token::FUNCTION, CHECK_OK);
368 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync; 165 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync;
369 return ParseHoistableDeclaration(pos, flags, ok); 166 return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
370 } 167 }
371 168
372 PreParser::Statement PreParser::ParseHoistableDeclaration(bool* ok) { 169 PreParser::Statement PreParser::ParseHoistableDeclaration(
170 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
373 // FunctionDeclaration :: 171 // FunctionDeclaration ::
374 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 172 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
375 // GeneratorDeclaration :: 173 // GeneratorDeclaration ::
376 // 'function' '*' Identifier '(' FormalParameterListopt ')' 174 // 'function' '*' Identifier '(' FormalParameterListopt ')'
377 // '{' FunctionBody '}' 175 // '{' FunctionBody '}'
378 176
379 Expect(Token::FUNCTION, CHECK_OK); 177 Expect(Token::FUNCTION, CHECK_OK);
380 int pos = position(); 178 int pos = position();
381 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; 179 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
382 if (Check(Token::MUL)) { 180 if (Check(Token::MUL)) {
383 flags |= ParseFunctionFlags::kIsGenerator; 181 flags |= ParseFunctionFlags::kIsGenerator;
384 } 182 }
385 return ParseHoistableDeclaration(pos, flags, ok); 183 return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
386 } 184 }
387 185
388 186 PreParser::Statement PreParser::ParseClassDeclaration(
389 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) { 187 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
390 Expect(Token::CLASS, CHECK_OK);
391
392 int pos = position(); 188 int pos = position();
393 bool is_strict_reserved = false; 189 bool is_strict_reserved = false;
394 Identifier name = 190 Identifier name =
395 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 191 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
396 ExpressionClassifier no_classifier(this); 192 ExpressionClassifier no_classifier(this);
397 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos, 193 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos,
398 CHECK_OK); 194 CHECK_OK);
399 return Statement::Default(); 195 return Statement::Default();
400 } 196 }
401 197
402 198 PreParser::Statement PreParser::ParseBlock(
403 PreParser::Statement PreParser::ParseBlock(bool* ok) { 199 ZoneList<const AstRawString*>* labels, bool* ok) {
404 // Block :: 200 // Block ::
405 // '{' StatementList '}' 201 // '{' StatementList '}'
406 202
407 Expect(Token::LBRACE, CHECK_OK); 203 Expect(Token::LBRACE, CHECK_OK);
408 Statement final = Statement::Default(); 204 Statement final = Statement::Default();
409 { 205 {
410 BlockState block_state(&scope_state_); 206 BlockState block_state(&scope_state_);
411 while (peek() != Token::RBRACE) { 207 while (peek() != Token::RBRACE) {
412 final = ParseStatementListItem(CHECK_OK); 208 final = ParseStatementListItem(CHECK_OK);
413 } 209 }
414 } 210 }
415 Expect(Token::RBRACE, ok); 211 Expect(Token::RBRACE, ok);
416 return final; 212 return final;
417 } 213 }
418 214
419
420 PreParser::Statement PreParser::ParseVariableStatement( 215 PreParser::Statement PreParser::ParseVariableStatement(
421 VariableDeclarationContext var_context, 216 VariableDeclarationContext var_context,
422 bool* ok) { 217 ZoneList<const AstRawString*>* names, bool* ok) {
423 // VariableStatement :: 218 // VariableStatement ::
424 // VariableDeclarations ';' 219 // VariableDeclarations ';'
425 220
426 Statement result = 221 Statement result =
427 ParseVariableDeclarations(var_context, nullptr, nullptr, CHECK_OK); 222 ParseVariableDeclarations(var_context, nullptr, names, CHECK_OK);
428 ExpectSemicolon(CHECK_OK); 223 ExpectSemicolon(CHECK_OK);
429 return result; 224 return result;
430 } 225 }
431 226
432 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { 227 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
433 Consume(Token::FUNCTION); 228 Consume(Token::FUNCTION);
434 int pos = position(); 229 int pos = position();
435 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; 230 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
436 if (Check(Token::MUL)) { 231 if (Check(Token::MUL)) {
437 flags |= ParseFunctionFlags::kIsGenerator; 232 flags |= ParseFunctionFlags::kIsGenerator;
438 if (allow_harmony_restrictive_declarations()) { 233 if (allow_harmony_restrictive_declarations()) {
439 ReportMessageAt(scanner()->location(), 234 ReportMessageAt(scanner()->location(),
440 MessageTemplate::kGeneratorInLegacyContext); 235 MessageTemplate::kGeneratorInLegacyContext);
441 *ok = false; 236 *ok = false;
442 return Statement::Default(); 237 return Statement::Default();
443 } 238 }
444 } 239 }
445 return ParseHoistableDeclaration(pos, flags, ok); 240 return ParseHoistableDeclaration(pos, flags, nullptr, false, ok);
446 } 241 }
447 242
448 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement( 243 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(
244 ZoneList<const AstRawString*>* names,
449 AllowLabelledFunctionStatement allow_function, bool* ok) { 245 AllowLabelledFunctionStatement allow_function, bool* ok) {
450 // ExpressionStatement | LabelledStatement :: 246 // ExpressionStatement | LabelledStatement ::
451 // Expression ';' 247 // Expression ';'
452 // Identifier ':' Statement 248 // Identifier ':' Statement
453 249
454 switch (peek()) { 250 switch (peek()) {
455 case Token::FUNCTION: 251 case Token::FUNCTION:
456 case Token::LBRACE: 252 case Token::LBRACE:
457 UNREACHABLE(); // Always handled by the callers. 253 UNREACHABLE(); // Always handled by the callers.
458 case Token::CLASS: 254 case Token::CLASS:
(...skipping 23 matching lines...) Expand all
482 Consume(Token::COLON); 278 Consume(Token::COLON);
483 // ES#sec-labelled-function-declarations Labelled Function Declarations 279 // ES#sec-labelled-function-declarations Labelled Function Declarations
484 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) { 280 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) {
485 if (allow_function == kAllowLabelledFunctionStatement) { 281 if (allow_function == kAllowLabelledFunctionStatement) {
486 return ParseFunctionDeclaration(ok); 282 return ParseFunctionDeclaration(ok);
487 } else { 283 } else {
488 return ParseScopedStatement(true, ok); 284 return ParseScopedStatement(true, ok);
489 } 285 }
490 } 286 }
491 Statement statement = 287 Statement statement =
492 ParseStatement(kDisallowLabelledFunctionStatement, ok); 288 ParseStatement(nullptr, kDisallowLabelledFunctionStatement, ok);
493 return statement.IsJumpStatement() ? Statement::Default() : statement; 289 return statement.IsJumpStatement() ? Statement::Default() : statement;
494 // Preparsing is disabled for extensions (because the extension details 290 // Preparsing is disabled for extensions (because the extension details
495 // aren't passed to lazily compiled functions), so we don't 291 // aren't passed to lazily compiled functions), so we don't
496 // accept "native function" in the preparser. 292 // accept "native function" in the preparser.
497 } 293 }
498 // Parsed expression statement. 294 // Parsed expression statement.
499 ExpectSemicolon(CHECK_OK); 295 ExpectSemicolon(CHECK_OK);
500 return Statement::ExpressionStatement(expr); 296 return Statement::ExpressionStatement(expr);
501 } 297 }
502 298
503 299 PreParser::Statement PreParser::ParseIfStatement(
504 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { 300 ZoneList<const AstRawString*>* labels, bool* ok) {
505 // IfStatement :: 301 // IfStatement ::
506 // 'if' '(' Expression ')' Statement ('else' Statement)? 302 // 'if' '(' Expression ')' Statement ('else' Statement)?
507 303
508 Expect(Token::IF, CHECK_OK); 304 Expect(Token::IF, CHECK_OK);
509 Expect(Token::LPAREN, CHECK_OK); 305 Expect(Token::LPAREN, CHECK_OK);
510 ParseExpression(true, CHECK_OK); 306 ParseExpression(true, CHECK_OK);
511 Expect(Token::RPAREN, CHECK_OK); 307 Expect(Token::RPAREN, CHECK_OK);
512 Statement stat = ParseScopedStatement(false, CHECK_OK); 308 Statement stat = ParseScopedStatement(false, CHECK_OK);
513 if (peek() == Token::ELSE) { 309 if (peek() == Token::ELSE) {
514 Next(); 310 Next();
(...skipping 17 matching lines...) Expand all
532 tok != Token::SEMICOLON && 328 tok != Token::SEMICOLON &&
533 tok != Token::RBRACE && 329 tok != Token::RBRACE &&
534 tok != Token::EOS) { 330 tok != Token::EOS) {
535 // ECMA allows "eval" or "arguments" as labels even in strict mode. 331 // ECMA allows "eval" or "arguments" as labels even in strict mode.
536 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); 332 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
537 } 333 }
538 ExpectSemicolon(CHECK_OK); 334 ExpectSemicolon(CHECK_OK);
539 return Statement::Jump(); 335 return Statement::Jump();
540 } 336 }
541 337
542 338 PreParser::Statement PreParser::ParseBreakStatement(
543 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { 339 ZoneList<const AstRawString*>* labels, bool* ok) {
544 // BreakStatement :: 340 // BreakStatement ::
545 // 'break' [no line terminator] Identifier? ';' 341 // 'break' [no line terminator] Identifier? ';'
546 342
547 Expect(Token::BREAK, CHECK_OK); 343 Expect(Token::BREAK, CHECK_OK);
548 Token::Value tok = peek(); 344 Token::Value tok = peek();
549 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 345 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
550 tok != Token::SEMICOLON && 346 tok != Token::SEMICOLON &&
551 tok != Token::RBRACE && 347 tok != Token::RBRACE &&
552 tok != Token::EOS) { 348 tok != Token::EOS) {
553 // ECMA allows "eval" or "arguments" as labels even in strict mode. 349 // ECMA allows "eval" or "arguments" as labels even in strict mode.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 : ReturnExprContext::kInsideValidReturnStatement; 382 : ReturnExprContext::kInsideValidReturnStatement;
587 383
588 ReturnExprScope maybe_allow_tail_calls(function_state_, 384 ReturnExprScope maybe_allow_tail_calls(function_state_,
589 return_expr_context); 385 return_expr_context);
590 ParseExpression(true, CHECK_OK); 386 ParseExpression(true, CHECK_OK);
591 } 387 }
592 ExpectSemicolon(CHECK_OK); 388 ExpectSemicolon(CHECK_OK);
593 return Statement::Jump(); 389 return Statement::Jump();
594 } 390 }
595 391
596 392 PreParser::Statement PreParser::ParseWithStatement(
597 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { 393 ZoneList<const AstRawString*>* labels, bool* ok) {
598 // WithStatement :: 394 // WithStatement ::
599 // 'with' '(' Expression ')' Statement 395 // 'with' '(' Expression ')' Statement
600 Expect(Token::WITH, CHECK_OK); 396 Expect(Token::WITH, CHECK_OK);
601 if (is_strict(language_mode())) { 397 if (is_strict(language_mode())) {
602 ReportMessageAt(scanner()->location(), MessageTemplate::kStrictWith); 398 ReportMessageAt(scanner()->location(), MessageTemplate::kStrictWith);
603 *ok = false; 399 *ok = false;
604 return Statement::Default(); 400 return Statement::Default();
605 } 401 }
606 Expect(Token::LPAREN, CHECK_OK); 402 Expect(Token::LPAREN, CHECK_OK);
607 ParseExpression(true, CHECK_OK); 403 ParseExpression(true, CHECK_OK);
608 Expect(Token::RPAREN, CHECK_OK); 404 Expect(Token::RPAREN, CHECK_OK);
609 405
610 Scope* with_scope = NewScope(WITH_SCOPE); 406 Scope* with_scope = NewScope(WITH_SCOPE);
611 BlockState block_state(&scope_state_, with_scope); 407 BlockState block_state(&scope_state_, with_scope);
612 ParseScopedStatement(true, CHECK_OK); 408 ParseScopedStatement(true, CHECK_OK);
613 return Statement::Default(); 409 return Statement::Default();
614 } 410 }
615 411
616 412 PreParser::Statement PreParser::ParseSwitchStatement(
617 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) { 413 ZoneList<const AstRawString*>* labels, bool* ok) {
618 // SwitchStatement :: 414 // SwitchStatement ::
619 // 'switch' '(' Expression ')' '{' CaseClause* '}' 415 // 'switch' '(' Expression ')' '{' CaseClause* '}'
620 416
621 Expect(Token::SWITCH, CHECK_OK); 417 Expect(Token::SWITCH, CHECK_OK);
622 Expect(Token::LPAREN, CHECK_OK); 418 Expect(Token::LPAREN, CHECK_OK);
623 ParseExpression(true, CHECK_OK); 419 ParseExpression(true, CHECK_OK);
624 Expect(Token::RPAREN, CHECK_OK); 420 Expect(Token::RPAREN, CHECK_OK);
625 421
626 { 422 {
627 BlockState cases_block_state(&scope_state_); 423 BlockState cases_block_state(&scope_state_);
(...skipping 14 matching lines...) Expand all
642 token != Token::RBRACE) { 438 token != Token::RBRACE) {
643 statement = ParseStatementListItem(CHECK_OK); 439 statement = ParseStatementListItem(CHECK_OK);
644 token = peek(); 440 token = peek();
645 } 441 }
646 } 442 }
647 } 443 }
648 Expect(Token::RBRACE, ok); 444 Expect(Token::RBRACE, ok);
649 return Statement::Default(); 445 return Statement::Default();
650 } 446 }
651 447
652 448 PreParser::Statement PreParser::ParseDoWhileStatement(
653 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { 449 ZoneList<const AstRawString*>* labels, bool* ok) {
654 // DoStatement :: 450 // DoStatement ::
655 // 'do' Statement 'while' '(' Expression ')' ';' 451 // 'do' Statement 'while' '(' Expression ')' ';'
656 452
657 Expect(Token::DO, CHECK_OK); 453 Expect(Token::DO, CHECK_OK);
658 ParseScopedStatement(true, CHECK_OK); 454 ParseScopedStatement(true, CHECK_OK);
659 Expect(Token::WHILE, CHECK_OK); 455 Expect(Token::WHILE, CHECK_OK);
660 Expect(Token::LPAREN, CHECK_OK); 456 Expect(Token::LPAREN, CHECK_OK);
661 ParseExpression(true, CHECK_OK); 457 ParseExpression(true, CHECK_OK);
662 Expect(Token::RPAREN, ok); 458 Expect(Token::RPAREN, ok);
663 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); 459 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
664 return Statement::Default(); 460 return Statement::Default();
665 } 461 }
666 462
667 463 PreParser::Statement PreParser::ParseWhileStatement(
668 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) { 464 ZoneList<const AstRawString*>* labels, bool* ok) {
669 // WhileStatement :: 465 // WhileStatement ::
670 // 'while' '(' Expression ')' Statement 466 // 'while' '(' Expression ')' Statement
671 467
672 Expect(Token::WHILE, CHECK_OK); 468 Expect(Token::WHILE, CHECK_OK);
673 Expect(Token::LPAREN, CHECK_OK); 469 Expect(Token::LPAREN, CHECK_OK);
674 ParseExpression(true, CHECK_OK); 470 ParseExpression(true, CHECK_OK);
675 Expect(Token::RPAREN, CHECK_OK); 471 Expect(Token::RPAREN, CHECK_OK);
676 ParseScopedStatement(true, ok); 472 ParseScopedStatement(true, ok);
677 return Statement::Default(); 473 return Statement::Default();
678 } 474 }
679 475
680 476 PreParser::Statement PreParser::ParseForStatement(
681 PreParser::Statement PreParser::ParseForStatement(bool* ok) { 477 ZoneList<const AstRawString*>* labels, bool* ok) {
682 // ForStatement :: 478 // ForStatement ::
683 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 479 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
684 480
685 // Create an in-between scope for let-bound iteration variables. 481 // Create an in-between scope for let-bound iteration variables.
686 bool has_lexical = false; 482 bool has_lexical = false;
687 483
688 BlockState block_state(&scope_state_); 484 BlockState block_state(&scope_state_);
689 Expect(Token::FOR, CHECK_OK); 485 Expect(Token::FOR, CHECK_OK);
690 Expect(Token::LPAREN, CHECK_OK); 486 Expect(Token::LPAREN, CHECK_OK);
691 if (peek() != Token::SEMICOLON) { 487 if (peek() != Token::SEMICOLON) {
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 // 'catch' '(' Identifier ')' Block 633 // 'catch' '(' Identifier ')' Block
838 // 634 //
839 // Finally :: 635 // Finally ::
840 // 'finally' Block 636 // 'finally' Block
841 637
842 Expect(Token::TRY, CHECK_OK); 638 Expect(Token::TRY, CHECK_OK);
843 639
844 { 640 {
845 ReturnExprScope no_tail_calls(function_state_, 641 ReturnExprScope no_tail_calls(function_state_,
846 ReturnExprContext::kInsideTryBlock); 642 ReturnExprContext::kInsideTryBlock);
847 ParseBlock(CHECK_OK); 643 ParseBlock(nullptr, CHECK_OK);
848 } 644 }
849 645
850 Token::Value tok = peek(); 646 Token::Value tok = peek();
851 if (tok != Token::CATCH && tok != Token::FINALLY) { 647 if (tok != Token::CATCH && tok != Token::FINALLY) {
852 ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally); 648 ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally);
853 *ok = false; 649 *ok = false;
854 return Statement::Default(); 650 return Statement::Default();
855 } 651 }
856 TailCallExpressionList tail_call_expressions_in_catch_block(zone()); 652 TailCallExpressionList tail_call_expressions_in_catch_block(zone());
857 bool catch_block_exists = false; 653 bool catch_block_exists = false;
858 if (tok == Token::CATCH) { 654 if (tok == Token::CATCH) {
859 Consume(Token::CATCH); 655 Consume(Token::CATCH);
860 Expect(Token::LPAREN, CHECK_OK); 656 Expect(Token::LPAREN, CHECK_OK);
861 Scope* catch_scope = NewScope(CATCH_SCOPE); 657 Scope* catch_scope = NewScope(CATCH_SCOPE);
862 ExpressionClassifier pattern_classifier(this); 658 ExpressionClassifier pattern_classifier(this);
863 ParsePrimaryExpression(CHECK_OK); 659 ParsePrimaryExpression(CHECK_OK);
864 ValidateBindingPattern(CHECK_OK); 660 ValidateBindingPattern(CHECK_OK);
865 Expect(Token::RPAREN, CHECK_OK); 661 Expect(Token::RPAREN, CHECK_OK);
866 { 662 {
867 CollectExpressionsInTailPositionToListScope 663 CollectExpressionsInTailPositionToListScope
868 collect_tail_call_expressions_scope( 664 collect_tail_call_expressions_scope(
869 function_state_, &tail_call_expressions_in_catch_block); 665 function_state_, &tail_call_expressions_in_catch_block);
870 BlockState block_state(&scope_state_, catch_scope); 666 BlockState block_state(&scope_state_, catch_scope);
871 { 667 {
872 BlockState block_state(&scope_state_); 668 BlockState block_state(&scope_state_);
873 ParseBlock(CHECK_OK); 669 ParseBlock(nullptr, CHECK_OK);
874 } 670 }
875 } 671 }
876 catch_block_exists = true; 672 catch_block_exists = true;
877 tok = peek(); 673 tok = peek();
878 } 674 }
879 if (tok == Token::FINALLY) { 675 if (tok == Token::FINALLY) {
880 Consume(Token::FINALLY); 676 Consume(Token::FINALLY);
881 ParseBlock(CHECK_OK); 677 ParseBlock(nullptr, CHECK_OK);
882 if (FLAG_harmony_explicit_tailcalls && catch_block_exists && 678 if (FLAG_harmony_explicit_tailcalls && catch_block_exists &&
883 tail_call_expressions_in_catch_block.has_explicit_tail_calls()) { 679 tail_call_expressions_in_catch_block.has_explicit_tail_calls()) {
884 // TODO(ishell): update chapter number. 680 // TODO(ishell): update chapter number.
885 // ES8 XX.YY.ZZ 681 // ES8 XX.YY.ZZ
886 ReportMessageAt(tail_call_expressions_in_catch_block.location(), 682 ReportMessageAt(tail_call_expressions_in_catch_block.location(),
887 MessageTemplate::kUnexpectedTailCallInCatchBlock); 683 MessageTemplate::kUnexpectedTailCallInCatchBlock);
888 *ok = false; 684 *ok = false;
889 return Statement::Default(); 685 return Statement::Default();
890 } 686 }
891 } 687 }
(...skipping 20 matching lines...) Expand all
912 708
913 PreParser::Expression PreParser::ParseFunctionLiteral( 709 PreParser::Expression PreParser::ParseFunctionLiteral(
914 Identifier function_name, Scanner::Location function_name_location, 710 Identifier function_name, Scanner::Location function_name_location,
915 FunctionNameValidity function_name_validity, FunctionKind kind, 711 FunctionNameValidity function_name_validity, FunctionKind kind,
916 int function_token_pos, FunctionLiteral::FunctionType function_type, 712 int function_token_pos, FunctionLiteral::FunctionType function_type,
917 LanguageMode language_mode, bool* ok) { 713 LanguageMode language_mode, bool* ok) {
918 // Function :: 714 // Function ::
919 // '(' FormalParameterList? ')' '{' FunctionBody '}' 715 // '(' FormalParameterList? ')' '{' FunctionBody '}'
920 716
921 // Parse function body. 717 // Parse function body.
718 PreParserStatementList body;
922 bool outer_is_script_scope = scope()->is_script_scope(); 719 bool outer_is_script_scope = scope()->is_script_scope();
923 DeclarationScope* function_scope = NewFunctionScope(kind); 720 DeclarationScope* function_scope = NewFunctionScope(kind);
924 function_scope->SetLanguageMode(language_mode); 721 function_scope->SetLanguageMode(language_mode);
925 FunctionState function_state(&function_state_, &scope_state_, function_scope, 722 FunctionState function_state(&function_state_, &scope_state_, function_scope,
926 kind); 723 kind);
927 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); 724 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
928 ExpressionClassifier formals_classifier(this, &duplicate_finder); 725 ExpressionClassifier formals_classifier(this, &duplicate_finder);
929 726
930 Expect(Token::LPAREN, CHECK_OK); 727 Expect(Token::LPAREN, CHECK_OK);
931 int start_position = scanner()->location().beg_pos; 728 int start_position = scanner()->location().beg_pos;
932 function_scope->set_start_position(start_position); 729 function_scope->set_start_position(start_position);
933 PreParserFormalParameters formals(function_scope); 730 PreParserFormalParameters formals(function_scope);
934 ParseFormalParameterList(&formals, CHECK_OK); 731 ParseFormalParameterList(&formals, CHECK_OK);
935 Expect(Token::RPAREN, CHECK_OK); 732 Expect(Token::RPAREN, CHECK_OK);
936 int formals_end_position = scanner()->location().end_pos; 733 int formals_end_position = scanner()->location().end_pos;
937 734
938 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position, 735 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position,
939 formals_end_position, CHECK_OK); 736 formals_end_position, CHECK_OK);
940 737
941 // See Parser::ParseFunctionLiteral for more information about lazy parsing 738 // See Parser::ParseFunctionLiteral for more information about lazy parsing
942 // and lazy compilation. 739 // and lazy compilation.
943 bool is_lazily_parsed = (outer_is_script_scope && allow_lazy() && 740 bool is_lazily_parsed = (outer_is_script_scope && allow_lazy() &&
944 !function_state_->this_function_is_parenthesized()); 741 !function_state_->this_function_is_parenthesized());
945 742
946 Expect(Token::LBRACE, CHECK_OK); 743 Expect(Token::LBRACE, CHECK_OK);
947 if (is_lazily_parsed) { 744 if (is_lazily_parsed) {
948 ParseLazyFunctionLiteralBody(false, CHECK_OK); 745 ParseLazyFunctionLiteralBody(false, CHECK_OK);
949 } else { 746 } else {
950 ParseStatementList(Token::RBRACE, CHECK_OK); 747 ParseStatementList(body, Token::RBRACE, CHECK_OK);
951 } 748 }
952 Expect(Token::RBRACE, CHECK_OK); 749 Expect(Token::RBRACE, CHECK_OK);
953 750
954 // Parsing the body may change the language mode in our scope. 751 // Parsing the body may change the language mode in our scope.
955 language_mode = function_scope->language_mode(); 752 language_mode = function_scope->language_mode();
956 753
957 // Validate name and parameter names. We can do this only after parsing the 754 // Validate name and parameter names. We can do this only after parsing the
958 // function, since the function can declare itself strict. 755 // function, since the function can declare itself strict.
959 CheckFunctionName(language_mode, function_name, function_name_validity, 756 CheckFunctionName(language_mode, function_name, function_name_validity,
960 function_name_location, CHECK_OK); 757 function_name_location, CHECK_OK);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 is_strict_reserved ? kFunctionNameIsStrictReserved 792 is_strict_reserved ? kFunctionNameIsStrictReserved
996 : kFunctionNameValidityUnknown, 793 : kFunctionNameValidityUnknown,
997 FunctionKind::kAsyncFunction, pos, type, language_mode(), 794 FunctionKind::kAsyncFunction, pos, type, language_mode(),
998 CHECK_OK); 795 CHECK_OK);
999 return Expression::Default(); 796 return Expression::Default();
1000 } 797 }
1001 798
1002 PreParser::LazyParsingResult PreParser::ParseLazyFunctionLiteralBody( 799 PreParser::LazyParsingResult PreParser::ParseLazyFunctionLiteralBody(
1003 bool may_abort, bool* ok) { 800 bool may_abort, bool* ok) {
1004 int body_start = position(); 801 int body_start = position();
802 PreParserStatementList body;
1005 LazyParsingResult result = ParseStatementList( 803 LazyParsingResult result = ParseStatementList(
1006 Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete)); 804 body, Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete));
1007 if (result == kLazyParsingAborted) return result; 805 if (result == kLazyParsingAborted) return result;
1008 806
1009 // Position right after terminal '}'. 807 // Position right after terminal '}'.
1010 DCHECK_EQ(Token::RBRACE, scanner()->peek()); 808 DCHECK_EQ(Token::RBRACE, scanner()->peek());
1011 int body_end = scanner()->peek_location().end_pos; 809 int body_end = scanner()->peek_location().end_pos;
1012 DeclarationScope* scope = this->scope()->AsDeclarationScope(); 810 DeclarationScope* scope = this->scope()->AsDeclarationScope();
1013 DCHECK(scope->is_function_scope()); 811 DCHECK(scope->is_function_scope());
1014 log_->LogFunction(body_start, body_end, 812 log_->LogFunction(body_start, body_end,
1015 function_state_->materialized_literal_count(), 813 function_state_->materialized_literal_count(),
1016 function_state_->expected_property_count(), language_mode(), 814 function_state_->expected_property_count(), language_mode(),
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 914
1117 body->Add(PreParserStatement::ExpressionStatement(return_value), zone()); 915 body->Add(PreParserStatement::ExpressionStatement(return_value), zone());
1118 } 916 }
1119 917
1120 #undef CHECK_OK 918 #undef CHECK_OK
1121 #undef CHECK_OK_CUSTOM 919 #undef CHECK_OK_CUSTOM
1122 920
1123 921
1124 } // namespace internal 922 } // namespace internal
1125 } // namespace v8 923 } // namespace v8
OLDNEW
« src/parsing/parser-base.h ('K') | « src/parsing/preparser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698