1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include <math.h>
29
30 #include "../include/v8stdint.h"
31
32 #include "allocation.h"
33 #include "checks.h"
34 #include "conversions.h"
35 #include "conversions-inl.h"
36 #include "globals.h"
37 #include "hashmap.h"
38 #include "list.h"
39 #include "preparse-data-format.h"
40 #include "preparse-data.h"
41 #include "preparser.h"
42 #include "unicode.h"
43 #include "utils.h"
44
45 namespace v8 {
46
47 #ifdef _MSC_VER
48 // Usually defined in math.h, but not in MSVC.
49 // Abstracted to work
50 int isfinite(double value);
51 #endif
52
53 namespace preparser {
54
PreParseLazyFunction(i::LanguageMode mode,i::ParserRecorder * log)55 PreParser::PreParseResult PreParser::PreParseLazyFunction(
56 i::LanguageMode mode, i::ParserRecorder* log) {
57 log_ = log;
58 // Lazy functions always have trivial outer scopes (no with/catch scopes).
59 Scope top_scope(&scope_, kTopLevelScope);
60 set_language_mode(mode);
61 Scope function_scope(&scope_, kFunctionScope);
62 ASSERT_EQ(i::Token::LBRACE, scanner_->current_token());
63 bool ok = true;
64 int start_position = scanner_->peek_location().beg_pos;
65 ParseLazyFunctionLiteralBody(&ok);
66 if (stack_overflow_) return kPreParseStackOverflow;
67 if (!ok) {
68 ReportUnexpectedToken(scanner_->current_token());
69 } else {
70 ASSERT_EQ(i::Token::RBRACE, scanner_->peek());
71 if (!is_classic_mode()) {
72 int end_pos = scanner_->location().end_pos;
73 CheckOctalLiteral(start_position, end_pos, &ok);
74 if (ok) {
75 CheckDelayedStrictModeViolation(start_position, end_pos, &ok);
76 }
77 }
78 }
79 return kPreParseSuccess;
80 }
81
82
83 // Preparsing checks a JavaScript program and emits preparse-data that helps
84 // a later parsing to be faster.
85 // See preparser-data.h for the data.
86
87 // The PreParser checks that the syntax follows the grammar for JavaScript,
88 // and collects some information about the program along the way.
89 // The grammar check is only performed in order to understand the program
90 // sufficiently to deduce some information about it, that can be used
91 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
92 // rather it is to speed up properly written and correct programs.
93 // That means that contextual checks (like a label being declared where
94 // it is used) are generally omitted.
95
ReportUnexpectedToken(i::Token::Value token)96 void PreParser::ReportUnexpectedToken(i::Token::Value token) {
97 // We don't report stack overflows here, to avoid increasing the
98 // stack depth even further. Instead we report it after parsing is
99 // over, in ParseProgram.
100 if (token == i::Token::ILLEGAL && stack_overflow_) {
101 return;
102 }
103 i::Scanner::Location source_location = scanner_->location();
104
105 // Four of the tokens are treated specially
106 switch (token) {
107 case i::Token::EOS:
108 return ReportMessageAt(source_location, "unexpected_eos", NULL);
109 case i::Token::NUMBER:
110 return ReportMessageAt(source_location, "unexpected_token_number", NULL);
111 case i::Token::STRING:
112 return ReportMessageAt(source_location, "unexpected_token_string", NULL);
113 case i::Token::IDENTIFIER:
114 return ReportMessageAt(source_location,
115 "unexpected_token_identifier", NULL);
116 case i::Token::FUTURE_RESERVED_WORD:
117 return ReportMessageAt(source_location, "unexpected_reserved", NULL);
118 case i::Token::FUTURE_STRICT_RESERVED_WORD:
119 return ReportMessageAt(source_location,
120 "unexpected_strict_reserved", NULL);
121 default:
122 const char* name = i::Token::String(token);
123 ReportMessageAt(source_location, "unexpected_token", name);
124 }
125 }
126
127
128 // Checks whether octal literal last seen is between beg_pos and end_pos.
129 // If so, reports an error.
CheckOctalLiteral(int beg_pos,int end_pos,bool * ok)130 void PreParser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
131 i::Scanner::Location octal = scanner_->octal_position();
132 if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) {
133 ReportMessageAt(octal, "strict_octal_literal", NULL);
134 scanner_->clear_octal_position();
135 *ok = false;
136 }
137 }
138
139
140 #define CHECK_OK ok); \
141 if (!*ok) return kUnknownSourceElements; \
142 ((void)0
143 #define DUMMY ) // to make indentation work
144 #undef DUMMY
145
146
ParseSourceElement(bool * ok)147 PreParser::Statement PreParser::ParseSourceElement(bool* ok) {
148 // (Ecma 262 5th Edition, clause 14):
149 // SourceElement:
150 // Statement
151 // FunctionDeclaration
152 //
153 // In harmony mode we allow additionally the following productions
154 // SourceElement:
155 // LetDeclaration
156 // ConstDeclaration
157
158 switch (peek()) {
159 case i::Token::FUNCTION:
160 return ParseFunctionDeclaration(ok);
161 case i::Token::LET:
162 case i::Token::CONST:
163 return ParseVariableStatement(kSourceElement, ok);
164 default:
165 return ParseStatement(ok);
166 }
167 }
168
169
ParseSourceElements(int end_token,bool * ok)170 PreParser::SourceElements PreParser::ParseSourceElements(int end_token,
171 bool* ok) {
172 // SourceElements ::
173 // (Statement)* <end_token>
174
175 bool allow_directive_prologue = true;
176 while (peek() != end_token) {
177 Statement statement = ParseSourceElement(CHECK_OK);
178 if (allow_directive_prologue) {
179 if (statement.IsUseStrictLiteral()) {
180 set_language_mode(harmony_scoping_ ?
181 i::EXTENDED_MODE : i::STRICT_MODE);
182 } else if (!statement.IsStringLiteral()) {
183 allow_directive_prologue = false;
184 }
185 }
186 }
187 return kUnknownSourceElements;
188 }
189
190
191 #undef CHECK_OK
192 #define CHECK_OK ok); \
193 if (!*ok) return Statement::Default(); \
194 ((void)0
195 #define DUMMY ) // to make indentation work
196 #undef DUMMY
197
198
ParseStatement(bool * ok)199 PreParser::Statement PreParser::ParseStatement(bool* ok) {
200 // Statement ::
201 // Block
202 // VariableStatement
203 // EmptyStatement
204 // ExpressionStatement
205 // IfStatement
206 // IterationStatement
207 // ContinueStatement
208 // BreakStatement
209 // ReturnStatement
210 // WithStatement
211 // LabelledStatement
212 // SwitchStatement
213 // ThrowStatement
214 // TryStatement
215 // DebuggerStatement
216
217 // Note: Since labels can only be used by 'break' and 'continue'
218 // statements, which themselves are only valid within blocks,
219 // iterations or 'switch' statements (i.e., BreakableStatements),
220 // labels can be simply ignored in all other cases; except for
221 // trivial labeled break statements 'label: break label' which is
222 // parsed into an empty statement.
223
224 // Keep the source position of the statement
225 switch (peek()) {
226 case i::Token::LBRACE:
227 return ParseBlock(ok);
228
229 case i::Token::CONST:
230 case i::Token::LET:
231 case i::Token::VAR:
232 return ParseVariableStatement(kStatement, ok);
233
234 case i::Token::SEMICOLON:
235 Next();
236 return Statement::Default();
237
238 case i::Token::IF:
239 return ParseIfStatement(ok);
240
241 case i::Token::DO:
242 return ParseDoWhileStatement(ok);
243
244 case i::Token::WHILE:
245 return ParseWhileStatement(ok);
246
247 case i::Token::FOR:
248 return ParseForStatement(ok);
249
250 case i::Token::CONTINUE:
251 return ParseContinueStatement(ok);
252
253 case i::Token::BREAK:
254 return ParseBreakStatement(ok);
255
256 case i::Token::RETURN:
257 return ParseReturnStatement(ok);
258
259 case i::Token::WITH:
260 return ParseWithStatement(ok);
261
262 case i::Token::SWITCH:
263 return ParseSwitchStatement(ok);
264
265 case i::Token::THROW:
266 return ParseThrowStatement(ok);
267
268 case i::Token::TRY:
269 return ParseTryStatement(ok);
270
271 case i::Token::FUNCTION: {
272 i::Scanner::Location start_location = scanner_->peek_location();
273 Statement statement = ParseFunctionDeclaration(CHECK_OK);
274 i::Scanner::Location end_location = scanner_->location();
275 if (!is_classic_mode()) {
276 ReportMessageAt(start_location.beg_pos, end_location.end_pos,
277 "strict_function", NULL);
278 *ok = false;
279 return Statement::Default();
280 } else {
281 return statement;
282 }
283 }
284
285 case i::Token::DEBUGGER:
286 return ParseDebuggerStatement(ok);
287
288 default:
289 return ParseExpressionOrLabelledStatement(ok);
290 }
291 }
292
293
ParseFunctionDeclaration(bool * ok)294 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
295 // FunctionDeclaration ::
296 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
297 Expect(i::Token::FUNCTION, CHECK_OK);
298
299 Identifier identifier = ParseIdentifier(CHECK_OK);
300 i::Scanner::Location location = scanner_->location();
301
302 Expression function_value = ParseFunctionLiteral(CHECK_OK);
303
304 if (function_value.IsStrictFunction() &&
305 !identifier.IsValidStrictVariable()) {
306 // Strict mode violation, using either reserved word or eval/arguments
307 // as name of strict function.
308 const char* type = "strict_function_name";
309 if (identifier.IsFutureStrictReserved()) {
310 type = "strict_reserved_word";
311 }
312 ReportMessageAt(location, type, NULL);
313 *ok = false;
314 }
315 return Statement::FunctionDeclaration();
316 }
317
318
ParseBlock(bool * ok)319 PreParser::Statement PreParser::ParseBlock(bool* ok) {
320 // Block ::
321 // '{' Statement* '}'
322
323 // Note that a Block does not introduce a new execution scope!
324 // (ECMA-262, 3rd, 12.2)
325 //
326 Expect(i::Token::LBRACE, CHECK_OK);
327 while (peek() != i::Token::RBRACE) {
328 if (is_extended_mode()) {
329 ParseSourceElement(CHECK_OK);
330 } else {
331 ParseStatement(CHECK_OK);
332 }
333 }
334 Expect(i::Token::RBRACE, ok);
335 return Statement::Default();
336 }
337
338
ParseVariableStatement(VariableDeclarationContext var_context,bool * ok)339 PreParser::Statement PreParser::ParseVariableStatement(
340 VariableDeclarationContext var_context,
341 bool* ok) {
342 // VariableStatement ::
343 // VariableDeclarations ';'
344
345 Statement result = ParseVariableDeclarations(var_context,
346 NULL,
347 NULL,
348 CHECK_OK);
349 ExpectSemicolon(CHECK_OK);
350 return result;
351 }
352
353
354 // If the variable declaration declares exactly one non-const
355 // variable, then *var is set to that variable. In all other cases,
356 // *var is untouched; in particular, it is the caller's responsibility
357 // to initialize it properly. This mechanism is also used for the parsing
358 // of 'for-in' loops.
ParseVariableDeclarations(VariableDeclarationContext var_context,VariableDeclarationProperties * decl_props,int * num_decl,bool * ok)359 PreParser::Statement PreParser::ParseVariableDeclarations(
360 VariableDeclarationContext var_context,
361 VariableDeclarationProperties* decl_props,
362 int* num_decl,
363 bool* ok) {
364 // VariableDeclarations ::
365 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
366 //
367 // The ES6 Draft Rev3 specifies the following grammar for const declarations
368 //
369 // ConstDeclaration ::
370 // const ConstBinding (',' ConstBinding)* ';'
371 // ConstBinding ::
372 // Identifier '=' AssignmentExpression
373 //
374 // TODO(ES6):
375 // ConstBinding ::
376 // BindingPattern '=' AssignmentExpression
377 bool require_initializer = false;
378 if (peek() == i::Token::VAR) {
379 Consume(i::Token::VAR);
380 } else if (peek() == i::Token::CONST) {
381 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
382 //
383 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
384 //
385 // * It is a Syntax Error if the code that matches this production is not
386 // contained in extended code.
387 //
388 // However disallowing const in classic mode will break compatibility with
389 // existing pages. Therefore we keep allowing const with the old
390 // non-harmony semantics in classic mode.
391 Consume(i::Token::CONST);
392 switch (language_mode()) {
393 case i::CLASSIC_MODE:
394 break;
395 case i::STRICT_MODE: {
396 i::Scanner::Location location = scanner_->peek_location();
397 ReportMessageAt(location, "strict_const", NULL);
398 *ok = false;
399 return Statement::Default();
400 }
401 case i::EXTENDED_MODE:
402 if (var_context != kSourceElement &&
403 var_context != kForStatement) {
404 i::Scanner::Location location = scanner_->peek_location();
405 ReportMessageAt(location.beg_pos, location.end_pos,
406 "unprotected_const", NULL);
407 *ok = false;
408 return Statement::Default();
409 }
410 require_initializer = true;
411 break;
412 }
413 } else if (peek() == i::Token::LET) {
414 // ES6 Draft Rev4 section 12.2.1:
415 //
416 // LetDeclaration : let LetBindingList ;
417 //
418 // * It is a Syntax Error if the code that matches this production is not
419 // contained in extended code.
420 if (!is_extended_mode()) {
421 i::Scanner::Location location = scanner_->peek_location();
422 ReportMessageAt(location.beg_pos, location.end_pos,
423 "illegal_let", NULL);
424 *ok = false;
425 return Statement::Default();
426 }
427 Consume(i::Token::LET);
428 if (var_context != kSourceElement &&
429 var_context != kForStatement) {
430 i::Scanner::Location location = scanner_->peek_location();
431 ReportMessageAt(location.beg_pos, location.end_pos,
432 "unprotected_let", NULL);
433 *ok = false;
434 return Statement::Default();
435 }
436 } else {
437 *ok = false;
438 return Statement::Default();
439 }
440
441 // The scope of a var/const declared variable anywhere inside a function
442 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
443 // of a let declared variable is the scope of the immediately enclosing
444 // block.
445 int nvars = 0; // the number of variables declared
446 do {
447 // Parse variable name.
448 if (nvars > 0) Consume(i::Token::COMMA);
449 Identifier identifier = ParseIdentifier(CHECK_OK);
450 if (!is_classic_mode() && !identifier.IsValidStrictVariable()) {
451 StrictModeIdentifierViolation(scanner_->location(),
452 "strict_var_name",
453 identifier,
454 ok);
455 return Statement::Default();
456 }
457 nvars++;
458 if (peek() == i::Token::ASSIGN || require_initializer) {
459 Expect(i::Token::ASSIGN, CHECK_OK);
460 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
461 if (decl_props != NULL) *decl_props = kHasInitializers;
462 }
463 } while (peek() == i::Token::COMMA);
464
465 if (num_decl != NULL) *num_decl = nvars;
466 return Statement::Default();
467 }
468
469
ParseExpressionOrLabelledStatement(bool * ok)470 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
471 // ExpressionStatement | LabelledStatement ::
472 // Expression ';'
473 // Identifier ':' Statement
474
475 Expression expr = ParseExpression(true, CHECK_OK);
476 if (expr.IsRawIdentifier()) {
477 ASSERT(!expr.AsIdentifier().IsFutureReserved());
478 ASSERT(is_classic_mode() || !expr.AsIdentifier().IsFutureStrictReserved());
479 if (peek() == i::Token::COLON) {
480 Consume(i::Token::COLON);
481 return ParseStatement(ok);
482 }
483 // Preparsing is disabled for extensions (because the extension details
484 // aren't passed to lazily compiled functions), so we don't
485 // accept "native function" in the preparser.
486 }
487 // Parsed expression statement.
488 ExpectSemicolon(CHECK_OK);
489 return Statement::ExpressionStatement(expr);
490 }
491
492
ParseIfStatement(bool * ok)493 PreParser::Statement PreParser::ParseIfStatement(bool* ok) {
494 // IfStatement ::
495 // 'if' '(' Expression ')' Statement ('else' Statement)?
496
497 Expect(i::Token::IF, CHECK_OK);
498 Expect(i::Token::LPAREN, CHECK_OK);
499 ParseExpression(true, CHECK_OK);
500 Expect(i::Token::RPAREN, CHECK_OK);
501 ParseStatement(CHECK_OK);
502 if (peek() == i::Token::ELSE) {
503 Next();
504 ParseStatement(CHECK_OK);
505 }
506 return Statement::Default();
507 }
508
509
ParseContinueStatement(bool * ok)510 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
511 // ContinueStatement ::
512 // 'continue' [no line terminator] Identifier? ';'
513
514 Expect(i::Token::CONTINUE, CHECK_OK);
515 i::Token::Value tok = peek();
516 if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
517 tok != i::Token::SEMICOLON &&
518 tok != i::Token::RBRACE &&
519 tok != i::Token::EOS) {
520 ParseIdentifier(CHECK_OK);
521 }
522 ExpectSemicolon(CHECK_OK);
523 return Statement::Default();
524 }
525
526
ParseBreakStatement(bool * ok)527 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) {
528 // BreakStatement ::
529 // 'break' [no line terminator] Identifier? ';'
530
531 Expect(i::Token::BREAK, CHECK_OK);
532 i::Token::Value tok = peek();
533 if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
534 tok != i::Token::SEMICOLON &&
535 tok != i::Token::RBRACE &&
536 tok != i::Token::EOS) {
537 ParseIdentifier(CHECK_OK);
538 }
539 ExpectSemicolon(CHECK_OK);
540 return Statement::Default();
541 }
542
543
ParseReturnStatement(bool * ok)544 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
545 // ReturnStatement ::
546 // 'return' [no line terminator] Expression? ';'
547
548 // Consume the return token. It is necessary to do the before
549 // reporting any errors on it, because of the way errors are
550 // reported (underlining).
551 Expect(i::Token::RETURN, CHECK_OK);
552
553 // An ECMAScript program is considered syntactically incorrect if it
554 // contains a return statement that is not within the body of a
555 // function. See ECMA-262, section 12.9, page 67.
556 // This is not handled during preparsing.
557
558 i::Token::Value tok = peek();
559 if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
560 tok != i::Token::SEMICOLON &&
561 tok != i::Token::RBRACE &&
562 tok != i::Token::EOS) {
563 ParseExpression(true, CHECK_OK);
564 }
565 ExpectSemicolon(CHECK_OK);
566 return Statement::Default();
567 }
568
569
ParseWithStatement(bool * ok)570 PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
571 // WithStatement ::
572 // 'with' '(' Expression ')' Statement
573 Expect(i::Token::WITH, CHECK_OK);
574 if (!is_classic_mode()) {
575 i::Scanner::Location location = scanner_->location();
576 ReportMessageAt(location, "strict_mode_with", NULL);
577 *ok = false;
578 return Statement::Default();
579 }
580 Expect(i::Token::LPAREN, CHECK_OK);
581 ParseExpression(true, CHECK_OK);
582 Expect(i::Token::RPAREN, CHECK_OK);
583
584 scope_->EnterWith();
585 ParseStatement(CHECK_OK);
586 scope_->LeaveWith();
587 return Statement::Default();
588 }
589
590
ParseSwitchStatement(bool * ok)591 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
592 // SwitchStatement ::
593 // 'switch' '(' Expression ')' '{' CaseClause* '}'
594
595 Expect(i::Token::SWITCH, CHECK_OK);
596 Expect(i::Token::LPAREN, CHECK_OK);
597 ParseExpression(true, CHECK_OK);
598 Expect(i::Token::RPAREN, CHECK_OK);
599
600 Expect(i::Token::LBRACE, CHECK_OK);
601 i::Token::Value token = peek();
602 while (token != i::Token::RBRACE) {
603 if (token == i::Token::CASE) {
604 Expect(i::Token::CASE, CHECK_OK);
605 ParseExpression(true, CHECK_OK);
606 Expect(i::Token::COLON, CHECK_OK);
607 } else if (token == i::Token::DEFAULT) {
608 Expect(i::Token::DEFAULT, CHECK_OK);
609 Expect(i::Token::COLON, CHECK_OK);
610 } else {
611 ParseStatement(CHECK_OK);
612 }
613 token = peek();
614 }
615 Expect(i::Token::RBRACE, ok);
616 return Statement::Default();
617 }
618
619
ParseDoWhileStatement(bool * ok)620 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
621 // DoStatement ::
622 // 'do' Statement 'while' '(' Expression ')' ';'
623
624 Expect(i::Token::DO, CHECK_OK);
625 ParseStatement(CHECK_OK);
626 Expect(i::Token::WHILE, CHECK_OK);
627 Expect(i::Token::LPAREN, CHECK_OK);
628 ParseExpression(true, CHECK_OK);
629 Expect(i::Token::RPAREN, ok);
630 if (peek() == i::Token::SEMICOLON) Consume(i::Token::SEMICOLON);
631 return Statement::Default();
632 }
633
634
ParseWhileStatement(bool * ok)635 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
636 // WhileStatement ::
637 // 'while' '(' Expression ')' Statement
638
639 Expect(i::Token::WHILE, CHECK_OK);
640 Expect(i::Token::LPAREN, CHECK_OK);
641 ParseExpression(true, CHECK_OK);
642 Expect(i::Token::RPAREN, CHECK_OK);
643 ParseStatement(ok);
644 return Statement::Default();
645 }
646
647
ParseForStatement(bool * ok)648 PreParser::Statement PreParser::ParseForStatement(bool* ok) {
649 // ForStatement ::
650 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
651
652 Expect(i::Token::FOR, CHECK_OK);
653 Expect(i::Token::LPAREN, CHECK_OK);
654 if (peek() != i::Token::SEMICOLON) {
655 if (peek() == i::Token::VAR || peek() == i::Token::CONST ||
656 peek() == i::Token::LET) {
657 bool is_let = peek() == i::Token::LET;
658 int decl_count;
659 VariableDeclarationProperties decl_props = kHasNoInitializers;
660 ParseVariableDeclarations(
661 kForStatement, &decl_props, &decl_count, CHECK_OK);
662 bool accept_IN = decl_count == 1 &&
663 !(is_let && decl_props == kHasInitializers);
664 if (peek() == i::Token::IN && accept_IN) {
665 Expect(i::Token::IN, CHECK_OK);
666 ParseExpression(true, CHECK_OK);
667 Expect(i::Token::RPAREN, CHECK_OK);
668
669 ParseStatement(CHECK_OK);
670 return Statement::Default();
671 }
672 } else {
673 ParseExpression(false, CHECK_OK);
674 if (peek() == i::Token::IN) {
675 Expect(i::Token::IN, CHECK_OK);
676 ParseExpression(true, CHECK_OK);
677 Expect(i::Token::RPAREN, CHECK_OK);
678
679 ParseStatement(CHECK_OK);
680 return Statement::Default();
681 }
682 }
683 }
684
685 // Parsed initializer at this point.
686 Expect(i::Token::SEMICOLON, CHECK_OK);
687
688 if (peek() != i::Token::SEMICOLON) {
689 ParseExpression(true, CHECK_OK);
690 }
691 Expect(i::Token::SEMICOLON, CHECK_OK);
692
693 if (peek() != i::Token::RPAREN) {
694 ParseExpression(true, CHECK_OK);
695 }
696 Expect(i::Token::RPAREN, CHECK_OK);
697
698 ParseStatement(ok);
699 return Statement::Default();
700 }
701
702
ParseThrowStatement(bool * ok)703 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
704 // ThrowStatement ::
705 // 'throw' [no line terminator] Expression ';'
706
707 Expect(i::Token::THROW, CHECK_OK);
708 if (scanner_->HasAnyLineTerminatorBeforeNext()) {
709 i::Scanner::Location pos = scanner_->location();
710 ReportMessageAt(pos, "newline_after_throw", NULL);
711 *ok = false;
712 return Statement::Default();
713 }
714 ParseExpression(true, CHECK_OK);
715 ExpectSemicolon(ok);
716 return Statement::Default();
717 }
718
719
ParseTryStatement(bool * ok)720 PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
721 // TryStatement ::
722 // 'try' Block Catch
723 // 'try' Block Finally
724 // 'try' Block Catch Finally
725 //
726 // Catch ::
727 // 'catch' '(' Identifier ')' Block
728 //
729 // Finally ::
730 // 'finally' Block
731
732 // In preparsing, allow any number of catch/finally blocks, including zero
733 // of both.
734
735 Expect(i::Token::TRY, CHECK_OK);
736
737 ParseBlock(CHECK_OK);
738
739 bool catch_or_finally_seen = false;
740 if (peek() == i::Token::CATCH) {
741 Consume(i::Token::CATCH);
742 Expect(i::Token::LPAREN, CHECK_OK);
743 Identifier id = ParseIdentifier(CHECK_OK);
744 if (!is_classic_mode() && !id.IsValidStrictVariable()) {
745 StrictModeIdentifierViolation(scanner_->location(),
746 "strict_catch_variable",
747 id,
748 ok);
749 return Statement::Default();
750 }
751 Expect(i::Token::RPAREN, CHECK_OK);
752 scope_->EnterWith();
753 ParseBlock(ok);
754 scope_->LeaveWith();
755 if (!*ok) Statement::Default();
756 catch_or_finally_seen = true;
757 }
758 if (peek() == i::Token::FINALLY) {
759 Consume(i::Token::FINALLY);
760 ParseBlock(CHECK_OK);
761 catch_or_finally_seen = true;
762 }
763 if (!catch_or_finally_seen) {
764 *ok = false;
765 }
766 return Statement::Default();
767 }
768
769
ParseDebuggerStatement(bool * ok)770 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
771 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
772 // contexts this is used as a statement which invokes the debugger as if a
773 // break point is present.
774 // DebuggerStatement ::
775 // 'debugger' ';'
776
777 Expect(i::Token::DEBUGGER, CHECK_OK);
778 ExpectSemicolon(ok);
779 return Statement::Default();
780 }
781
782
783 #undef CHECK_OK
784 #define CHECK_OK ok); \
785 if (!*ok) return Expression::Default(); \
786 ((void)0
787 #define DUMMY ) // to make indentation work
788 #undef DUMMY
789
790
791 // Precedence = 1
ParseExpression(bool accept_IN,bool * ok)792 PreParser::Expression PreParser::ParseExpression(bool accept_IN, bool* ok) {
793 // Expression ::
794 // AssignmentExpression
795 // Expression ',' AssignmentExpression
796
797 Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK);
798 while (peek() == i::Token::COMMA) {
799 Expect(i::Token::COMMA, CHECK_OK);
800 ParseAssignmentExpression(accept_IN, CHECK_OK);
801 result = Expression::Default();
802 }
803 return result;
804 }
805
806
807 // Precedence = 2
ParseAssignmentExpression(bool accept_IN,bool * ok)808 PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN,
809 bool* ok) {
810 // AssignmentExpression ::
811 // ConditionalExpression
812 // LeftHandSideExpression AssignmentOperator AssignmentExpression
813
814 i::Scanner::Location before = scanner_->peek_location();
815 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
816
817 if (!i::Token::IsAssignmentOp(peek())) {
818 // Parsed conditional expression only (no assignment).
819 return expression;
820 }
821
822 if (!is_classic_mode() &&
823 expression.IsIdentifier() &&
824 expression.AsIdentifier().IsEvalOrArguments()) {
825 i::Scanner::Location after = scanner_->location();
826 ReportMessageAt(before.beg_pos, after.end_pos,
827 "strict_lhs_assignment", NULL);
828 *ok = false;
829 return Expression::Default();
830 }
831
832 i::Token::Value op = Next(); // Get assignment operator.
833 ParseAssignmentExpression(accept_IN, CHECK_OK);
834
835 if ((op == i::Token::ASSIGN) && expression.IsThisProperty()) {
836 scope_->AddProperty();
837 }
838
839 return Expression::Default();
840 }
841
842
843 // Precedence = 3
ParseConditionalExpression(bool accept_IN,bool * ok)844 PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN,
845 bool* ok) {
846 // ConditionalExpression ::
847 // LogicalOrExpression
848 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
849
850 // We start using the binary expression parser for prec >= 4 only!
851 Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
852 if (peek() != i::Token::CONDITIONAL) return expression;
853 Consume(i::Token::CONDITIONAL);
854 // In parsing the first assignment expression in conditional
855 // expressions we always accept the 'in' keyword; see ECMA-262,
856 // section 11.12, page 58.
857 ParseAssignmentExpression(true, CHECK_OK);
858 Expect(i::Token::COLON, CHECK_OK);
859 ParseAssignmentExpression(accept_IN, CHECK_OK);
860 return Expression::Default();
861 }
862
863
Precedence(i::Token::Value tok,bool accept_IN)864 int PreParser::Precedence(i::Token::Value tok, bool accept_IN) {
865 if (tok == i::Token::IN && !accept_IN)
866 return 0; // 0 precedence will terminate binary expression parsing
867
868 return i::Token::Precedence(tok);
869 }
870
871
872 // Precedence >= 4
ParseBinaryExpression(int prec,bool accept_IN,bool * ok)873 PreParser::Expression PreParser::ParseBinaryExpression(int prec,
874 bool accept_IN,
875 bool* ok) {
876 Expression result = ParseUnaryExpression(CHECK_OK);
877 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
878 // prec1 >= 4
879 while (Precedence(peek(), accept_IN) == prec1) {
880 Next();
881 ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
882 result = Expression::Default();
883 }
884 }
885 return result;
886 }
887
888
ParseUnaryExpression(bool * ok)889 PreParser::Expression PreParser::ParseUnaryExpression(bool* ok) {
890 // UnaryExpression ::
891 // PostfixExpression
892 // 'delete' UnaryExpression
893 // 'void' UnaryExpression
894 // 'typeof' UnaryExpression
895 // '++' UnaryExpression
896 // '--' UnaryExpression
897 // '+' UnaryExpression
898 // '-' UnaryExpression
899 // '~' UnaryExpression
900 // '!' UnaryExpression
901
902 i::Token::Value op = peek();
903 if (i::Token::IsUnaryOp(op)) {
904 op = Next();
905 ParseUnaryExpression(ok);
906 return Expression::Default();
907 } else if (i::Token::IsCountOp(op)) {
908 op = Next();
909 i::Scanner::Location before = scanner_->peek_location();
910 Expression expression = ParseUnaryExpression(CHECK_OK);
911 if (!is_classic_mode() &&
912 expression.IsIdentifier() &&
913 expression.AsIdentifier().IsEvalOrArguments()) {
914 i::Scanner::Location after = scanner_->location();
915 ReportMessageAt(before.beg_pos, after.end_pos,
916 "strict_lhs_prefix", NULL);
917 *ok = false;
918 }
919 return Expression::Default();
920 } else {
921 return ParsePostfixExpression(ok);
922 }
923 }
924
925
ParsePostfixExpression(bool * ok)926 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
927 // PostfixExpression ::
928 // LeftHandSideExpression ('++' | '--')?
929
930 i::Scanner::Location before = scanner_->peek_location();
931 Expression expression = ParseLeftHandSideExpression(CHECK_OK);
932 if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
933 i::Token::IsCountOp(peek())) {
934 if (!is_classic_mode() &&
935 expression.IsIdentifier() &&
936 expression.AsIdentifier().IsEvalOrArguments()) {
937 i::Scanner::Location after = scanner_->location();
938 ReportMessageAt(before.beg_pos, after.end_pos,
939 "strict_lhs_postfix", NULL);
940 *ok = false;
941 return Expression::Default();
942 }
943 Next();
944 return Expression::Default();
945 }
946 return expression;
947 }
948
949
ParseLeftHandSideExpression(bool * ok)950 PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) {
951 // LeftHandSideExpression ::
952 // (NewExpression | MemberExpression) ...
953
954 Expression result = Expression::Default();
955 if (peek() == i::Token::NEW) {
956 result = ParseNewExpression(CHECK_OK);
957 } else {
958 result = ParseMemberExpression(CHECK_OK);
959 }
960
961 while (true) {
962 switch (peek()) {
963 case i::Token::LBRACK: {
964 Consume(i::Token::LBRACK);
965 ParseExpression(true, CHECK_OK);
966 Expect(i::Token::RBRACK, CHECK_OK);
967 if (result.IsThis()) {
968 result = Expression::ThisProperty();
969 } else {
970 result = Expression::Default();
971 }
972 break;
973 }
974
975 case i::Token::LPAREN: {
976 ParseArguments(CHECK_OK);
977 result = Expression::Default();
978 break;
979 }
980
981 case i::Token::PERIOD: {
982 Consume(i::Token::PERIOD);
983 ParseIdentifierName(CHECK_OK);
984 if (result.IsThis()) {
985 result = Expression::ThisProperty();
986 } else {
987 result = Expression::Default();
988 }
989 break;
990 }
991
992 default:
993 return result;
994 }
995 }
996 }
997
998
ParseNewExpression(bool * ok)999 PreParser::Expression PreParser::ParseNewExpression(bool* ok) {
1000 // NewExpression ::
1001 // ('new')+ MemberExpression
1002
1003 // The grammar for new expressions is pretty warped. The keyword
1004 // 'new' can either be a part of the new expression (where it isn't
1005 // followed by an argument list) or a part of the member expression,
1006 // where it must be followed by an argument list. To accommodate
1007 // this, we parse the 'new' keywords greedily and keep track of how
1008 // many we have parsed. This information is then passed on to the
1009 // member expression parser, which is only allowed to match argument
1010 // lists as long as it has 'new' prefixes left
1011 unsigned new_count = 0;
1012 do {
1013 Consume(i::Token::NEW);
1014 new_count++;
1015 } while (peek() == i::Token::NEW);
1016
1017 return ParseMemberWithNewPrefixesExpression(new_count, ok);
1018 }
1019
1020
ParseMemberExpression(bool * ok)1021 PreParser::Expression PreParser::ParseMemberExpression(bool* ok) {
1022 return ParseMemberWithNewPrefixesExpression(0, ok);
1023 }
1024
1025
ParseMemberWithNewPrefixesExpression(unsigned new_count,bool * ok)1026 PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression(
1027 unsigned new_count, bool* ok) {
1028 // MemberExpression ::
1029 // (PrimaryExpression | FunctionLiteral)
1030 // ('[' Expression ']' | '.' Identifier | Arguments)*
1031
1032 // Parse the initial primary or function expression.
1033 Expression result = Expression::Default();
1034 if (peek() == i::Token::FUNCTION) {
1035 Consume(i::Token::FUNCTION);
1036 Identifier identifier = Identifier::Default();
1037 if (peek_any_identifier()) {
1038 identifier = ParseIdentifier(CHECK_OK);
1039 }
1040 result = ParseFunctionLiteral(CHECK_OK);
1041 if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) {
1042 StrictModeIdentifierViolation(scanner_->location(),
1043 "strict_function_name",
1044 identifier,
1045 ok);
1046 return Expression::Default();
1047 }
1048 } else {
1049 result = ParsePrimaryExpression(CHECK_OK);
1050 }
1051
1052 while (true) {
1053 switch (peek()) {
1054 case i::Token::LBRACK: {
1055 Consume(i::Token::LBRACK);
1056 ParseExpression(true, CHECK_OK);
1057 Expect(i::Token::RBRACK, CHECK_OK);
1058 if (result.IsThis()) {
1059 result = Expression::ThisProperty();
1060 } else {
1061 result = Expression::Default();
1062 }
1063 break;
1064 }
1065 case i::Token::PERIOD: {
1066 Consume(i::Token::PERIOD);
1067 ParseIdentifierName(CHECK_OK);
1068 if (result.IsThis()) {
1069 result = Expression::ThisProperty();
1070 } else {
1071 result = Expression::Default();
1072 }
1073 break;
1074 }
1075 case i::Token::LPAREN: {
1076 if (new_count == 0) return result;
1077 // Consume one of the new prefixes (already parsed).
1078 ParseArguments(CHECK_OK);
1079 new_count--;
1080 result = Expression::Default();
1081 break;
1082 }
1083 default:
1084 return result;
1085 }
1086 }
1087 }
1088
1089
ParsePrimaryExpression(bool * ok)1090 PreParser::Expression PreParser::ParsePrimaryExpression(bool* ok) {
1091 // PrimaryExpression ::
1092 // 'this'
1093 // 'null'
1094 // 'true'
1095 // 'false'
1096 // Identifier
1097 // Number
1098 // String
1099 // ArrayLiteral
1100 // ObjectLiteral
1101 // RegExpLiteral
1102 // '(' Expression ')'
1103
1104 Expression result = Expression::Default();
1105 switch (peek()) {
1106 case i::Token::THIS: {
1107 Next();
1108 result = Expression::This();
1109 break;
1110 }
1111
1112 case i::Token::FUTURE_RESERVED_WORD: {
1113 Next();
1114 i::Scanner::Location location = scanner_->location();
1115 ReportMessageAt(location.beg_pos, location.end_pos,
1116 "reserved_word", NULL);
1117 *ok = false;
1118 return Expression::Default();
1119 }
1120
1121 case i::Token::FUTURE_STRICT_RESERVED_WORD:
1122 if (!is_classic_mode()) {
1123 Next();
1124 i::Scanner::Location location = scanner_->location();
1125 ReportMessageAt(location, "strict_reserved_word", NULL);
1126 *ok = false;
1127 return Expression::Default();
1128 }
1129 // FALLTHROUGH
1130 case i::Token::IDENTIFIER: {
1131 Identifier id = ParseIdentifier(CHECK_OK);
1132 result = Expression::FromIdentifier(id);
1133 break;
1134 }
1135
1136 case i::Token::NULL_LITERAL:
1137 case i::Token::TRUE_LITERAL:
1138 case i::Token::FALSE_LITERAL:
1139 case i::Token::NUMBER: {
1140 Next();
1141 break;
1142 }
1143 case i::Token::STRING: {
1144 Next();
1145 result = GetStringSymbol();
1146 break;
1147 }
1148
1149 case i::Token::ASSIGN_DIV:
1150 result = ParseRegExpLiteral(true, CHECK_OK);
1151 break;
1152
1153 case i::Token::DIV:
1154 result = ParseRegExpLiteral(false, CHECK_OK);
1155 break;
1156
1157 case i::Token::LBRACK:
1158 result = ParseArrayLiteral(CHECK_OK);
1159 break;
1160
1161 case i::Token::LBRACE:
1162 result = ParseObjectLiteral(CHECK_OK);
1163 break;
1164
1165 case i::Token::LPAREN:
1166 Consume(i::Token::LPAREN);
1167 parenthesized_function_ = (peek() == i::Token::FUNCTION);
1168 result = ParseExpression(true, CHECK_OK);
1169 Expect(i::Token::RPAREN, CHECK_OK);
1170 result = result.Parenthesize();
1171 break;
1172
1173 case i::Token::MOD:
1174 result = ParseV8Intrinsic(CHECK_OK);
1175 break;
1176
1177 default: {
1178 Next();
1179 *ok = false;
1180 return Expression::Default();
1181 }
1182 }
1183
1184 return result;
1185 }
1186
1187
ParseArrayLiteral(bool * ok)1188 PreParser::Expression PreParser::ParseArrayLiteral(bool* ok) {
1189 // ArrayLiteral ::
1190 // '[' Expression? (',' Expression?)* ']'
1191 Expect(i::Token::LBRACK, CHECK_OK);
1192 while (peek() != i::Token::RBRACK) {
1193 if (peek() != i::Token::COMMA) {
1194 ParseAssignmentExpression(true, CHECK_OK);
1195 }
1196 if (peek() != i::Token::RBRACK) {
1197 Expect(i::Token::COMMA, CHECK_OK);
1198 }
1199 }
1200 Expect(i::Token::RBRACK, CHECK_OK);
1201
1202 scope_->NextMaterializedLiteralIndex();
1203 return Expression::Default();
1204 }
1205
CheckDuplicate(DuplicateFinder * finder,i::Token::Value property,int type,bool * ok)1206 void PreParser::CheckDuplicate(DuplicateFinder* finder,
1207 i::Token::Value property,
1208 int type,
1209 bool* ok) {
1210 int old_type;
1211 if (property == i::Token::NUMBER) {
1212 old_type = finder->AddNumber(scanner_->literal_ascii_string(), type);
1213 } else if (scanner_->is_literal_ascii()) {
1214 old_type = finder->AddAsciiSymbol(scanner_->literal_ascii_string(),
1215 type);
1216 } else {
1217 old_type = finder->AddUtf16Symbol(scanner_->literal_utf16_string(), type);
1218 }
1219 if (HasConflict(old_type, type)) {
1220 if (IsDataDataConflict(old_type, type)) {
1221 // Both are data properties.
1222 if (is_classic_mode()) return;
1223 ReportMessageAt(scanner_->location(),
1224 "strict_duplicate_property", NULL);
1225 } else if (IsDataAccessorConflict(old_type, type)) {
1226 // Both a data and an accessor property with the same name.
1227 ReportMessageAt(scanner_->location(),
1228 "accessor_data_property", NULL);
1229 } else {
1230 ASSERT(IsAccessorAccessorConflict(old_type, type));
1231 // Both accessors of the same type.
1232 ReportMessageAt(scanner_->location(),
1233 "accessor_get_set", NULL);
1234 }
1235 *ok = false;
1236 }
1237 }
1238
1239
ParseObjectLiteral(bool * ok)1240 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
1241 // ObjectLiteral ::
1242 // '{' (
1243 // ((IdentifierName | String | Number) ':' AssignmentExpression)
1244 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
1245 // )*[','] '}'
1246
1247 Expect(i::Token::LBRACE, CHECK_OK);
1248 DuplicateFinder duplicate_finder(scanner_->unicode_cache());
1249 while (peek() != i::Token::RBRACE) {
1250 i::Token::Value next = peek();
1251 switch (next) {
1252 case i::Token::IDENTIFIER:
1253 case i::Token::FUTURE_RESERVED_WORD:
1254 case i::Token::FUTURE_STRICT_RESERVED_WORD: {
1255 bool is_getter = false;
1256 bool is_setter = false;
1257 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
1258 if ((is_getter || is_setter) && peek() != i::Token::COLON) {
1259 i::Token::Value name = Next();
1260 bool is_keyword = i::Token::IsKeyword(name);
1261 if (name != i::Token::IDENTIFIER &&
1262 name != i::Token::FUTURE_RESERVED_WORD &&
1263 name != i::Token::FUTURE_STRICT_RESERVED_WORD &&
1264 name != i::Token::NUMBER &&
1265 name != i::Token::STRING &&
1266 !is_keyword) {
1267 *ok = false;
1268 return Expression::Default();
1269 }
1270 if (!is_keyword) {
1271 LogSymbol();
1272 }
1273 PropertyType type = is_getter ? kGetterProperty : kSetterProperty;
1274 CheckDuplicate(&duplicate_finder, name, type, CHECK_OK);
1275 ParseFunctionLiteral(CHECK_OK);
1276 if (peek() != i::Token::RBRACE) {
1277 Expect(i::Token::COMMA, CHECK_OK);
1278 }
1279 continue; // restart the while
1280 }
1281 CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK);
1282 break;
1283 }
1284 case i::Token::STRING:
1285 Consume(next);
1286 CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK);
1287 GetStringSymbol();
1288 break;
1289 case i::Token::NUMBER:
1290 Consume(next);
1291 CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK);
1292 break;
1293 default:
1294 if (i::Token::IsKeyword(next)) {
1295 Consume(next);
1296 CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK);
1297 } else {
1298 // Unexpected token.
1299 *ok = false;
1300 return Expression::Default();
1301 }
1302 }
1303
1304 Expect(i::Token::COLON, CHECK_OK);
1305 ParseAssignmentExpression(true, CHECK_OK);
1306
1307 // TODO(1240767): Consider allowing trailing comma.
1308 if (peek() != i::Token::RBRACE) Expect(i::Token::COMMA, CHECK_OK);
1309 }
1310 Expect(i::Token::RBRACE, CHECK_OK);
1311
1312 scope_->NextMaterializedLiteralIndex();
1313 return Expression::Default();
1314 }
1315
1316
ParseRegExpLiteral(bool seen_equal,bool * ok)1317 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal,
1318 bool* ok) {
1319 if (!scanner_->ScanRegExpPattern(seen_equal)) {
1320 Next();
1321 ReportMessageAt(scanner_->location(), "unterminated_regexp", NULL);
1322 *ok = false;
1323 return Expression::Default();
1324 }
1325
1326 scope_->NextMaterializedLiteralIndex();
1327
1328 if (!scanner_->ScanRegExpFlags()) {
1329 Next();
1330 ReportMessageAt(scanner_->location(), "invalid_regexp_flags", NULL);
1331 *ok = false;
1332 return Expression::Default();
1333 }
1334 Next();
1335 return Expression::Default();
1336 }
1337
1338
ParseArguments(bool * ok)1339 PreParser::Arguments PreParser::ParseArguments(bool* ok) {
1340 // Arguments ::
1341 // '(' (AssignmentExpression)*[','] ')'
1342
1343 Expect(i::Token::LPAREN, ok);
1344 if (!*ok) return -1;
1345 bool done = (peek() == i::Token::RPAREN);
1346 int argc = 0;
1347 while (!done) {
1348 ParseAssignmentExpression(true, ok);
1349 if (!*ok) return -1;
1350 argc++;
1351 done = (peek() == i::Token::RPAREN);
1352 if (!done) {
1353 Expect(i::Token::COMMA, ok);
1354 if (!*ok) return -1;
1355 }
1356 }
1357 Expect(i::Token::RPAREN, ok);
1358 return argc;
1359 }
1360
1361
ParseFunctionLiteral(bool * ok)1362 PreParser::Expression PreParser::ParseFunctionLiteral(bool* ok) {
1363 // Function ::
1364 // '(' FormalParameterList? ')' '{' FunctionBody '}'
1365
1366 // Parse function body.
1367 ScopeType outer_scope_type = scope_->type();
1368 bool inside_with = scope_->IsInsideWith();
1369 Scope function_scope(&scope_, kFunctionScope);
1370 // FormalParameterList ::
1371 // '(' (Identifier)*[','] ')'
1372 Expect(i::Token::LPAREN, CHECK_OK);
1373 int start_position = scanner_->location().beg_pos;
1374 bool done = (peek() == i::Token::RPAREN);
1375 DuplicateFinder duplicate_finder(scanner_->unicode_cache());
1376 while (!done) {
1377 Identifier id = ParseIdentifier(CHECK_OK);
1378 if (!id.IsValidStrictVariable()) {
1379 StrictModeIdentifierViolation(scanner_->location(),
1380 "strict_param_name",
1381 id,
1382 CHECK_OK);
1383 }
1384 int prev_value;
1385 if (scanner_->is_literal_ascii()) {
1386 prev_value =
1387 duplicate_finder.AddAsciiSymbol(scanner_->literal_ascii_string(), 1);
1388 } else {
1389 prev_value =
1390 duplicate_finder.AddUtf16Symbol(scanner_->literal_utf16_string(), 1);
1391 }
1392
1393 if (prev_value != 0) {
1394 SetStrictModeViolation(scanner_->location(),
1395 "strict_param_dupe",
1396 CHECK_OK);
1397 }
1398 done = (peek() == i::Token::RPAREN);
1399 if (!done) {
1400 Expect(i::Token::COMMA, CHECK_OK);
1401 }
1402 }
1403 Expect(i::Token::RPAREN, CHECK_OK);
1404
1405 // Determine if the function will be lazily compiled.
1406 // Currently only happens to top-level functions.
1407 // Optimistically assume that all top-level functions are lazily compiled.
1408 bool is_lazily_compiled = (outer_scope_type == kTopLevelScope &&
1409 !inside_with && allow_lazy_ &&
1410 !parenthesized_function_);
1411 parenthesized_function_ = false;
1412
1413 Expect(i::Token::LBRACE, CHECK_OK);
1414 if (is_lazily_compiled) {
1415 ParseLazyFunctionLiteralBody(CHECK_OK);
1416 } else {
1417 ParseSourceElements(i::Token::RBRACE, ok);
1418 }
1419 Expect(i::Token::RBRACE, CHECK_OK);
1420
1421 if (!is_classic_mode()) {
1422 int end_position = scanner_->location().end_pos;
1423 CheckOctalLiteral(start_position, end_position, CHECK_OK);
1424 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK);
1425 return Expression::StrictFunction();
1426 }
1427
1428 return Expression::Default();
1429 }
1430
1431
ParseLazyFunctionLiteralBody(bool * ok)1432 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
1433 int body_start = scanner_->location().beg_pos;
1434 log_->PauseRecording();
1435 ParseSourceElements(i::Token::RBRACE, ok);
1436 log_->ResumeRecording();
1437 if (!*ok) return;
1438
1439 // Position right after terminal '}'.
1440 ASSERT_EQ(i::Token::RBRACE, scanner_->peek());
1441 int body_end = scanner_->peek_location().end_pos;
1442 log_->LogFunction(body_start, body_end,
1443 scope_->materialized_literal_count(),
1444 scope_->expected_properties(),
1445 language_mode());
1446 }
1447
1448
ParseV8Intrinsic(bool * ok)1449 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
1450 // CallRuntime ::
1451 // '%' Identifier Arguments
1452 Expect(i::Token::MOD, CHECK_OK);
1453 if (!allow_natives_syntax_) {
1454 *ok = false;
1455 return Expression::Default();
1456 }
1457 ParseIdentifier(CHECK_OK);
1458 ParseArguments(ok);
1459
1460 return Expression::Default();
1461 }
1462
1463 #undef CHECK_OK
1464
1465
ExpectSemicolon(bool * ok)1466 void PreParser::ExpectSemicolon(bool* ok) {
1467 // Check for automatic semicolon insertion according to
1468 // the rules given in ECMA-262, section 7.9, page 21.
1469 i::Token::Value tok = peek();
1470 if (tok == i::Token::SEMICOLON) {
1471 Next();
1472 return;
1473 }
1474 if (scanner_->HasAnyLineTerminatorBeforeNext() ||
1475 tok == i::Token::RBRACE ||
1476 tok == i::Token::EOS) {
1477 return;
1478 }
1479 Expect(i::Token::SEMICOLON, ok);
1480 }
1481
1482
LogSymbol()1483 void PreParser::LogSymbol() {
1484 int identifier_pos = scanner_->location().beg_pos;
1485 if (scanner_->is_literal_ascii()) {
1486 log_->LogAsciiSymbol(identifier_pos, scanner_->literal_ascii_string());
1487 } else {
1488 log_->LogUtf16Symbol(identifier_pos, scanner_->literal_utf16_string());
1489 }
1490 }
1491
1492
GetStringSymbol()1493 PreParser::Expression PreParser::GetStringSymbol() {
1494 const int kUseStrictLength = 10;
1495 const char* kUseStrictChars = "use strict";
1496 LogSymbol();
1497 if (scanner_->is_literal_ascii() &&
1498 scanner_->literal_length() == kUseStrictLength &&
1499 !scanner_->literal_contains_escapes() &&
1500 !strncmp(scanner_->literal_ascii_string().start(), kUseStrictChars,
1501 kUseStrictLength)) {
1502 return Expression::UseStrictStringLiteral();
1503 }
1504 return Expression::StringLiteral();
1505 }
1506
1507
GetIdentifierSymbol()1508 PreParser::Identifier PreParser::GetIdentifierSymbol() {
1509 LogSymbol();
1510 if (scanner_->current_token() == i::Token::FUTURE_RESERVED_WORD) {
1511 return Identifier::FutureReserved();
1512 } else if (scanner_->current_token() ==
1513 i::Token::FUTURE_STRICT_RESERVED_WORD) {
1514 return Identifier::FutureStrictReserved();
1515 }
1516 if (scanner_->is_literal_ascii()) {
1517 // Detect strict-mode poison words.
1518 if (scanner_->literal_length() == 4 &&
1519 !strncmp(scanner_->literal_ascii_string().start(), "eval", 4)) {
1520 return Identifier::Eval();
1521 }
1522 if (scanner_->literal_length() == 9 &&
1523 !strncmp(scanner_->literal_ascii_string().start(), "arguments", 9)) {
1524 return Identifier::Arguments();
1525 }
1526 }
1527 return Identifier::Default();
1528 }
1529
1530
ParseIdentifier(bool * ok)1531 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
1532 i::Token::Value next = Next();
1533 switch (next) {
1534 case i::Token::FUTURE_RESERVED_WORD: {
1535 i::Scanner::Location location = scanner_->location();
1536 ReportMessageAt(location.beg_pos, location.end_pos,
1537 "reserved_word", NULL);
1538 *ok = false;
1539 return GetIdentifierSymbol();
1540 }
1541 case i::Token::FUTURE_STRICT_RESERVED_WORD:
1542 if (!is_classic_mode()) {
1543 i::Scanner::Location location = scanner_->location();
1544 ReportMessageAt(location.beg_pos, location.end_pos,
1545 "strict_reserved_word", NULL);
1546 *ok = false;
1547 }
1548 // FALLTHROUGH
1549 case i::Token::IDENTIFIER:
1550 return GetIdentifierSymbol();
1551 default:
1552 *ok = false;
1553 return Identifier::Default();
1554 }
1555 }
1556
1557
SetStrictModeViolation(i::Scanner::Location location,const char * type,bool * ok)1558 void PreParser::SetStrictModeViolation(i::Scanner::Location location,
1559 const char* type,
1560 bool* ok) {
1561 if (!is_classic_mode()) {
1562 ReportMessageAt(location, type, NULL);
1563 *ok = false;
1564 return;
1565 }
1566 // Delay report in case this later turns out to be strict code
1567 // (i.e., for function names and parameters prior to a "use strict"
1568 // directive).
1569 // It's safe to overwrite an existing violation.
1570 // It's either from a function that turned out to be non-strict,
1571 // or it's in the current function (and we just need to report
1572 // one error), or it's in a unclosed nesting function that wasn't
1573 // strict (otherwise we would already be in strict mode).
1574 strict_mode_violation_location_ = location;
1575 strict_mode_violation_type_ = type;
1576 }
1577
1578
CheckDelayedStrictModeViolation(int beg_pos,int end_pos,bool * ok)1579 void PreParser::CheckDelayedStrictModeViolation(int beg_pos,
1580 int end_pos,
1581 bool* ok) {
1582 i::Scanner::Location location = strict_mode_violation_location_;
1583 if (location.IsValid() &&
1584 location.beg_pos > beg_pos && location.end_pos < end_pos) {
1585 ReportMessageAt(location, strict_mode_violation_type_, NULL);
1586 *ok = false;
1587 }
1588 }
1589
1590
StrictModeIdentifierViolation(i::Scanner::Location location,const char * eval_args_type,Identifier identifier,bool * ok)1591 void PreParser::StrictModeIdentifierViolation(i::Scanner::Location location,
1592 const char* eval_args_type,
1593 Identifier identifier,
1594 bool* ok) {
1595 const char* type = eval_args_type;
1596 if (identifier.IsFutureReserved()) {
1597 type = "reserved_word";
1598 } else if (identifier.IsFutureStrictReserved()) {
1599 type = "strict_reserved_word";
1600 }
1601 if (!is_classic_mode()) {
1602 ReportMessageAt(location, type, NULL);
1603 *ok = false;
1604 return;
1605 }
1606 strict_mode_violation_location_ = location;
1607 strict_mode_violation_type_ = type;
1608 }
1609
1610
ParseIdentifierName(bool * ok)1611 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
1612 i::Token::Value next = Next();
1613 if (i::Token::IsKeyword(next)) {
1614 int pos = scanner_->location().beg_pos;
1615 const char* keyword = i::Token::String(next);
1616 log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword,
1617 i::StrLength(keyword)));
1618 return Identifier::Default();
1619 }
1620 if (next == i::Token::IDENTIFIER ||
1621 next == i::Token::FUTURE_RESERVED_WORD ||
1622 next == i::Token::FUTURE_STRICT_RESERVED_WORD) {
1623 return GetIdentifierSymbol();
1624 }
1625 *ok = false;
1626 return Identifier::Default();
1627 }
1628
1629 #undef CHECK_OK
1630
1631
1632 // This function reads an identifier and determines whether or not it
1633 // is 'get' or 'set'.
ParseIdentifierNameOrGetOrSet(bool * is_get,bool * is_set,bool * ok)1634 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get,
1635 bool* is_set,
1636 bool* ok) {
1637 Identifier result = ParseIdentifierName(ok);
1638 if (!*ok) return Identifier::Default();
1639 if (scanner_->is_literal_ascii() &&
1640 scanner_->literal_length() == 3) {
1641 const char* token = scanner_->literal_ascii_string().start();
1642 *is_get = strncmp(token, "get", 3) == 0;
1643 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
1644 }
1645 return result;
1646 }
1647
peek_any_identifier()1648 bool PreParser::peek_any_identifier() {
1649 i::Token::Value next = peek();
1650 return next == i::Token::IDENTIFIER ||
1651 next == i::Token::FUTURE_RESERVED_WORD ||
1652 next == i::Token::FUTURE_STRICT_RESERVED_WORD;
1653 }
1654
1655
AddAsciiSymbol(i::Vector<const char> key,int value)1656 int DuplicateFinder::AddAsciiSymbol(i::Vector<const char> key, int value) {
1657 return AddSymbol(i::Vector<const byte>::cast(key), true, value);
1658 }
1659
AddUtf16Symbol(i::Vector<const uint16_t> key,int value)1660 int DuplicateFinder::AddUtf16Symbol(i::Vector<const uint16_t> key, int value) {
1661 return AddSymbol(i::Vector<const byte>::cast(key), false, value);
1662 }
1663
AddSymbol(i::Vector<const byte> key,bool is_ascii,int value)1664 int DuplicateFinder::AddSymbol(i::Vector<const byte> key,
1665 bool is_ascii,
1666 int value) {
1667 uint32_t hash = Hash(key, is_ascii);
1668 byte* encoding = BackupKey(key, is_ascii);
1669 i::HashMap::Entry* entry = map_.Lookup(encoding, hash, true);
1670 int old_value = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
1671 entry->value =
1672 reinterpret_cast<void*>(static_cast<intptr_t>(value | old_value));
1673 return old_value;
1674 }
1675
1676
AddNumber(i::Vector<const char> key,int value)1677 int DuplicateFinder::AddNumber(i::Vector<const char> key, int value) {
1678 ASSERT(key.length() > 0);
1679 // Quick check for already being in canonical form.
1680 if (IsNumberCanonical(key)) {
1681 return AddAsciiSymbol(key, value);
1682 }
1683
1684 int flags = i::ALLOW_HEX | i::ALLOW_OCTALS;
1685 double double_value = StringToDouble(unicode_constants_, key, flags, 0.0);
1686 int length;
1687 const char* string;
1688 if (!isfinite(double_value)) {
1689 string = "Infinity";
1690 length = 8; // strlen("Infinity");
1691 } else {
1692 string = DoubleToCString(double_value,
1693 i::Vector<char>(number_buffer_, kBufferSize));
1694 length = i::StrLength(string);
1695 }
1696 return AddSymbol(i::Vector<const byte>(reinterpret_cast<const byte*>(string),
1697 length), true, value);
1698 }
1699
1700
IsNumberCanonical(i::Vector<const char> number)1701 bool DuplicateFinder::IsNumberCanonical(i::Vector<const char> number) {
1702 // Test for a safe approximation of number literals that are already
1703 // in canonical form: max 15 digits, no leading zeroes, except an
1704 // integer part that is a single zero, and no trailing zeros below
1705 // the decimal point.
1706 int pos = 0;
1707 int length = number.length();
1708 if (number.length() > 15) return false;
1709 if (number[pos] == '0') {
1710 pos++;
1711 } else {
1712 while (pos < length &&
1713 static_cast<unsigned>(number[pos] - '0') <= ('9' - '0')) pos++;
1714 }
1715 if (length == pos) return true;
1716 if (number[pos] != '.') return false;
1717 pos++;
1718 bool invalid_last_digit = true;
1719 while (pos < length) {
1720 byte digit = number[pos] - '0';
1721 if (digit > '9' - '0') return false;
1722 invalid_last_digit = (digit == 0);
1723 pos++;
1724 }
1725 return !invalid_last_digit;
1726 }
1727
1728
Hash(i::Vector<const byte> key,bool is_ascii)1729 uint32_t DuplicateFinder::Hash(i::Vector<const byte> key, bool is_ascii) {
1730 // Primitive hash function, almost identical to the one used
1731 // for strings (except that it's seeded by the length and ASCII-ness).
1732 int length = key.length();
1733 uint32_t hash = (length << 1) | (is_ascii ? 1 : 0) ;
1734 for (int i = 0; i < length; i++) {
1735 uint32_t c = key[i];
1736 hash = (hash + c) * 1025;
1737 hash ^= (hash >> 6);
1738 }
1739 return hash;
1740 }
1741
1742
Match(void * first,void * second)1743 bool DuplicateFinder::Match(void* first, void* second) {
1744 // Decode lengths.
1745 // Length + ASCII-bit is encoded as base 128, most significant heptet first,
1746 // with a 8th bit being non-zero while there are more heptets.
1747 // The value encodes the number of bytes following, and whether the original
1748 // was ASCII.
1749 byte* s1 = reinterpret_cast<byte*>(first);
1750 byte* s2 = reinterpret_cast<byte*>(second);
1751 uint32_t length_ascii_field = 0;
1752 byte c1;
1753 do {
1754 c1 = *s1;
1755 if (c1 != *s2) return false;
1756 length_ascii_field = (length_ascii_field << 7) | (c1 & 0x7f);
1757 s1++;
1758 s2++;
1759 } while ((c1 & 0x80) != 0);
1760 int length = static_cast<int>(length_ascii_field >> 1);
1761 return memcmp(s1, s2, length) == 0;
1762 }
1763
1764
BackupKey(i::Vector<const byte> bytes,bool is_ascii)1765 byte* DuplicateFinder::BackupKey(i::Vector<const byte> bytes,
1766 bool is_ascii) {
1767 uint32_t ascii_length = (bytes.length() << 1) | (is_ascii ? 1 : 0);
1768 backing_store_.StartSequence();
1769 // Emit ascii_length as base-128 encoded number, with the 7th bit set
1770 // on the byte of every heptet except the last, least significant, one.
1771 if (ascii_length >= (1 << 7)) {
1772 if (ascii_length >= (1 << 14)) {
1773 if (ascii_length >= (1 << 21)) {
1774 if (ascii_length >= (1 << 28)) {
1775 backing_store_.Add(static_cast<byte>((ascii_length >> 28) | 0x80));
1776 }
1777 backing_store_.Add(static_cast<byte>((ascii_length >> 21) | 0x80u));
1778 }
1779 backing_store_.Add(static_cast<byte>((ascii_length >> 14) | 0x80u));
1780 }
1781 backing_store_.Add(static_cast<byte>((ascii_length >> 7) | 0x80u));
1782 }
1783 backing_store_.Add(static_cast<byte>(ascii_length & 0x7f));
1784
1785 backing_store_.AddBlock(bytes);
1786 return backing_store_.EndSequence().start();
1787 }
1788 } } // v8::preparser
1789