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