blob: 59100f1ae96869283ea632512c8120e1e3d8b4a8 [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
282 // Parenthesized expressions in the form `( Expression )`.
283 void set_is_parenthesized() {
284 code_ = ParenthesizedField::update(code_, true);
285 }
286 bool is_parenthesized() const { return ParenthesizedField::decode(code_); }
287
288 private:
289 enum Type {
290 kExpression,
291 kIdentifierExpression,
292 kStringLiteralExpression,
293 kBinaryOperationExpression,
294 kSpreadExpression,
295 kObjectLiteralExpression,
296 kArrayLiteralExpression
297 };
298
299 enum ExpressionType {
300 kThisExpression,
301 kThisPropertyExpression,
302 kPropertyExpression,
303 kCallExpression,
304 kSuperCallReference,
305 kNoTemplateTagExpression,
306 kAssignment
307 };
308
309 explicit PreParserExpression(uint32_t expression_code)
310 : code_(expression_code) {}
311
312 // The first three bits are for the Type.
313 typedef BitField<Type, 0, 3> TypeField;
314
315 // The high order bit applies only to nodes which would inherit from the
316 // Expression ASTNode --- This is by necessity, due to the fact that
317 // Expression nodes may be represented as multiple Types, not exclusively
318 // through kExpression.
319 // TODO(caitp, adamk): clean up PreParserExpression bitfields.
320 typedef BitField<bool, 31, 1> ParenthesizedField;
321
322 // The rest of the bits are interpreted depending on the value
323 // of the Type field, so they can share the storage.
324 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField;
325 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField;
326 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField;
327 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10>
328 IdentifierTypeField;
329 typedef BitField<bool, TypeField::kNext, 1> HasCoverInitializedNameField;
330
331 uint32_t code_;
332};
333
334
335// The pre-parser doesn't need to build lists of expressions, identifiers, or
336// the like.
337template <typename T>
338class PreParserList {
339 public:
340 // These functions make list->Add(some_expression) work (and do nothing).
341 PreParserList() : length_(0) {}
342 PreParserList* operator->() { return this; }
343 void Add(T, void*) { ++length_; }
344 int length() const { return length_; }
345 private:
346 int length_;
347};
348
349
350typedef PreParserList<PreParserExpression> PreParserExpressionList;
351
352
353class PreParserStatement {
354 public:
355 static PreParserStatement Default() {
356 return PreParserStatement(kUnknownStatement);
357 }
358
359 static PreParserStatement Jump() {
360 return PreParserStatement(kJumpStatement);
361 }
362
363 static PreParserStatement FunctionDeclaration() {
364 return PreParserStatement(kFunctionDeclaration);
365 }
366
367 // Creates expression statement from expression.
368 // Preserves being an unparenthesized string literal, possibly
369 // "use strict".
370 static PreParserStatement ExpressionStatement(
371 PreParserExpression expression) {
372 if (expression.IsUseStrictLiteral()) {
373 return PreParserStatement(kUseStrictExpressionStatement);
374 }
375 if (expression.IsUseStrongLiteral()) {
376 return PreParserStatement(kUseStrongExpressionStatement);
377 }
378 if (expression.IsStringLiteral()) {
379 return PreParserStatement(kStringLiteralExpressionStatement);
380 }
381 return Default();
382 }
383
384 bool IsStringLiteral() {
385 return code_ == kStringLiteralExpressionStatement;
386 }
387
388 bool IsUseStrictLiteral() {
389 return code_ == kUseStrictExpressionStatement;
390 }
391
392 bool IsUseStrongLiteral() { return code_ == kUseStrongExpressionStatement; }
393
394 bool IsFunctionDeclaration() {
395 return code_ == kFunctionDeclaration;
396 }
397
398 bool IsJumpStatement() {
399 return code_ == kJumpStatement;
400 }
401
402 private:
403 enum Type {
404 kUnknownStatement,
405 kJumpStatement,
406 kStringLiteralExpressionStatement,
407 kUseStrictExpressionStatement,
408 kUseStrongExpressionStatement,
409 kFunctionDeclaration
410 };
411
412 explicit PreParserStatement(Type code) : code_(code) {}
413 Type code_;
414};
415
416
417typedef PreParserList<PreParserStatement> PreParserStatementList;
418
419
420class PreParserFactory {
421 public:
422 explicit PreParserFactory(void* unused_value_factory) {}
423 PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
424 int pos) {
425 return PreParserExpression::Default();
426 }
427 PreParserExpression NewNumberLiteral(double number,
428 int pos) {
429 return PreParserExpression::Default();
430 }
431 PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
432 int js_flags, int literal_index,
433 bool is_strong, int pos) {
434 return PreParserExpression::Default();
435 }
436 PreParserExpression NewArrayLiteral(PreParserExpressionList values,
437 int literal_index,
438 bool is_strong,
439 int pos) {
440 return PreParserExpression::ArrayLiteral();
441 }
442 PreParserExpression NewArrayLiteral(PreParserExpressionList values,
443 int first_spread_index, int literal_index,
444 bool is_strong, int pos) {
445 return PreParserExpression::ArrayLiteral();
446 }
447 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
448 PreParserExpression value,
449 ObjectLiteralProperty::Kind kind,
450 bool is_static,
451 bool is_computed_name) {
452 return PreParserExpression::Default();
453 }
454 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
455 PreParserExpression value,
456 bool is_static,
457 bool is_computed_name) {
458 return PreParserExpression::Default();
459 }
460 PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
461 int literal_index,
462 int boilerplate_properties,
463 bool has_function,
464 bool is_strong,
465 int pos) {
466 return PreParserExpression::ObjectLiteral();
467 }
468 PreParserExpression NewVariableProxy(void* variable) {
469 return PreParserExpression::Default();
470 }
471 PreParserExpression NewProperty(PreParserExpression obj,
472 PreParserExpression key,
473 int pos) {
474 if (obj.IsThis()) {
475 return PreParserExpression::ThisProperty();
476 }
477 return PreParserExpression::Property();
478 }
479 PreParserExpression NewUnaryOperation(Token::Value op,
480 PreParserExpression expression,
481 int pos) {
482 return PreParserExpression::Default();
483 }
484 PreParserExpression NewBinaryOperation(Token::Value op,
485 PreParserExpression left,
486 PreParserExpression right, int pos) {
487 return PreParserExpression::BinaryOperation(left, op, right);
488 }
489 PreParserExpression NewCompareOperation(Token::Value op,
490 PreParserExpression left,
491 PreParserExpression right, int pos) {
492 return PreParserExpression::Default();
493 }
494 PreParserExpression NewRewritableAssignmentExpression(
495 PreParserExpression expression) {
496 return expression;
497 }
498 PreParserExpression NewAssignment(Token::Value op,
499 PreParserExpression left,
500 PreParserExpression right,
501 int pos) {
502 return PreParserExpression::Assignment();
503 }
504 PreParserExpression NewYield(PreParserExpression generator_object,
505 PreParserExpression expression,
506 Yield::Kind yield_kind,
507 int pos) {
508 return PreParserExpression::Default();
509 }
510 PreParserExpression NewConditional(PreParserExpression condition,
511 PreParserExpression then_expression,
512 PreParserExpression else_expression,
513 int pos) {
514 return PreParserExpression::Default();
515 }
516 PreParserExpression NewCountOperation(Token::Value op,
517 bool is_prefix,
518 PreParserExpression expression,
519 int pos) {
520 return PreParserExpression::Default();
521 }
522 PreParserExpression NewCall(PreParserExpression expression,
523 PreParserExpressionList arguments,
524 int pos) {
525 return PreParserExpression::Call();
526 }
527 PreParserExpression NewCallNew(PreParserExpression expression,
528 PreParserExpressionList arguments,
529 int pos) {
530 return PreParserExpression::Default();
531 }
532 PreParserExpression NewCallRuntime(const AstRawString* name,
533 const Runtime::Function* function,
534 PreParserExpressionList arguments,
535 int pos) {
536 return PreParserExpression::Default();
537 }
538 PreParserStatement NewReturnStatement(PreParserExpression expression,
539 int pos) {
540 return PreParserStatement::Default();
541 }
542 PreParserExpression NewFunctionLiteral(
543 PreParserIdentifier name, Scope* scope, PreParserStatementList body,
544 int materialized_literal_count, int expected_property_count,
545 int parameter_count,
546 FunctionLiteral::ParameterFlag has_duplicate_parameters,
547 FunctionLiteral::FunctionType function_type,
548 FunctionLiteral::EagerCompileHint eager_compile_hint, FunctionKind kind,
549 int position) {
550 return PreParserExpression::Default();
551 }
552
553 PreParserExpression NewSpread(PreParserExpression expression, int pos) {
554 return PreParserExpression::Spread(expression);
555 }
556
557 PreParserExpression NewEmptyParentheses(int pos) {
558 return PreParserExpression::Default();
559 }
560
561 // Return the object itself as AstVisitor and implement the needed
562 // dummy method right in this class.
563 PreParserFactory* visitor() { return this; }
564 int* ast_properties() {
565 static int dummy = 42;
566 return &dummy;
567 }
568};
569
570
571struct PreParserFormalParameters : FormalParametersBase {
572 explicit PreParserFormalParameters(Scope* scope)
573 : FormalParametersBase(scope) {}
574 int arity = 0;
575
576 int Arity() const { return arity; }
577 PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy
578};
579
580
581class PreParser;
582
583class PreParserTraits {
584 public:
585 struct Type {
586 // TODO(marja): To be removed. The Traits object should contain all the data
587 // it needs.
588 typedef PreParser* Parser;
589
590 // PreParser doesn't need to store generator variables.
591 typedef void GeneratorVariable;
592
593 typedef int AstProperties;
594
595 // Return types for traversing functions.
596 typedef PreParserIdentifier Identifier;
597 typedef PreParserExpression Expression;
598 typedef PreParserExpression YieldExpression;
599 typedef PreParserExpression FunctionLiteral;
600 typedef PreParserExpression ClassLiteral;
601 typedef PreParserExpression ObjectLiteralProperty;
602 typedef PreParserExpression Literal;
603 typedef PreParserExpressionList ExpressionList;
604 typedef PreParserExpressionList PropertyList;
605 typedef PreParserIdentifier FormalParameter;
606 typedef PreParserFormalParameters FormalParameters;
607 typedef PreParserStatementList StatementList;
608
609 // For constructing objects returned by the traversing functions.
610 typedef PreParserFactory Factory;
611 };
612
613 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
614
615 // Helper functions for recursive descent.
616 static bool IsEval(PreParserIdentifier identifier) {
617 return identifier.IsEval();
618 }
619
620 static bool IsArguments(PreParserIdentifier identifier) {
621 return identifier.IsArguments();
622 }
623
624 static bool IsEvalOrArguments(PreParserIdentifier identifier) {
625 return identifier.IsEvalOrArguments();
626 }
627
628 static bool IsUndefined(PreParserIdentifier identifier) {
629 return identifier.IsUndefined();
630 }
631
632 static bool IsPrototype(PreParserIdentifier identifier) {
633 return identifier.IsPrototype();
634 }
635
636 static bool IsConstructor(PreParserIdentifier identifier) {
637 return identifier.IsConstructor();
638 }
639
640 // Returns true if the expression is of type "this.foo".
641 static bool IsThisProperty(PreParserExpression expression) {
642 return expression.IsThisProperty();
643 }
644
645 static bool IsIdentifier(PreParserExpression expression) {
646 return expression.IsIdentifier();
647 }
648
649 static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
650 return expression.AsIdentifier();
651 }
652
653 static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
654 return identifier.IsFutureStrictReserved();
655 }
656
657 static bool IsBoilerplateProperty(PreParserExpression property) {
658 // PreParser doesn't count boilerplate properties.
659 return false;
660 }
661
662 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
663 return false;
664 }
665
666 static PreParserExpression GetPropertyValue(PreParserExpression property) {
667 return PreParserExpression::Default();
668 }
669
670 // Functions for encapsulating the differences between parsing and preparsing;
671 // operations interleaved with the recursive descent.
672 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
673 // PreParser should not use FuncNameInferrer.
674 UNREACHABLE();
675 }
676
677 static void PushPropertyName(FuncNameInferrer* fni,
678 PreParserExpression expression) {
679 // PreParser should not use FuncNameInferrer.
680 UNREACHABLE();
681 }
682
683 static void InferFunctionName(FuncNameInferrer* fni,
684 PreParserExpression expression) {
685 // PreParser should not use FuncNameInferrer.
686 UNREACHABLE();
687 }
688
689 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
690 Scope* scope, PreParserExpression property, bool* has_function) {}
691
692 static void CheckAssigningFunctionLiteralToProperty(
693 PreParserExpression left, PreParserExpression right) {}
694
695 static PreParserExpression MarkExpressionAsAssigned(
696 PreParserExpression expression) {
697 // TODO(marja): To be able to produce the same errors, the preparser needs
698 // to start tracking which expressions are variables and which are assigned.
699 return expression;
700 }
701
702 bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
703 PreParserExpression y,
704 Token::Value op,
705 int pos,
706 PreParserFactory* factory) {
707 return false;
708 }
709
710 PreParserExpression BuildUnaryExpression(PreParserExpression expression,
711 Token::Value op, int pos,
712 PreParserFactory* factory) {
713 return PreParserExpression::Default();
714 }
715
716 PreParserExpression NewThrowReferenceError(MessageTemplate::Template message,
717 int pos) {
718 return PreParserExpression::Default();
719 }
720 PreParserExpression NewThrowSyntaxError(MessageTemplate::Template message,
721 Handle<Object> arg, int pos) {
722 return PreParserExpression::Default();
723 }
724 PreParserExpression NewThrowTypeError(MessageTemplate::Template message,
725 Handle<Object> arg, int pos) {
726 return PreParserExpression::Default();
727 }
728
729 // Reporting errors.
730 void ReportMessageAt(Scanner::Location location,
731 MessageTemplate::Template message,
732 const char* arg = NULL,
733 ParseErrorType error_type = kSyntaxError);
734 void ReportMessageAt(int start_pos, int end_pos,
735 MessageTemplate::Template message,
736 const char* arg = NULL,
737 ParseErrorType error_type = kSyntaxError);
738
739 // "null" return type creators.
740 static PreParserIdentifier EmptyIdentifier() {
741 return PreParserIdentifier::Default();
742 }
743 static PreParserIdentifier EmptyIdentifierString() {
744 return PreParserIdentifier::Default();
745 }
746 static PreParserExpression EmptyExpression() {
747 return PreParserExpression::Default();
748 }
749 static PreParserExpression EmptyLiteral() {
750 return PreParserExpression::Default();
751 }
752 static PreParserExpression EmptyObjectLiteralProperty() {
753 return PreParserExpression::Default();
754 }
755 static PreParserExpression EmptyFunctionLiteral() {
756 return PreParserExpression::Default();
757 }
758 static PreParserExpressionList NullExpressionList() {
759 return PreParserExpressionList();
760 }
761
762 // Odd-ball literal creators.
763 static PreParserExpression GetLiteralTheHole(int position,
764 PreParserFactory* factory) {
765 return PreParserExpression::Default();
766 }
767
768 // Producing data during the recursive descent.
769 PreParserIdentifier GetSymbol(Scanner* scanner);
770 PreParserIdentifier GetNumberAsSymbol(Scanner* scanner);
771
772 static PreParserIdentifier GetNextSymbol(Scanner* scanner) {
773 return PreParserIdentifier::Default();
774 }
775
776 static PreParserExpression ThisExpression(Scope* scope,
777 PreParserFactory* factory,
778 int pos) {
779 return PreParserExpression::This();
780 }
781
782 static PreParserExpression SuperPropertyReference(Scope* scope,
783 PreParserFactory* factory,
784 int pos) {
785 return PreParserExpression::Default();
786 }
787
788 static PreParserExpression SuperCallReference(Scope* scope,
789 PreParserFactory* factory,
790 int pos) {
791 return PreParserExpression::SuperCallReference();
792 }
793
794 static PreParserExpression NewTargetExpression(Scope* scope,
795 PreParserFactory* factory,
796 int pos) {
797 return PreParserExpression::Default();
798 }
799
800 static PreParserExpression DefaultConstructor(bool call_super, Scope* scope,
801 int pos, int end_pos) {
802 return PreParserExpression::Default();
803 }
804
805 static PreParserExpression ExpressionFromLiteral(
806 Token::Value token, int pos, Scanner* scanner,
807 PreParserFactory* factory) {
808 return PreParserExpression::Default();
809 }
810
811 static PreParserExpression ExpressionFromIdentifier(
812 PreParserIdentifier name, int start_position, int end_position,
813 Scope* scope, PreParserFactory* factory) {
814 return PreParserExpression::FromIdentifier(name);
815 }
816
817 PreParserExpression ExpressionFromString(int pos,
818 Scanner* scanner,
819 PreParserFactory* factory = NULL);
820
821 PreParserExpression GetIterator(PreParserExpression iterable,
822 PreParserFactory* factory, int pos) {
823 return PreParserExpression::Default();
824 }
825
826 static PreParserExpressionList NewExpressionList(int size, Zone* zone) {
827 return PreParserExpressionList();
828 }
829
830 static PreParserStatementList NewStatementList(int size, Zone* zone) {
831 return PreParserStatementList();
832 }
833
834 static PreParserExpressionList NewPropertyList(int size, Zone* zone) {
835 return PreParserExpressionList();
836 }
837
838 static void AddParameterInitializationBlock(
839 const PreParserFormalParameters& parameters,
840 PreParserStatementList list, bool* ok) {}
841
842 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count,
843 int* expected_property_count, bool* ok) {
844 UNREACHABLE();
845 }
846
847 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
848 PreParserIdentifier function_name, int pos,
849 const PreParserFormalParameters& parameters, FunctionKind kind,
850 FunctionLiteral::FunctionType function_type, bool* ok);
851
852 V8_INLINE void ParseArrowFunctionFormalParameterList(
853 PreParserFormalParameters* parameters,
854 PreParserExpression expression, const Scanner::Location& params_loc,
855 Scanner::Location* duplicate_loc, bool* ok);
856
857 void ReindexLiterals(const PreParserFormalParameters& paramaters) {}
858
859 struct TemplateLiteralState {};
860
861 TemplateLiteralState OpenTemplateLiteral(int pos) {
862 return TemplateLiteralState();
863 }
864 void AddTemplateSpan(TemplateLiteralState*, bool) {}
865 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {}
866 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int,
867 PreParserExpression tag) {
868 if (IsTaggedTemplate(tag)) {
869 // Emulate generation of array literals for tag callsite
870 // 1st is array of cooked strings, second is array of raw strings
871 MaterializeTemplateCallsiteLiterals();
872 }
873 return EmptyExpression();
874 }
875 inline void MaterializeTemplateCallsiteLiterals();
876 PreParserExpression NoTemplateTag() {
877 return PreParserExpression::NoTemplateTag();
878 }
879 static bool IsTaggedTemplate(const PreParserExpression tag) {
880 return !tag.IsNoTemplateTag();
881 }
882
883 void AddFormalParameter(PreParserFormalParameters* parameters,
884 PreParserExpression pattern,
885 PreParserExpression initializer,
886 int initializer_end_position, bool is_rest) {
887 ++parameters->arity;
888 }
889 void DeclareFormalParameter(Scope* scope, PreParserIdentifier parameter,
890 ExpressionClassifier* classifier) {
891 if (!classifier->is_simple_parameter_list()) {
892 scope->SetHasNonSimpleParameters();
893 }
894 }
895
896 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
897
898 // Temporary glue; these functions will move to ParserBase.
899 PreParserExpression ParseV8Intrinsic(bool* ok);
900 V8_INLINE PreParserExpression ParseDoExpression(bool* ok);
901 PreParserExpression ParseFunctionLiteral(
902 PreParserIdentifier name, Scanner::Location function_name_location,
903 FunctionNameValidity function_name_validity, FunctionKind kind,
904 int function_token_position, FunctionLiteral::FunctionType type,
905 FunctionLiteral::ArityRestriction arity_restriction,
906 LanguageMode language_mode, bool* ok);
907
908 PreParserExpression ParseClassLiteral(PreParserIdentifier name,
909 Scanner::Location class_name_location,
910 bool name_is_strict_reserved, int pos,
911 bool* ok);
912
913 PreParserExpressionList PrepareSpreadArguments(PreParserExpressionList list) {
914 return list;
915 }
916
917 inline void MaterializeUnspreadArgumentsLiterals(int count);
918
919 inline PreParserExpression SpreadCall(PreParserExpression function,
920 PreParserExpressionList args, int pos);
921
922 inline PreParserExpression SpreadCallNew(PreParserExpression function,
923 PreParserExpressionList args,
924 int pos);
925
926 inline void RewriteDestructuringAssignments() {}
927
928 inline void QueueDestructuringAssignmentForRewriting(PreParserExpression) {}
929
930 void SetFunctionNameFromPropertyName(PreParserExpression,
931 PreParserIdentifier) {}
932 void SetFunctionNameFromIdentifierRef(PreParserExpression,
933 PreParserExpression) {}
934
935 inline PreParserExpression RewriteNonPattern(
936 PreParserExpression expr, const ExpressionClassifier* classifier,
937 bool* ok);
938 inline PreParserExpression RewriteNonPatternArguments(
939 PreParserExpression args, const ExpressionClassifier* classifier,
940 bool* ok);
941 inline PreParserExpression RewriteNonPatternObjectLiteralProperty(
942 PreParserExpression property, const ExpressionClassifier* classifier,
943 bool* ok);
944
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,
1074 FunctionLiteral::ArityRestriction arity_restriction,
1075 LanguageMode language_mode, bool* ok);
1076 void ParseLazyFunctionLiteralBody(bool* ok,
1077 Scanner::BookmarkScope* bookmark = nullptr);
1078
1079 PreParserExpression ParseClassLiteral(PreParserIdentifier name,
1080 Scanner::Location class_name_location,
1081 bool name_is_strict_reserved, int pos,
1082 bool* ok);
1083};
1084
1085
1086void PreParserTraits::MaterializeTemplateCallsiteLiterals() {
1087 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1088 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1089}
1090
1091
1092void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) {
1093 for (int i = 0; i < count; ++i) {
1094 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1095 }
1096}
1097
1098
1099PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function,
1100 PreParserExpressionList args,
1101 int pos) {
1102 return pre_parser_->factory()->NewCall(function, args, pos);
1103}
1104
1105PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function,
1106 PreParserExpressionList args,
1107 int pos) {
1108 return pre_parser_->factory()->NewCallNew(function, args, pos);
1109}
1110
1111
1112void PreParserTraits::ParseArrowFunctionFormalParameterList(
1113 PreParserFormalParameters* parameters,
1114 PreParserExpression params, const Scanner::Location& params_loc,
1115 Scanner::Location* duplicate_loc, bool* ok) {
1116 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter
1117 // lists that are too long.
1118}
1119
1120
1121PreParserExpression PreParserTraits::ParseDoExpression(bool* ok) {
1122 return pre_parser_->ParseDoExpression(ok);
1123}
1124
1125
1126PreParserExpression PreParserTraits::RewriteNonPattern(
1127 PreParserExpression expr, const ExpressionClassifier* classifier,
1128 bool* ok) {
1129 pre_parser_->ValidateExpression(classifier, ok);
1130 return expr;
1131}
1132
1133
1134PreParserExpression PreParserTraits::RewriteNonPatternArguments(
1135 PreParserExpression args, const ExpressionClassifier* classifier,
1136 bool* ok) {
1137 pre_parser_->ValidateExpression(classifier, ok);
1138 return args;
1139}
1140
1141
1142PreParserExpression PreParserTraits::RewriteNonPatternObjectLiteralProperty(
1143 PreParserExpression property, const ExpressionClassifier* classifier,
1144 bool* ok) {
1145 pre_parser_->ValidateExpression(classifier, ok);
1146 return property;
1147}
1148
1149
1150PreParserStatementList PreParser::ParseEagerFunctionBody(
1151 PreParserIdentifier function_name, int pos,
1152 const PreParserFormalParameters& parameters, FunctionKind kind,
1153 FunctionLiteral::FunctionType function_type, bool* ok) {
1154 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1155
1156 ParseStatementList(Token::RBRACE, ok);
1157 if (!*ok) return PreParserStatementList();
1158
1159 Expect(Token::RBRACE, ok);
1160 return PreParserStatementList();
1161}
1162
1163
1164PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
1165 PreParserIdentifier function_name, int pos,
1166 const PreParserFormalParameters& parameters, FunctionKind kind,
1167 FunctionLiteral::FunctionType function_type, bool* ok) {
1168 return pre_parser_->ParseEagerFunctionBody(function_name, pos, parameters,
1169 kind, function_type, ok);
1170}
1171
1172} // namespace internal
1173} // namespace v8
1174
1175#endif // V8_PARSING_PREPARSER_H