blob: 253251c0734620ab3279cae4897e77cc0afcdfb7 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2012 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_PARSING_PREPARSER_H
6#define V8_PARSING_PREPARSER_H
7
8#include "src/ast/scopes.h"
9#include "src/bailout-reason.h"
10#include "src/hashmap.h"
11#include "src/messages.h"
12#include "src/parsing/expression-classifier.h"
13#include "src/parsing/func-name-inferrer.h"
14#include "src/parsing/parser-base.h"
15#include "src/parsing/scanner.h"
16#include "src/parsing/token.h"
17
18namespace v8 {
19namespace internal {
20
21
22class PreParserIdentifier {
23 public:
24 PreParserIdentifier() : type_(kUnknownIdentifier) {}
25 static PreParserIdentifier Default() {
26 return PreParserIdentifier(kUnknownIdentifier);
27 }
28 static PreParserIdentifier Eval() {
29 return PreParserIdentifier(kEvalIdentifier);
30 }
31 static PreParserIdentifier Arguments() {
32 return PreParserIdentifier(kArgumentsIdentifier);
33 }
34 static PreParserIdentifier Undefined() {
35 return PreParserIdentifier(kUndefinedIdentifier);
36 }
37 static PreParserIdentifier FutureReserved() {
38 return PreParserIdentifier(kFutureReservedIdentifier);
39 }
40 static PreParserIdentifier FutureStrictReserved() {
41 return PreParserIdentifier(kFutureStrictReservedIdentifier);
42 }
43 static PreParserIdentifier Let() {
44 return PreParserIdentifier(kLetIdentifier);
45 }
46 static PreParserIdentifier Static() {
47 return PreParserIdentifier(kStaticIdentifier);
48 }
49 static PreParserIdentifier Yield() {
50 return PreParserIdentifier(kYieldIdentifier);
51 }
52 static PreParserIdentifier Prototype() {
53 return PreParserIdentifier(kPrototypeIdentifier);
54 }
55 static PreParserIdentifier Constructor() {
56 return PreParserIdentifier(kConstructorIdentifier);
57 }
58 bool IsEval() const { return type_ == kEvalIdentifier; }
59 bool IsArguments() const { return type_ == kArgumentsIdentifier; }
60 bool IsEvalOrArguments() const { return IsEval() || IsArguments(); }
61 bool IsUndefined() const { return type_ == kUndefinedIdentifier; }
62 bool IsLet() const { return type_ == kLetIdentifier; }
63 bool IsStatic() const { return type_ == kStaticIdentifier; }
64 bool IsYield() const { return type_ == kYieldIdentifier; }
65 bool IsPrototype() const { return type_ == kPrototypeIdentifier; }
66 bool IsConstructor() const { return type_ == kConstructorIdentifier; }
67 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; }
68 bool IsFutureStrictReserved() const {
69 return type_ == kFutureStrictReservedIdentifier ||
70 type_ == kLetIdentifier || type_ == kStaticIdentifier ||
71 type_ == kYieldIdentifier;
72 }
73
74 // Allow identifier->name()[->length()] to work. The preparser
75 // does not need the actual positions/lengths of the identifiers.
76 const PreParserIdentifier* operator->() const { return this; }
77 const PreParserIdentifier raw_name() const { return *this; }
78
79 int position() const { return 0; }
80 int length() const { return 0; }
81
82 private:
83 enum Type {
84 kUnknownIdentifier,
85 kFutureReservedIdentifier,
86 kFutureStrictReservedIdentifier,
87 kLetIdentifier,
88 kStaticIdentifier,
89 kYieldIdentifier,
90 kEvalIdentifier,
91 kArgumentsIdentifier,
92 kUndefinedIdentifier,
93 kPrototypeIdentifier,
94 kConstructorIdentifier
95 };
96
97 explicit PreParserIdentifier(Type type) : type_(type) {}
98 Type type_;
99
100 friend class PreParserExpression;
101};
102
103
104class PreParserExpression {
105 public:
106 static PreParserExpression Default() {
107 return PreParserExpression(TypeField::encode(kExpression));
108 }
109
110 static PreParserExpression Spread(PreParserExpression expression) {
111 return PreParserExpression(TypeField::encode(kSpreadExpression));
112 }
113
114 static PreParserExpression FromIdentifier(PreParserIdentifier id) {
115 return PreParserExpression(TypeField::encode(kIdentifierExpression) |
116 IdentifierTypeField::encode(id.type_));
117 }
118
119 static PreParserExpression BinaryOperation(PreParserExpression left,
120 Token::Value op,
121 PreParserExpression right) {
122 return PreParserExpression(TypeField::encode(kBinaryOperationExpression));
123 }
124
125 static PreParserExpression Assignment() {
126 return PreParserExpression(TypeField::encode(kExpression) |
127 ExpressionTypeField::encode(kAssignment));
128 }
129
130 static PreParserExpression ObjectLiteral() {
131 return PreParserExpression(TypeField::encode(kObjectLiteralExpression));
132 }
133
134 static PreParserExpression ArrayLiteral() {
135 return PreParserExpression(TypeField::encode(kArrayLiteralExpression));
136 }
137
138 static PreParserExpression StringLiteral() {
139 return PreParserExpression(TypeField::encode(kStringLiteralExpression));
140 }
141
142 static PreParserExpression UseStrictStringLiteral() {
143 return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
144 IsUseStrictField::encode(true));
145 }
146
147 static PreParserExpression UseStrongStringLiteral() {
148 return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
149 IsUseStrongField::encode(true));
150 }
151
152 static PreParserExpression This() {
153 return PreParserExpression(TypeField::encode(kExpression) |
154 ExpressionTypeField::encode(kThisExpression));
155 }
156
157 static PreParserExpression ThisProperty() {
158 return PreParserExpression(
159 TypeField::encode(kExpression) |
160 ExpressionTypeField::encode(kThisPropertyExpression));
161 }
162
163 static PreParserExpression Property() {
164 return PreParserExpression(
165 TypeField::encode(kExpression) |
166 ExpressionTypeField::encode(kPropertyExpression));
167 }
168
169 static PreParserExpression Call() {
170 return PreParserExpression(TypeField::encode(kExpression) |
171 ExpressionTypeField::encode(kCallExpression));
172 }
173
174 static PreParserExpression SuperCallReference() {
175 return PreParserExpression(
176 TypeField::encode(kExpression) |
177 ExpressionTypeField::encode(kSuperCallReference));
178 }
179
180 static PreParserExpression NoTemplateTag() {
181 return PreParserExpression(
182 TypeField::encode(kExpression) |
183 ExpressionTypeField::encode(kNoTemplateTagExpression));
184 }
185
186 bool IsIdentifier() const {
187 return TypeField::decode(code_) == kIdentifierExpression;
188 }
189
190 PreParserIdentifier AsIdentifier() const {
191 DCHECK(IsIdentifier());
192 return PreParserIdentifier(IdentifierTypeField::decode(code_));
193 }
194
195 bool IsAssignment() const {
196 return TypeField::decode(code_) == kExpression &&
197 ExpressionTypeField::decode(code_) == kAssignment;
198 }
199
200 bool IsObjectLiteral() const {
201 return TypeField::decode(code_) == kObjectLiteralExpression;
202 }
203
204 bool IsArrayLiteral() const {
205 return TypeField::decode(code_) == kArrayLiteralExpression;
206 }
207
208 bool IsStringLiteral() const {
209 return TypeField::decode(code_) == kStringLiteralExpression;
210 }
211
212 bool IsUseStrictLiteral() const {
213 return TypeField::decode(code_) == kStringLiteralExpression &&
214 IsUseStrictField::decode(code_);
215 }
216
217 bool IsUseStrongLiteral() const {
218 return TypeField::decode(code_) == kStringLiteralExpression &&
219 IsUseStrongField::decode(code_);
220 }
221
222 bool IsThis() const {
223 return TypeField::decode(code_) == kExpression &&
224 ExpressionTypeField::decode(code_) == kThisExpression;
225 }
226
227 bool IsThisProperty() const {
228 return TypeField::decode(code_) == kExpression &&
229 ExpressionTypeField::decode(code_) == kThisPropertyExpression;
230 }
231
232 bool IsProperty() const {
233 return TypeField::decode(code_) == kExpression &&
234 (ExpressionTypeField::decode(code_) == kPropertyExpression ||
235 ExpressionTypeField::decode(code_) == kThisPropertyExpression);
236 }
237
238 bool IsCall() const {
239 return TypeField::decode(code_) == kExpression &&
240 ExpressionTypeField::decode(code_) == kCallExpression;
241 }
242
243 bool IsSuperCallReference() const {
244 return TypeField::decode(code_) == kExpression &&
245 ExpressionTypeField::decode(code_) == kSuperCallReference;
246 }
247
248 bool IsValidReferenceExpression() const {
249 return IsIdentifier() || IsProperty();
250 }
251
252 // At the moment PreParser doesn't track these expression types.
253 bool IsFunctionLiteral() const { return false; }
254 bool IsCallNew() const { return false; }
255
256 bool IsNoTemplateTag() const {
257 return TypeField::decode(code_) == kExpression &&
258 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression;
259 }
260
261 bool IsSpreadExpression() const {
262 return TypeField::decode(code_) == kSpreadExpression;
263 }
264
265 PreParserExpression AsFunctionLiteral() { return *this; }
266
267 bool IsBinaryOperation() const {
268 return TypeField::decode(code_) == kBinaryOperationExpression;
269 }
270
271 // Dummy implementation for making expression->somefunc() work in both Parser
272 // and PreParser.
273 PreParserExpression* operator->() { return this; }
274
275 // More dummy implementations of things PreParser doesn't need to track:
276 void set_index(int index) {} // For YieldExpressions
277 void set_should_eager_compile() {}
278
279 int position() const { return RelocInfo::kNoPosition; }
280 void set_function_token_position(int position) {}
281
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000282 private:
283 enum Type {
284 kExpression,
285 kIdentifierExpression,
286 kStringLiteralExpression,
287 kBinaryOperationExpression,
288 kSpreadExpression,
289 kObjectLiteralExpression,
290 kArrayLiteralExpression
291 };
292
293 enum ExpressionType {
294 kThisExpression,
295 kThisPropertyExpression,
296 kPropertyExpression,
297 kCallExpression,
298 kSuperCallReference,
299 kNoTemplateTagExpression,
300 kAssignment
301 };
302
303 explicit PreParserExpression(uint32_t expression_code)
304 : code_(expression_code) {}
305
306 // The first three bits are for the Type.
307 typedef BitField<Type, 0, 3> TypeField;
308
309 // The high order bit applies only to nodes which would inherit from the
310 // Expression ASTNode --- This is by necessity, due to the fact that
311 // Expression nodes may be represented as multiple Types, not exclusively
312 // through kExpression.
313 // TODO(caitp, adamk): clean up PreParserExpression bitfields.
314 typedef BitField<bool, 31, 1> ParenthesizedField;
315
316 // The rest of the bits are interpreted depending on the value
317 // of the Type field, so they can share the storage.
318 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField;
319 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField;
320 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField;
321 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10>
322 IdentifierTypeField;
323 typedef BitField<bool, TypeField::kNext, 1> HasCoverInitializedNameField;
324
325 uint32_t code_;
326};
327
328
329// The pre-parser doesn't need to build lists of expressions, identifiers, or
330// the like.
331template <typename T>
332class PreParserList {
333 public:
334 // These functions make list->Add(some_expression) work (and do nothing).
335 PreParserList() : length_(0) {}
336 PreParserList* operator->() { return this; }
337 void Add(T, void*) { ++length_; }
338 int length() const { return length_; }
339 private:
340 int length_;
341};
342
343
344typedef PreParserList<PreParserExpression> PreParserExpressionList;
345
346
347class PreParserStatement {
348 public:
349 static PreParserStatement Default() {
350 return PreParserStatement(kUnknownStatement);
351 }
352
353 static PreParserStatement Jump() {
354 return PreParserStatement(kJumpStatement);
355 }
356
357 static PreParserStatement FunctionDeclaration() {
358 return PreParserStatement(kFunctionDeclaration);
359 }
360
361 // Creates expression statement from expression.
362 // Preserves being an unparenthesized string literal, possibly
363 // "use strict".
364 static PreParserStatement ExpressionStatement(
365 PreParserExpression expression) {
366 if (expression.IsUseStrictLiteral()) {
367 return PreParserStatement(kUseStrictExpressionStatement);
368 }
369 if (expression.IsUseStrongLiteral()) {
370 return PreParserStatement(kUseStrongExpressionStatement);
371 }
372 if (expression.IsStringLiteral()) {
373 return PreParserStatement(kStringLiteralExpressionStatement);
374 }
375 return Default();
376 }
377
378 bool IsStringLiteral() {
379 return code_ == kStringLiteralExpressionStatement;
380 }
381
382 bool IsUseStrictLiteral() {
383 return code_ == kUseStrictExpressionStatement;
384 }
385
386 bool IsUseStrongLiteral() { return code_ == kUseStrongExpressionStatement; }
387
388 bool IsFunctionDeclaration() {
389 return code_ == kFunctionDeclaration;
390 }
391
392 bool IsJumpStatement() {
393 return code_ == kJumpStatement;
394 }
395
396 private:
397 enum Type {
398 kUnknownStatement,
399 kJumpStatement,
400 kStringLiteralExpressionStatement,
401 kUseStrictExpressionStatement,
402 kUseStrongExpressionStatement,
403 kFunctionDeclaration
404 };
405
406 explicit PreParserStatement(Type code) : code_(code) {}
407 Type code_;
408};
409
410
411typedef PreParserList<PreParserStatement> PreParserStatementList;
412
413
414class PreParserFactory {
415 public:
416 explicit PreParserFactory(void* unused_value_factory) {}
417 PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
418 int pos) {
419 return PreParserExpression::Default();
420 }
421 PreParserExpression NewNumberLiteral(double number,
422 int pos) {
423 return PreParserExpression::Default();
424 }
425 PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
426 int js_flags, int literal_index,
427 bool is_strong, int pos) {
428 return PreParserExpression::Default();
429 }
430 PreParserExpression NewArrayLiteral(PreParserExpressionList values,
431 int literal_index,
432 bool is_strong,
433 int pos) {
434 return PreParserExpression::ArrayLiteral();
435 }
436 PreParserExpression NewArrayLiteral(PreParserExpressionList values,
437 int first_spread_index, int literal_index,
438 bool is_strong, int pos) {
439 return PreParserExpression::ArrayLiteral();
440 }
441 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
442 PreParserExpression value,
443 ObjectLiteralProperty::Kind kind,
444 bool is_static,
445 bool is_computed_name) {
446 return PreParserExpression::Default();
447 }
448 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
449 PreParserExpression value,
450 bool is_static,
451 bool is_computed_name) {
452 return PreParserExpression::Default();
453 }
454 PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
455 int literal_index,
456 int boilerplate_properties,
457 bool has_function,
458 bool is_strong,
459 int pos) {
460 return PreParserExpression::ObjectLiteral();
461 }
462 PreParserExpression NewVariableProxy(void* variable) {
463 return PreParserExpression::Default();
464 }
465 PreParserExpression NewProperty(PreParserExpression obj,
466 PreParserExpression key,
467 int pos) {
468 if (obj.IsThis()) {
469 return PreParserExpression::ThisProperty();
470 }
471 return PreParserExpression::Property();
472 }
473 PreParserExpression NewUnaryOperation(Token::Value op,
474 PreParserExpression expression,
475 int pos) {
476 return PreParserExpression::Default();
477 }
478 PreParserExpression NewBinaryOperation(Token::Value op,
479 PreParserExpression left,
480 PreParserExpression right, int pos) {
481 return PreParserExpression::BinaryOperation(left, op, right);
482 }
483 PreParserExpression NewCompareOperation(Token::Value op,
484 PreParserExpression left,
485 PreParserExpression right, int pos) {
486 return PreParserExpression::Default();
487 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100488 PreParserExpression NewRewritableExpression(PreParserExpression expression) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000489 return expression;
490 }
491 PreParserExpression NewAssignment(Token::Value op,
492 PreParserExpression left,
493 PreParserExpression right,
494 int pos) {
495 return PreParserExpression::Assignment();
496 }
497 PreParserExpression NewYield(PreParserExpression generator_object,
498 PreParserExpression expression,
499 Yield::Kind yield_kind,
500 int pos) {
501 return PreParserExpression::Default();
502 }
503 PreParserExpression NewConditional(PreParserExpression condition,
504 PreParserExpression then_expression,
505 PreParserExpression else_expression,
506 int pos) {
507 return PreParserExpression::Default();
508 }
509 PreParserExpression NewCountOperation(Token::Value op,
510 bool is_prefix,
511 PreParserExpression expression,
512 int pos) {
513 return PreParserExpression::Default();
514 }
515 PreParserExpression NewCall(PreParserExpression expression,
516 PreParserExpressionList arguments,
517 int pos) {
518 return PreParserExpression::Call();
519 }
520 PreParserExpression NewCallNew(PreParserExpression expression,
521 PreParserExpressionList arguments,
522 int pos) {
523 return PreParserExpression::Default();
524 }
525 PreParserExpression NewCallRuntime(const AstRawString* name,
526 const Runtime::Function* function,
527 PreParserExpressionList arguments,
528 int pos) {
529 return PreParserExpression::Default();
530 }
531 PreParserStatement NewReturnStatement(PreParserExpression expression,
532 int pos) {
533 return PreParserStatement::Default();
534 }
535 PreParserExpression NewFunctionLiteral(
536 PreParserIdentifier name, Scope* scope, PreParserStatementList body,
537 int materialized_literal_count, int expected_property_count,
538 int parameter_count,
539 FunctionLiteral::ParameterFlag has_duplicate_parameters,
540 FunctionLiteral::FunctionType function_type,
541 FunctionLiteral::EagerCompileHint eager_compile_hint, FunctionKind kind,
542 int position) {
543 return PreParserExpression::Default();
544 }
545
Ben Murdoch097c5b22016-05-18 11:27:45 +0100546 PreParserExpression NewSpread(PreParserExpression expression, int pos,
547 int expr_pos) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000548 return PreParserExpression::Spread(expression);
549 }
550
551 PreParserExpression NewEmptyParentheses(int pos) {
552 return PreParserExpression::Default();
553 }
554
555 // Return the object itself as AstVisitor and implement the needed
556 // dummy method right in this class.
557 PreParserFactory* visitor() { return this; }
558 int* ast_properties() {
559 static int dummy = 42;
560 return &dummy;
561 }
562};
563
564
565struct PreParserFormalParameters : FormalParametersBase {
566 explicit PreParserFormalParameters(Scope* scope)
567 : FormalParametersBase(scope) {}
568 int arity = 0;
569
570 int Arity() const { return arity; }
571 PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy
572};
573
574
575class PreParser;
576
577class PreParserTraits {
578 public:
579 struct Type {
580 // TODO(marja): To be removed. The Traits object should contain all the data
581 // it needs.
582 typedef PreParser* Parser;
583
584 // PreParser doesn't need to store generator variables.
585 typedef void GeneratorVariable;
586
587 typedef int AstProperties;
588
Ben Murdoch097c5b22016-05-18 11:27:45 +0100589 typedef v8::internal::ExpressionClassifier<PreParserTraits>
590 ExpressionClassifier;
591
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000592 // Return types for traversing functions.
593 typedef PreParserIdentifier Identifier;
594 typedef PreParserExpression Expression;
595 typedef PreParserExpression YieldExpression;
596 typedef PreParserExpression FunctionLiteral;
597 typedef PreParserExpression ClassLiteral;
598 typedef PreParserExpression ObjectLiteralProperty;
599 typedef PreParserExpression Literal;
600 typedef PreParserExpressionList ExpressionList;
601 typedef PreParserExpressionList PropertyList;
602 typedef PreParserIdentifier FormalParameter;
603 typedef PreParserFormalParameters FormalParameters;
604 typedef PreParserStatementList StatementList;
605
606 // For constructing objects returned by the traversing functions.
607 typedef PreParserFactory Factory;
608 };
609
610 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
611
612 // Helper functions for recursive descent.
613 static bool IsEval(PreParserIdentifier identifier) {
614 return identifier.IsEval();
615 }
616
617 static bool IsArguments(PreParserIdentifier identifier) {
618 return identifier.IsArguments();
619 }
620
621 static bool IsEvalOrArguments(PreParserIdentifier identifier) {
622 return identifier.IsEvalOrArguments();
623 }
624
625 static bool IsUndefined(PreParserIdentifier identifier) {
626 return identifier.IsUndefined();
627 }
628
629 static bool IsPrototype(PreParserIdentifier identifier) {
630 return identifier.IsPrototype();
631 }
632
633 static bool IsConstructor(PreParserIdentifier identifier) {
634 return identifier.IsConstructor();
635 }
636
637 // Returns true if the expression is of type "this.foo".
638 static bool IsThisProperty(PreParserExpression expression) {
639 return expression.IsThisProperty();
640 }
641
642 static bool IsIdentifier(PreParserExpression expression) {
643 return expression.IsIdentifier();
644 }
645
646 static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
647 return expression.AsIdentifier();
648 }
649
650 static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
651 return identifier.IsFutureStrictReserved();
652 }
653
654 static bool IsBoilerplateProperty(PreParserExpression property) {
655 // PreParser doesn't count boilerplate properties.
656 return false;
657 }
658
659 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
660 return false;
661 }
662
663 static PreParserExpression GetPropertyValue(PreParserExpression property) {
664 return PreParserExpression::Default();
665 }
666
667 // Functions for encapsulating the differences between parsing and preparsing;
668 // operations interleaved with the recursive descent.
669 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
670 // PreParser should not use FuncNameInferrer.
671 UNREACHABLE();
672 }
673
674 static void PushPropertyName(FuncNameInferrer* fni,
675 PreParserExpression expression) {
676 // PreParser should not use FuncNameInferrer.
677 UNREACHABLE();
678 }
679
680 static void InferFunctionName(FuncNameInferrer* fni,
681 PreParserExpression expression) {
682 // PreParser should not use FuncNameInferrer.
683 UNREACHABLE();
684 }
685
686 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
687 Scope* scope, PreParserExpression property, bool* has_function) {}
688
689 static void CheckAssigningFunctionLiteralToProperty(
690 PreParserExpression left, PreParserExpression right) {}
691
692 static PreParserExpression MarkExpressionAsAssigned(
693 PreParserExpression expression) {
694 // TODO(marja): To be able to produce the same errors, the preparser needs
695 // to start tracking which expressions are variables and which are assigned.
696 return expression;
697 }
698
699 bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
700 PreParserExpression y,
701 Token::Value op,
702 int pos,
703 PreParserFactory* factory) {
704 return false;
705 }
706
707 PreParserExpression BuildUnaryExpression(PreParserExpression expression,
708 Token::Value op, int pos,
709 PreParserFactory* factory) {
710 return PreParserExpression::Default();
711 }
712
713 PreParserExpression NewThrowReferenceError(MessageTemplate::Template message,
714 int pos) {
715 return PreParserExpression::Default();
716 }
717 PreParserExpression NewThrowSyntaxError(MessageTemplate::Template message,
718 Handle<Object> arg, int pos) {
719 return PreParserExpression::Default();
720 }
721 PreParserExpression NewThrowTypeError(MessageTemplate::Template message,
722 Handle<Object> arg, int pos) {
723 return PreParserExpression::Default();
724 }
725
726 // Reporting errors.
727 void ReportMessageAt(Scanner::Location location,
728 MessageTemplate::Template message,
729 const char* arg = NULL,
730 ParseErrorType error_type = kSyntaxError);
731 void ReportMessageAt(int start_pos, int end_pos,
732 MessageTemplate::Template message,
733 const char* arg = NULL,
734 ParseErrorType error_type = kSyntaxError);
735
736 // "null" return type creators.
737 static PreParserIdentifier EmptyIdentifier() {
738 return PreParserIdentifier::Default();
739 }
740 static PreParserIdentifier EmptyIdentifierString() {
741 return PreParserIdentifier::Default();
742 }
743 static PreParserExpression EmptyExpression() {
744 return PreParserExpression::Default();
745 }
746 static PreParserExpression EmptyLiteral() {
747 return PreParserExpression::Default();
748 }
749 static PreParserExpression EmptyObjectLiteralProperty() {
750 return PreParserExpression::Default();
751 }
752 static PreParserExpression EmptyFunctionLiteral() {
753 return PreParserExpression::Default();
754 }
755 static PreParserExpressionList NullExpressionList() {
756 return PreParserExpressionList();
757 }
758
759 // Odd-ball literal creators.
760 static PreParserExpression GetLiteralTheHole(int position,
761 PreParserFactory* factory) {
762 return PreParserExpression::Default();
763 }
764
765 // Producing data during the recursive descent.
766 PreParserIdentifier GetSymbol(Scanner* scanner);
767 PreParserIdentifier GetNumberAsSymbol(Scanner* scanner);
768
769 static PreParserIdentifier GetNextSymbol(Scanner* scanner) {
770 return PreParserIdentifier::Default();
771 }
772
773 static PreParserExpression ThisExpression(Scope* scope,
774 PreParserFactory* factory,
775 int pos) {
776 return PreParserExpression::This();
777 }
778
779 static PreParserExpression SuperPropertyReference(Scope* scope,
780 PreParserFactory* factory,
781 int pos) {
782 return PreParserExpression::Default();
783 }
784
785 static PreParserExpression SuperCallReference(Scope* scope,
786 PreParserFactory* factory,
787 int pos) {
788 return PreParserExpression::SuperCallReference();
789 }
790
791 static PreParserExpression NewTargetExpression(Scope* scope,
792 PreParserFactory* factory,
793 int pos) {
794 return PreParserExpression::Default();
795 }
796
Ben Murdoch097c5b22016-05-18 11:27:45 +0100797 static PreParserExpression FunctionSentExpression(Scope* scope,
798 PreParserFactory* factory,
799 int pos) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000800 return PreParserExpression::Default();
801 }
802
803 static PreParserExpression ExpressionFromLiteral(
804 Token::Value token, int pos, Scanner* scanner,
805 PreParserFactory* factory) {
806 return PreParserExpression::Default();
807 }
808
809 static PreParserExpression ExpressionFromIdentifier(
810 PreParserIdentifier name, int start_position, int end_position,
811 Scope* scope, PreParserFactory* factory) {
812 return PreParserExpression::FromIdentifier(name);
813 }
814
815 PreParserExpression ExpressionFromString(int pos,
816 Scanner* scanner,
817 PreParserFactory* factory = NULL);
818
819 PreParserExpression GetIterator(PreParserExpression iterable,
820 PreParserFactory* factory, int pos) {
821 return PreParserExpression::Default();
822 }
823
824 static PreParserExpressionList NewExpressionList(int size, Zone* zone) {
825 return PreParserExpressionList();
826 }
827
828 static PreParserStatementList NewStatementList(int size, Zone* zone) {
829 return PreParserStatementList();
830 }
831
832 static PreParserExpressionList NewPropertyList(int size, Zone* zone) {
833 return PreParserExpressionList();
834 }
835
836 static void AddParameterInitializationBlock(
837 const PreParserFormalParameters& parameters,
838 PreParserStatementList list, bool* ok) {}
839
840 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count,
841 int* expected_property_count, bool* ok) {
842 UNREACHABLE();
843 }
844
845 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
846 PreParserIdentifier function_name, int pos,
847 const PreParserFormalParameters& parameters, FunctionKind kind,
848 FunctionLiteral::FunctionType function_type, bool* ok);
849
850 V8_INLINE void ParseArrowFunctionFormalParameterList(
851 PreParserFormalParameters* parameters,
852 PreParserExpression expression, const Scanner::Location& params_loc,
853 Scanner::Location* duplicate_loc, bool* ok);
854
855 void ReindexLiterals(const PreParserFormalParameters& paramaters) {}
856
857 struct TemplateLiteralState {};
858
859 TemplateLiteralState OpenTemplateLiteral(int pos) {
860 return TemplateLiteralState();
861 }
862 void AddTemplateSpan(TemplateLiteralState*, bool) {}
863 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {}
864 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int,
865 PreParserExpression tag) {
866 if (IsTaggedTemplate(tag)) {
867 // Emulate generation of array literals for tag callsite
868 // 1st is array of cooked strings, second is array of raw strings
869 MaterializeTemplateCallsiteLiterals();
870 }
871 return EmptyExpression();
872 }
873 inline void MaterializeTemplateCallsiteLiterals();
874 PreParserExpression NoTemplateTag() {
875 return PreParserExpression::NoTemplateTag();
876 }
877 static bool IsTaggedTemplate(const PreParserExpression tag) {
878 return !tag.IsNoTemplateTag();
879 }
880
881 void AddFormalParameter(PreParserFormalParameters* parameters,
882 PreParserExpression pattern,
883 PreParserExpression initializer,
884 int initializer_end_position, bool is_rest) {
885 ++parameters->arity;
886 }
887 void DeclareFormalParameter(Scope* scope, PreParserIdentifier parameter,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100888 Type::ExpressionClassifier* classifier) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000889 if (!classifier->is_simple_parameter_list()) {
890 scope->SetHasNonSimpleParameters();
891 }
892 }
893
894 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
895
896 // Temporary glue; these functions will move to ParserBase.
897 PreParserExpression ParseV8Intrinsic(bool* ok);
898 V8_INLINE PreParserExpression ParseDoExpression(bool* ok);
899 PreParserExpression ParseFunctionLiteral(
900 PreParserIdentifier name, Scanner::Location function_name_location,
901 FunctionNameValidity function_name_validity, FunctionKind kind,
902 int function_token_position, FunctionLiteral::FunctionType type,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000903 LanguageMode language_mode, bool* ok);
904
905 PreParserExpression ParseClassLiteral(PreParserIdentifier name,
906 Scanner::Location class_name_location,
907 bool name_is_strict_reserved, int pos,
908 bool* ok);
909
910 PreParserExpressionList PrepareSpreadArguments(PreParserExpressionList list) {
911 return list;
912 }
913
914 inline void MaterializeUnspreadArgumentsLiterals(int count);
915
916 inline PreParserExpression SpreadCall(PreParserExpression function,
917 PreParserExpressionList args, int pos);
918
919 inline PreParserExpression SpreadCallNew(PreParserExpression function,
920 PreParserExpressionList args,
921 int pos);
922
923 inline void RewriteDestructuringAssignments() {}
924
925 inline void QueueDestructuringAssignmentForRewriting(PreParserExpression) {}
Ben Murdoch097c5b22016-05-18 11:27:45 +0100926 inline void QueueNonPatternForRewriting(PreParserExpression) {}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000927
928 void SetFunctionNameFromPropertyName(PreParserExpression,
929 PreParserIdentifier) {}
930 void SetFunctionNameFromIdentifierRef(PreParserExpression,
931 PreParserExpression) {}
932
Ben Murdoch097c5b22016-05-18 11:27:45 +0100933 inline void RewriteNonPattern(Type::ExpressionClassifier* classifier,
934 bool* ok);
935
936 V8_INLINE Zone* zone() const;
937 V8_INLINE ZoneList<PreParserExpression>* GetNonPatternList() const;
938
939 inline PreParserExpression RewriteYieldStar(
940 PreParserExpression generator, PreParserExpression expr, int pos);
941 inline PreParserExpression RewriteInstanceof(PreParserExpression lhs,
942 PreParserExpression rhs,
943 int pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000944
945 private:
946 PreParser* pre_parser_;
947};
948
949
950// Preparsing checks a JavaScript program and emits preparse-data that helps
951// a later parsing to be faster.
952// See preparse-data-format.h for the data format.
953
954// The PreParser checks that the syntax follows the grammar for JavaScript,
955// and collects some information about the program along the way.
956// The grammar check is only performed in order to understand the program
957// sufficiently to deduce some information about it, that can be used
958// to speed up later parsing. Finding errors is not the goal of pre-parsing,
959// rather it is to speed up properly written and correct programs.
960// That means that contextual checks (like a label being declared where
961// it is used) are generally omitted.
962class PreParser : public ParserBase<PreParserTraits> {
963 public:
964 typedef PreParserIdentifier Identifier;
965 typedef PreParserExpression Expression;
966 typedef PreParserStatement Statement;
967
968 enum PreParseResult {
969 kPreParseStackOverflow,
970 kPreParseSuccess
971 };
972
973 PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory,
974 ParserRecorder* log, uintptr_t stack_limit)
975 : ParserBase<PreParserTraits>(zone, scanner, stack_limit, NULL,
976 ast_value_factory, log, this) {}
977
978 // Pre-parse the program from the character stream; returns true on
979 // success (even if parsing failed, the pre-parse data successfully
980 // captured the syntax error), and false if a stack-overflow happened
981 // during parsing.
982 PreParseResult PreParseProgram(int* materialized_literals = 0) {
983 Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
984 PreParserFactory factory(NULL);
985 FunctionState top_scope(&function_state_, &scope_, scope, kNormalFunction,
986 &factory);
987 bool ok = true;
988 int start_position = scanner()->peek_location().beg_pos;
989 ParseStatementList(Token::EOS, &ok);
990 if (stack_overflow()) return kPreParseStackOverflow;
991 if (!ok) {
992 ReportUnexpectedToken(scanner()->current_token());
993 } else if (is_strict(scope_->language_mode())) {
994 CheckStrictOctalLiteral(start_position, scanner()->location().end_pos,
995 &ok);
996 }
997 if (materialized_literals) {
998 *materialized_literals = function_state_->materialized_literal_count();
999 }
1000 return kPreParseSuccess;
1001 }
1002
1003 // Parses a single function literal, from the opening parentheses before
1004 // parameters to the closing brace after the body.
1005 // Returns a FunctionEntry describing the body of the function in enough
1006 // detail that it can be lazily compiled.
1007 // The scanner is expected to have matched the "function" or "function*"
1008 // keyword and parameters, and have consumed the initial '{'.
1009 // At return, unless an error occurred, the scanner is positioned before the
1010 // the final '}'.
1011 PreParseResult PreParseLazyFunction(
1012 LanguageMode language_mode, FunctionKind kind, bool has_simple_parameters,
1013 ParserRecorder* log, Scanner::BookmarkScope* bookmark = nullptr);
1014
1015 private:
1016 friend class PreParserTraits;
1017
1018 static const int kLazyParseTrialLimit = 200;
1019
1020 // These types form an algebra over syntactic categories that is just
1021 // rich enough to let us recognize and propagate the constructs that
1022 // are either being counted in the preparser data, or is important
1023 // to throw the correct syntax error exceptions.
1024
1025 // All ParseXXX functions take as the last argument an *ok parameter
1026 // which is set to false if parsing failed; it is unchanged otherwise.
1027 // By making the 'exception handling' explicit, we are forced to check
1028 // for failure at the call sites.
1029 Statement ParseStatementListItem(bool* ok);
1030 void ParseStatementList(int end_token, bool* ok,
1031 Scanner::BookmarkScope* bookmark = nullptr);
1032 Statement ParseStatement(bool* ok);
1033 Statement ParseSubStatement(bool* ok);
1034 Statement ParseFunctionDeclaration(bool* ok);
1035 Statement ParseClassDeclaration(bool* ok);
1036 Statement ParseBlock(bool* ok);
1037 Statement ParseVariableStatement(VariableDeclarationContext var_context,
1038 bool* ok);
1039 Statement ParseVariableDeclarations(VariableDeclarationContext var_context,
1040 int* num_decl, bool* is_lexical,
1041 bool* is_binding_pattern,
1042 Scanner::Location* first_initializer_loc,
1043 Scanner::Location* bindings_loc,
1044 bool* ok);
1045 Statement ParseExpressionOrLabelledStatement(bool* ok);
1046 Statement ParseIfStatement(bool* ok);
1047 Statement ParseContinueStatement(bool* ok);
1048 Statement ParseBreakStatement(bool* ok);
1049 Statement ParseReturnStatement(bool* ok);
1050 Statement ParseWithStatement(bool* ok);
1051 Statement ParseSwitchStatement(bool* ok);
1052 Statement ParseDoWhileStatement(bool* ok);
1053 Statement ParseWhileStatement(bool* ok);
1054 Statement ParseForStatement(bool* ok);
1055 Statement ParseThrowStatement(bool* ok);
1056 Statement ParseTryStatement(bool* ok);
1057 Statement ParseDebuggerStatement(bool* ok);
1058 Expression ParseConditionalExpression(bool accept_IN, bool* ok);
1059 Expression ParseObjectLiteral(bool* ok);
1060 Expression ParseV8Intrinsic(bool* ok);
1061 Expression ParseDoExpression(bool* ok);
1062
1063 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count,
1064 int* expected_property_count, bool* ok);
1065 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1066 PreParserIdentifier function_name, int pos,
1067 const PreParserFormalParameters& parameters, FunctionKind kind,
1068 FunctionLiteral::FunctionType function_type, bool* ok);
1069
1070 Expression ParseFunctionLiteral(
1071 Identifier name, Scanner::Location function_name_location,
1072 FunctionNameValidity function_name_validity, FunctionKind kind,
1073 int function_token_pos, FunctionLiteral::FunctionType function_type,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001074 LanguageMode language_mode, bool* ok);
1075 void ParseLazyFunctionLiteralBody(bool* ok,
1076 Scanner::BookmarkScope* bookmark = nullptr);
1077
1078 PreParserExpression ParseClassLiteral(PreParserIdentifier name,
1079 Scanner::Location class_name_location,
1080 bool name_is_strict_reserved, int pos,
1081 bool* ok);
1082};
1083
1084
1085void PreParserTraits::MaterializeTemplateCallsiteLiterals() {
1086 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1087 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1088}
1089
1090
1091void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) {
1092 for (int i = 0; i < count; ++i) {
1093 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1094 }
1095}
1096
1097
1098PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function,
1099 PreParserExpressionList args,
1100 int pos) {
1101 return pre_parser_->factory()->NewCall(function, args, pos);
1102}
1103
1104PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function,
1105 PreParserExpressionList args,
1106 int pos) {
1107 return pre_parser_->factory()->NewCallNew(function, args, pos);
1108}
1109
1110
1111void PreParserTraits::ParseArrowFunctionFormalParameterList(
1112 PreParserFormalParameters* parameters,
1113 PreParserExpression params, const Scanner::Location& params_loc,
1114 Scanner::Location* duplicate_loc, bool* ok) {
1115 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter
1116 // lists that are too long.
1117}
1118
1119
1120PreParserExpression PreParserTraits::ParseDoExpression(bool* ok) {
1121 return pre_parser_->ParseDoExpression(ok);
1122}
1123
1124
Ben Murdoch097c5b22016-05-18 11:27:45 +01001125void PreParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier,
1126 bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001127 pre_parser_->ValidateExpression(classifier, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001128}
1129
1130
Ben Murdoch097c5b22016-05-18 11:27:45 +01001131Zone* PreParserTraits::zone() const {
1132 return pre_parser_->function_state_->scope()->zone();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001133}
1134
1135
Ben Murdoch097c5b22016-05-18 11:27:45 +01001136ZoneList<PreParserExpression>* PreParserTraits::GetNonPatternList() const {
1137 return pre_parser_->function_state_->non_patterns_to_rewrite();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001138}
1139
1140
Ben Murdoch097c5b22016-05-18 11:27:45 +01001141PreParserExpression PreParserTraits::RewriteYieldStar(
1142 PreParserExpression generator, PreParserExpression expression, int pos) {
1143 return pre_parser_->factory()->NewYield(
1144 generator, expression, Yield::kDelegating, pos);
1145}
1146
1147PreParserExpression PreParserTraits::RewriteInstanceof(PreParserExpression lhs,
1148 PreParserExpression rhs,
1149 int pos) {
1150 return PreParserExpression::Default();
1151}
1152
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001153PreParserStatementList PreParser::ParseEagerFunctionBody(
1154 PreParserIdentifier function_name, int pos,
1155 const PreParserFormalParameters& parameters, FunctionKind kind,
1156 FunctionLiteral::FunctionType function_type, bool* ok) {
1157 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1158
1159 ParseStatementList(Token::RBRACE, ok);
1160 if (!*ok) return PreParserStatementList();
1161
1162 Expect(Token::RBRACE, ok);
1163 return PreParserStatementList();
1164}
1165
1166
1167PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
1168 PreParserIdentifier function_name, int pos,
1169 const PreParserFormalParameters& parameters, FunctionKind kind,
1170 FunctionLiteral::FunctionType function_type, bool* ok) {
1171 return pre_parser_->ParseEagerFunctionBody(function_name, pos, parameters,
1172 kind, function_type, ok);
1173}
1174
1175} // namespace internal
1176} // namespace v8
1177
1178#endif // V8_PARSING_PREPARSER_H