1 // 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/parsing/parser-base.h"
10
11 namespace v8 {
12 namespace internal {
13
14 // Whereas the Parser generates AST during the recursive descent,
15 // the PreParser doesn't create a tree. Instead, it passes around minimal
16 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain
17 // just enough data for the upper layer functions. PreParserFactory is
18 // responsible for creating these dummy objects. It provides a similar kind of
19 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is
20 // used.
21
22 class PreParserIdentifier {
23 public:
PreParserIdentifier()24 PreParserIdentifier() : type_(kUnknownIdentifier) {}
Default()25 static PreParserIdentifier Default() {
26 return PreParserIdentifier(kUnknownIdentifier);
27 }
Empty()28 static PreParserIdentifier Empty() {
29 return PreParserIdentifier(kEmptyIdentifier);
30 }
Eval()31 static PreParserIdentifier Eval() {
32 return PreParserIdentifier(kEvalIdentifier);
33 }
Arguments()34 static PreParserIdentifier Arguments() {
35 return PreParserIdentifier(kArgumentsIdentifier);
36 }
Undefined()37 static PreParserIdentifier Undefined() {
38 return PreParserIdentifier(kUndefinedIdentifier);
39 }
FutureReserved()40 static PreParserIdentifier FutureReserved() {
41 return PreParserIdentifier(kFutureReservedIdentifier);
42 }
FutureStrictReserved()43 static PreParserIdentifier FutureStrictReserved() {
44 return PreParserIdentifier(kFutureStrictReservedIdentifier);
45 }
Let()46 static PreParserIdentifier Let() {
47 return PreParserIdentifier(kLetIdentifier);
48 }
Static()49 static PreParserIdentifier Static() {
50 return PreParserIdentifier(kStaticIdentifier);
51 }
Yield()52 static PreParserIdentifier Yield() {
53 return PreParserIdentifier(kYieldIdentifier);
54 }
Prototype()55 static PreParserIdentifier Prototype() {
56 return PreParserIdentifier(kPrototypeIdentifier);
57 }
Constructor()58 static PreParserIdentifier Constructor() {
59 return PreParserIdentifier(kConstructorIdentifier);
60 }
Enum()61 static PreParserIdentifier Enum() {
62 return PreParserIdentifier(kEnumIdentifier);
63 }
Await()64 static PreParserIdentifier Await() {
65 return PreParserIdentifier(kAwaitIdentifier);
66 }
Async()67 static PreParserIdentifier Async() {
68 return PreParserIdentifier(kAsyncIdentifier);
69 }
IsEmpty()70 bool IsEmpty() const { return type_ == kEmptyIdentifier; }
IsEval()71 bool IsEval() const { return type_ == kEvalIdentifier; }
IsArguments()72 bool IsArguments() const { return type_ == kArgumentsIdentifier; }
IsEvalOrArguments()73 bool IsEvalOrArguments() const { return IsEval() || IsArguments(); }
IsUndefined()74 bool IsUndefined() const { return type_ == kUndefinedIdentifier; }
IsLet()75 bool IsLet() const { return type_ == kLetIdentifier; }
IsStatic()76 bool IsStatic() const { return type_ == kStaticIdentifier; }
IsYield()77 bool IsYield() const { return type_ == kYieldIdentifier; }
IsPrototype()78 bool IsPrototype() const { return type_ == kPrototypeIdentifier; }
IsConstructor()79 bool IsConstructor() const { return type_ == kConstructorIdentifier; }
IsEnum()80 bool IsEnum() const { return type_ == kEnumIdentifier; }
IsAwait()81 bool IsAwait() const { return type_ == kAwaitIdentifier; }
IsFutureStrictReserved()82 bool IsFutureStrictReserved() const {
83 return type_ == kFutureStrictReservedIdentifier ||
84 type_ == kLetIdentifier || type_ == kStaticIdentifier ||
85 type_ == kYieldIdentifier;
86 }
87
88 // Allow identifier->name()[->length()] to work. The preparser
89 // does not need the actual positions/lengths of the identifiers.
90 const PreParserIdentifier* operator->() const { return this; }
raw_name()91 const PreParserIdentifier raw_name() const { return *this; }
92
position()93 int position() const { return 0; }
length()94 int length() const { return 0; }
95
96 private:
97 enum Type {
98 kEmptyIdentifier,
99 kUnknownIdentifier,
100 kFutureReservedIdentifier,
101 kFutureStrictReservedIdentifier,
102 kLetIdentifier,
103 kStaticIdentifier,
104 kYieldIdentifier,
105 kEvalIdentifier,
106 kArgumentsIdentifier,
107 kUndefinedIdentifier,
108 kPrototypeIdentifier,
109 kConstructorIdentifier,
110 kEnumIdentifier,
111 kAwaitIdentifier,
112 kAsyncIdentifier
113 };
114
PreParserIdentifier(Type type)115 explicit PreParserIdentifier(Type type) : type_(type), string_(nullptr) {}
116 Type type_;
117 // Only non-nullptr when PreParser.track_unresolved_variables_ is true.
118 const AstRawString* string_;
119 friend class PreParserExpression;
120 friend class PreParser;
121 friend class PreParserFactory;
122 };
123
124
125 class PreParserExpression {
126 public:
PreParserExpression()127 PreParserExpression()
128 : code_(TypeField::encode(kEmpty)), identifiers_(nullptr) {}
129
Empty()130 static PreParserExpression Empty() { return PreParserExpression(); }
131
132 static PreParserExpression Default(
133 ZoneList<const AstRawString*>* identifiers = nullptr) {
134 return PreParserExpression(TypeField::encode(kExpression), identifiers);
135 }
136
Spread(PreParserExpression expression)137 static PreParserExpression Spread(PreParserExpression expression) {
138 return PreParserExpression(TypeField::encode(kSpreadExpression),
139 expression.identifiers_);
140 }
141
FromIdentifier(PreParserIdentifier id,Zone * zone)142 static PreParserExpression FromIdentifier(PreParserIdentifier id,
143 Zone* zone) {
144 PreParserExpression expression(TypeField::encode(kIdentifierExpression) |
145 IdentifierTypeField::encode(id.type_));
146 expression.AddIdentifier(id.string_, zone);
147 return expression;
148 }
149
BinaryOperation(PreParserExpression left,Token::Value op,PreParserExpression right)150 static PreParserExpression BinaryOperation(PreParserExpression left,
151 Token::Value op,
152 PreParserExpression right) {
153 return PreParserExpression(TypeField::encode(kBinaryOperationExpression));
154 }
155
Assignment()156 static PreParserExpression Assignment() {
157 return PreParserExpression(TypeField::encode(kExpression) |
158 ExpressionTypeField::encode(kAssignment));
159 }
160
161 static PreParserExpression ObjectLiteral(
162 ZoneList<const AstRawString*>* identifiers = nullptr) {
163 return PreParserExpression(TypeField::encode(kObjectLiteralExpression),
164 identifiers);
165 }
166
167 static PreParserExpression ArrayLiteral(
168 ZoneList<const AstRawString*>* identifiers = nullptr) {
169 return PreParserExpression(TypeField::encode(kArrayLiteralExpression),
170 identifiers);
171 }
172
StringLiteral()173 static PreParserExpression StringLiteral() {
174 return PreParserExpression(TypeField::encode(kStringLiteralExpression));
175 }
176
UseStrictStringLiteral()177 static PreParserExpression UseStrictStringLiteral() {
178 return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
179 IsUseStrictField::encode(true));
180 }
181
UseAsmStringLiteral()182 static PreParserExpression UseAsmStringLiteral() {
183 return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
184 IsUseAsmField::encode(true));
185 }
186
This()187 static PreParserExpression This() {
188 return PreParserExpression(TypeField::encode(kExpression) |
189 ExpressionTypeField::encode(kThisExpression));
190 }
191
ThisProperty()192 static PreParserExpression ThisProperty() {
193 return PreParserExpression(
194 TypeField::encode(kExpression) |
195 ExpressionTypeField::encode(kThisPropertyExpression));
196 }
197
Property()198 static PreParserExpression Property() {
199 return PreParserExpression(
200 TypeField::encode(kExpression) |
201 ExpressionTypeField::encode(kPropertyExpression));
202 }
203
Call()204 static PreParserExpression Call() {
205 return PreParserExpression(TypeField::encode(kExpression) |
206 ExpressionTypeField::encode(kCallExpression));
207 }
208
CallEval()209 static PreParserExpression CallEval() {
210 return PreParserExpression(
211 TypeField::encode(kExpression) |
212 ExpressionTypeField::encode(kCallEvalExpression));
213 }
214
SuperCallReference()215 static PreParserExpression SuperCallReference() {
216 return PreParserExpression(
217 TypeField::encode(kExpression) |
218 ExpressionTypeField::encode(kSuperCallReference));
219 }
220
NoTemplateTag()221 static PreParserExpression NoTemplateTag() {
222 return PreParserExpression(
223 TypeField::encode(kExpression) |
224 ExpressionTypeField::encode(kNoTemplateTagExpression));
225 }
226
IsEmpty()227 bool IsEmpty() const { return TypeField::decode(code_) == kEmpty; }
228
IsIdentifier()229 bool IsIdentifier() const {
230 return TypeField::decode(code_) == kIdentifierExpression;
231 }
232
AsIdentifier()233 PreParserIdentifier AsIdentifier() const {
234 DCHECK(IsIdentifier());
235 return PreParserIdentifier(IdentifierTypeField::decode(code_));
236 }
237
IsAssignment()238 bool IsAssignment() const {
239 return TypeField::decode(code_) == kExpression &&
240 ExpressionTypeField::decode(code_) == kAssignment;
241 }
242
IsObjectLiteral()243 bool IsObjectLiteral() const {
244 return TypeField::decode(code_) == kObjectLiteralExpression;
245 }
246
IsArrayLiteral()247 bool IsArrayLiteral() const {
248 return TypeField::decode(code_) == kArrayLiteralExpression;
249 }
250
IsStringLiteral()251 bool IsStringLiteral() const {
252 return TypeField::decode(code_) == kStringLiteralExpression;
253 }
254
IsUseStrictLiteral()255 bool IsUseStrictLiteral() const {
256 return TypeField::decode(code_) == kStringLiteralExpression &&
257 IsUseStrictField::decode(code_);
258 }
259
IsUseAsmLiteral()260 bool IsUseAsmLiteral() const {
261 return TypeField::decode(code_) == kStringLiteralExpression &&
262 IsUseAsmField::decode(code_);
263 }
264
IsThis()265 bool IsThis() const {
266 return TypeField::decode(code_) == kExpression &&
267 ExpressionTypeField::decode(code_) == kThisExpression;
268 }
269
IsThisProperty()270 bool IsThisProperty() const {
271 return TypeField::decode(code_) == kExpression &&
272 ExpressionTypeField::decode(code_) == kThisPropertyExpression;
273 }
274
IsProperty()275 bool IsProperty() const {
276 return TypeField::decode(code_) == kExpression &&
277 (ExpressionTypeField::decode(code_) == kPropertyExpression ||
278 ExpressionTypeField::decode(code_) == kThisPropertyExpression);
279 }
280
IsCall()281 bool IsCall() const {
282 return TypeField::decode(code_) == kExpression &&
283 (ExpressionTypeField::decode(code_) == kCallExpression ||
284 ExpressionTypeField::decode(code_) == kCallEvalExpression);
285 }
286
IsDirectEvalCall()287 bool IsDirectEvalCall() const {
288 return TypeField::decode(code_) == kExpression &&
289 ExpressionTypeField::decode(code_) == kCallEvalExpression;
290 }
291
IsSuperCallReference()292 bool IsSuperCallReference() const {
293 return TypeField::decode(code_) == kExpression &&
294 ExpressionTypeField::decode(code_) == kSuperCallReference;
295 }
296
IsValidReferenceExpression()297 bool IsValidReferenceExpression() const {
298 return IsIdentifier() || IsProperty();
299 }
300
301 // At the moment PreParser doesn't track these expression types.
IsFunctionLiteral()302 bool IsFunctionLiteral() const { return false; }
IsCallNew()303 bool IsCallNew() const { return false; }
304
IsNoTemplateTag()305 bool IsNoTemplateTag() const {
306 return TypeField::decode(code_) == kExpression &&
307 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression;
308 }
309
IsSpread()310 bool IsSpread() const {
311 return TypeField::decode(code_) == kSpreadExpression;
312 }
313
AsFunctionLiteral()314 PreParserExpression AsFunctionLiteral() { return *this; }
315
IsBinaryOperation()316 bool IsBinaryOperation() const {
317 return TypeField::decode(code_) == kBinaryOperationExpression;
318 }
319
320 // Dummy implementation for making expression->somefunc() work in both Parser
321 // and PreParser.
322 PreParserExpression* operator->() { return this; }
323
324 // More dummy implementations of things PreParser doesn't need to track:
set_index(int index)325 void set_index(int index) {} // For YieldExpressions
SetShouldEagerCompile()326 void SetShouldEagerCompile() {}
set_should_be_used_once_hint()327 void set_should_be_used_once_hint() {}
328
position()329 int position() const { return kNoSourcePosition; }
set_function_token_position(int position)330 void set_function_token_position(int position) {}
331
set_is_class_field_initializer(bool is_class_field_initializer)332 void set_is_class_field_initializer(bool is_class_field_initializer) {}
333
334 private:
335 enum Type {
336 kEmpty,
337 kExpression,
338 kIdentifierExpression,
339 kStringLiteralExpression,
340 kBinaryOperationExpression,
341 kSpreadExpression,
342 kObjectLiteralExpression,
343 kArrayLiteralExpression
344 };
345
346 enum ExpressionType {
347 kThisExpression,
348 kThisPropertyExpression,
349 kPropertyExpression,
350 kCallExpression,
351 kCallEvalExpression,
352 kSuperCallReference,
353 kNoTemplateTagExpression,
354 kAssignment
355 };
356
357 explicit PreParserExpression(
358 uint32_t expression_code,
359 ZoneList<const AstRawString*>* identifiers = nullptr)
code_(expression_code)360 : code_(expression_code), identifiers_(identifiers) {}
361
AddIdentifier(const AstRawString * identifier,Zone * zone)362 void AddIdentifier(const AstRawString* identifier, Zone* zone) {
363 if (identifier == nullptr) {
364 return;
365 }
366 if (identifiers_ == nullptr) {
367 identifiers_ = new (zone) ZoneList<const AstRawString*>(1, zone);
368 }
369 identifiers_->Add(identifier, zone);
370 }
371
372 // The first three bits are for the Type.
373 typedef BitField<Type, 0, 3> TypeField;
374
375 // The high order bit applies only to nodes which would inherit from the
376 // Expression ASTNode --- This is by necessity, due to the fact that
377 // Expression nodes may be represented as multiple Types, not exclusively
378 // through kExpression.
379 // TODO(caitp, adamk): clean up PreParserExpression bitfields.
380 typedef BitField<bool, 31, 1> ParenthesizedField;
381
382 // The rest of the bits are interpreted depending on the value
383 // of the Type field, so they can share the storage.
384 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField;
385 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField;
386 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseAsmField;
387 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10>
388 IdentifierTypeField;
389 typedef BitField<bool, TypeField::kNext, 1> HasCoverInitializedNameField;
390
391 uint32_t code_;
392 // If the PreParser is used in the identifier tracking mode,
393 // PreParserExpression accumulates identifiers in that expression.
394 ZoneList<const AstRawString*>* identifiers_;
395
396 friend class PreParser;
397 friend class PreParserFactory;
398 template <typename T>
399 friend class PreParserList;
400 };
401
402
403 // The pre-parser doesn't need to build lists of expressions, identifiers, or
404 // the like. If the PreParser is used in identifier tracking mode, it needs to
405 // build lists of identifiers though.
406 template <typename T>
407 class PreParserList {
408 public:
409 // These functions make list->Add(some_expression) work (and do nothing).
PreParserList()410 PreParserList() : length_(0), identifiers_(nullptr) {}
411 PreParserList* operator->() { return this; }
412 void Add(T, Zone* zone);
length()413 int length() const { return length_; }
Null()414 static PreParserList Null() { return PreParserList(-1); }
IsNull()415 bool IsNull() const { return length_ == -1; }
416
417 private:
PreParserList(int n)418 explicit PreParserList(int n) : length_(n), identifiers_(nullptr) {}
419 int length_;
420 ZoneList<const AstRawString*>* identifiers_;
421
422 friend class PreParser;
423 friend class PreParserFactory;
424 };
425
426 template <>
Add(PreParserExpression expression,Zone * zone)427 inline void PreParserList<PreParserExpression>::Add(
428 PreParserExpression expression, Zone* zone) {
429 if (expression.identifiers_ != nullptr) {
430 DCHECK(FLAG_lazy_inner_functions);
431 DCHECK(zone != nullptr);
432 if (identifiers_ == nullptr) {
433 identifiers_ = new (zone) ZoneList<const AstRawString*>(1, zone);
434 }
435 for (auto identifier : (*expression.identifiers_)) {
436 identifiers_->Add(identifier, zone);
437 }
438 }
439 ++length_;
440 }
441
442 template <typename T>
Add(T,Zone * zone)443 void PreParserList<T>::Add(T, Zone* zone) {
444 ++length_;
445 }
446
447 typedef PreParserList<PreParserExpression> PreParserExpressionList;
448
449 class PreParserStatement;
450 typedef PreParserList<PreParserStatement> PreParserStatementList;
451
452 class PreParserStatement {
453 public:
Default()454 static PreParserStatement Default() {
455 return PreParserStatement(kUnknownStatement);
456 }
457
Null()458 static PreParserStatement Null() {
459 return PreParserStatement(kNullStatement);
460 }
461
Empty()462 static PreParserStatement Empty() {
463 return PreParserStatement(kEmptyStatement);
464 }
465
Jump()466 static PreParserStatement Jump() {
467 return PreParserStatement(kJumpStatement);
468 }
469
470 // Creates expression statement from expression.
471 // Preserves being an unparenthesized string literal, possibly
472 // "use strict".
ExpressionStatement(PreParserExpression expression)473 static PreParserStatement ExpressionStatement(
474 PreParserExpression expression) {
475 if (expression.IsUseStrictLiteral()) {
476 return PreParserStatement(kUseStrictExpressionStatement);
477 }
478 if (expression.IsUseAsmLiteral()) {
479 return PreParserStatement(kUseAsmExpressionStatement);
480 }
481 if (expression.IsStringLiteral()) {
482 return PreParserStatement(kStringLiteralExpressionStatement);
483 }
484 return Default();
485 }
486
IsStringLiteral()487 bool IsStringLiteral() {
488 return code_ == kStringLiteralExpressionStatement || IsUseStrictLiteral() ||
489 IsUseAsmLiteral();
490 }
491
IsUseStrictLiteral()492 bool IsUseStrictLiteral() {
493 return code_ == kUseStrictExpressionStatement;
494 }
495
IsUseAsmLiteral()496 bool IsUseAsmLiteral() { return code_ == kUseAsmExpressionStatement; }
497
IsJumpStatement()498 bool IsJumpStatement() {
499 return code_ == kJumpStatement;
500 }
501
IsNullStatement()502 bool IsNullStatement() { return code_ == kNullStatement; }
503
IsEmptyStatement()504 bool IsEmptyStatement() { return code_ == kEmptyStatement; }
505
506 // Dummy implementation for making statement->somefunc() work in both Parser
507 // and PreParser.
508 PreParserStatement* operator->() { return this; }
509
statements()510 PreParserStatementList statements() { return PreParserStatementList(); }
set_scope(Scope * scope)511 void set_scope(Scope* scope) {}
Initialize(PreParserExpression cond,PreParserStatement body)512 void Initialize(PreParserExpression cond, PreParserStatement body) {}
Initialize(PreParserStatement init,PreParserExpression cond,PreParserStatement next,PreParserStatement body)513 void Initialize(PreParserStatement init, PreParserExpression cond,
514 PreParserStatement next, PreParserStatement body) {}
515
516 private:
517 enum Type {
518 kNullStatement,
519 kEmptyStatement,
520 kUnknownStatement,
521 kJumpStatement,
522 kStringLiteralExpressionStatement,
523 kUseStrictExpressionStatement,
524 kUseAsmExpressionStatement,
525 };
526
PreParserStatement(Type code)527 explicit PreParserStatement(Type code) : code_(code) {}
528 Type code_;
529 };
530
531
532 class PreParserFactory {
533 public:
PreParserFactory(AstValueFactory * ast_value_factory)534 explicit PreParserFactory(AstValueFactory* ast_value_factory)
535 : zone_(ast_value_factory->zone()) {}
536
set_zone(Zone * zone)537 void set_zone(Zone* zone) { zone_ = zone; }
538
NewStringLiteral(PreParserIdentifier identifier,int pos)539 PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
540 int pos) {
541 // This is needed for object literal property names. Property names are
542 // normalized to string literals during object literal parsing.
543 PreParserExpression expression = PreParserExpression::Default();
544 expression.AddIdentifier(identifier.string_, zone_);
545 return expression;
546 }
NewNumberLiteral(double number,int pos)547 PreParserExpression NewNumberLiteral(double number,
548 int pos) {
549 return PreParserExpression::Default();
550 }
NewUndefinedLiteral(int pos)551 PreParserExpression NewUndefinedLiteral(int pos) {
552 return PreParserExpression::Default();
553 }
NewRegExpLiteral(PreParserIdentifier js_pattern,int js_flags,int literal_index,int pos)554 PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
555 int js_flags, int literal_index,
556 int pos) {
557 return PreParserExpression::Default();
558 }
NewArrayLiteral(PreParserExpressionList values,int first_spread_index,int literal_index,int pos)559 PreParserExpression NewArrayLiteral(PreParserExpressionList values,
560 int first_spread_index, int literal_index,
561 int pos) {
562 return PreParserExpression::ArrayLiteral(values.identifiers_);
563 }
NewClassLiteralProperty(PreParserExpression key,PreParserExpression value,ClassLiteralProperty::Kind kind,bool is_static,bool is_computed_name)564 PreParserExpression NewClassLiteralProperty(PreParserExpression key,
565 PreParserExpression value,
566 ClassLiteralProperty::Kind kind,
567 bool is_static,
568 bool is_computed_name) {
569 return PreParserExpression::Default();
570 }
NewObjectLiteralProperty(PreParserExpression key,PreParserExpression value,ObjectLiteralProperty::Kind kind,bool is_computed_name)571 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
572 PreParserExpression value,
573 ObjectLiteralProperty::Kind kind,
574 bool is_computed_name) {
575 return PreParserExpression::Default(value.identifiers_);
576 }
NewObjectLiteralProperty(PreParserExpression key,PreParserExpression value,bool is_computed_name)577 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
578 PreParserExpression value,
579 bool is_computed_name) {
580 return PreParserExpression::Default(value.identifiers_);
581 }
NewObjectLiteral(PreParserExpressionList properties,int literal_index,int boilerplate_properties,int pos)582 PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
583 int literal_index,
584 int boilerplate_properties,
585 int pos) {
586 return PreParserExpression::ObjectLiteral(properties.identifiers_);
587 }
NewVariableProxy(void * variable)588 PreParserExpression NewVariableProxy(void* variable) {
589 return PreParserExpression::Default();
590 }
NewProperty(PreParserExpression obj,PreParserExpression key,int pos)591 PreParserExpression NewProperty(PreParserExpression obj,
592 PreParserExpression key,
593 int pos) {
594 if (obj.IsThis()) {
595 return PreParserExpression::ThisProperty();
596 }
597 return PreParserExpression::Property();
598 }
NewUnaryOperation(Token::Value op,PreParserExpression expression,int pos)599 PreParserExpression NewUnaryOperation(Token::Value op,
600 PreParserExpression expression,
601 int pos) {
602 return PreParserExpression::Default();
603 }
NewBinaryOperation(Token::Value op,PreParserExpression left,PreParserExpression right,int pos)604 PreParserExpression NewBinaryOperation(Token::Value op,
605 PreParserExpression left,
606 PreParserExpression right, int pos) {
607 return PreParserExpression::BinaryOperation(left, op, right);
608 }
NewCompareOperation(Token::Value op,PreParserExpression left,PreParserExpression right,int pos)609 PreParserExpression NewCompareOperation(Token::Value op,
610 PreParserExpression left,
611 PreParserExpression right, int pos) {
612 return PreParserExpression::Default();
613 }
NewRewritableExpression(PreParserExpression expression)614 PreParserExpression NewRewritableExpression(PreParserExpression expression) {
615 return expression;
616 }
NewAssignment(Token::Value op,PreParserExpression left,PreParserExpression right,int pos)617 PreParserExpression NewAssignment(Token::Value op,
618 PreParserExpression left,
619 PreParserExpression right,
620 int pos) {
621 return PreParserExpression::Assignment();
622 }
NewYield(PreParserExpression generator_object,PreParserExpression expression,int pos,Yield::OnException on_exception)623 PreParserExpression NewYield(PreParserExpression generator_object,
624 PreParserExpression expression, int pos,
625 Yield::OnException on_exception) {
626 return PreParserExpression::Default();
627 }
NewConditional(PreParserExpression condition,PreParserExpression then_expression,PreParserExpression else_expression,int pos)628 PreParserExpression NewConditional(PreParserExpression condition,
629 PreParserExpression then_expression,
630 PreParserExpression else_expression,
631 int pos) {
632 return PreParserExpression::Default();
633 }
NewCountOperation(Token::Value op,bool is_prefix,PreParserExpression expression,int pos)634 PreParserExpression NewCountOperation(Token::Value op,
635 bool is_prefix,
636 PreParserExpression expression,
637 int pos) {
638 return PreParserExpression::Default();
639 }
640 PreParserExpression NewCall(
641 PreParserExpression expression, PreParserExpressionList arguments,
642 int pos, Call::PossiblyEval possibly_eval = Call::NOT_EVAL) {
643 if (possibly_eval == Call::IS_POSSIBLY_EVAL) {
644 DCHECK(expression.IsIdentifier() && expression.AsIdentifier().IsEval());
645 return PreParserExpression::CallEval();
646 }
647 return PreParserExpression::Call();
648 }
NewCallNew(PreParserExpression expression,PreParserExpressionList arguments,int pos)649 PreParserExpression NewCallNew(PreParserExpression expression,
650 PreParserExpressionList arguments,
651 int pos) {
652 return PreParserExpression::Default();
653 }
NewReturnStatement(PreParserExpression expression,int pos)654 PreParserStatement NewReturnStatement(PreParserExpression expression,
655 int pos) {
656 return PreParserStatement::Jump();
657 }
NewFunctionLiteral(PreParserIdentifier name,Scope * scope,PreParserStatementList body,int materialized_literal_count,int expected_property_count,int parameter_count,int function_length,FunctionLiteral::ParameterFlag has_duplicate_parameters,FunctionLiteral::FunctionType function_type,FunctionLiteral::EagerCompileHint eager_compile_hint,int position,bool has_braces)658 PreParserExpression NewFunctionLiteral(
659 PreParserIdentifier name, Scope* scope, PreParserStatementList body,
660 int materialized_literal_count, int expected_property_count,
661 int parameter_count, int function_length,
662 FunctionLiteral::ParameterFlag has_duplicate_parameters,
663 FunctionLiteral::FunctionType function_type,
664 FunctionLiteral::EagerCompileHint eager_compile_hint, int position,
665 bool has_braces) {
666 return PreParserExpression::Default();
667 }
668
NewSpread(PreParserExpression expression,int pos,int expr_pos)669 PreParserExpression NewSpread(PreParserExpression expression, int pos,
670 int expr_pos) {
671 return PreParserExpression::Spread(expression);
672 }
673
NewEmptyParentheses(int pos)674 PreParserExpression NewEmptyParentheses(int pos) {
675 return PreParserExpression::Default();
676 }
677
NewEmptyStatement(int pos)678 PreParserStatement NewEmptyStatement(int pos) {
679 return PreParserStatement::Default();
680 }
681
NewBlock(ZoneList<const AstRawString * > * labels,int capacity,bool ignore_completion_value,int pos)682 PreParserStatement NewBlock(ZoneList<const AstRawString*>* labels,
683 int capacity, bool ignore_completion_value,
684 int pos) {
685 return PreParserStatement::Default();
686 }
687
NewDebuggerStatement(int pos)688 PreParserStatement NewDebuggerStatement(int pos) {
689 return PreParserStatement::Default();
690 }
691
NewExpressionStatement(PreParserExpression expr,int pos)692 PreParserStatement NewExpressionStatement(PreParserExpression expr, int pos) {
693 return PreParserStatement::ExpressionStatement(expr);
694 }
695
NewIfStatement(PreParserExpression condition,PreParserStatement then_statement,PreParserStatement else_statement,int pos)696 PreParserStatement NewIfStatement(PreParserExpression condition,
697 PreParserStatement then_statement,
698 PreParserStatement else_statement,
699 int pos) {
700 // This must return a jump statement iff both clauses are jump statements.
701 return else_statement.IsJumpStatement() ? then_statement : else_statement;
702 }
703
NewBreakStatement(PreParserStatement target,int pos)704 PreParserStatement NewBreakStatement(PreParserStatement target, int pos) {
705 return PreParserStatement::Jump();
706 }
707
NewContinueStatement(PreParserStatement target,int pos)708 PreParserStatement NewContinueStatement(PreParserStatement target, int pos) {
709 return PreParserStatement::Jump();
710 }
711
NewWithStatement(Scope * scope,PreParserExpression expression,PreParserStatement statement,int pos)712 PreParserStatement NewWithStatement(Scope* scope,
713 PreParserExpression expression,
714 PreParserStatement statement, int pos) {
715 return PreParserStatement::Default();
716 }
717
NewDoWhileStatement(ZoneList<const AstRawString * > * labels,int pos)718 PreParserStatement NewDoWhileStatement(ZoneList<const AstRawString*>* labels,
719 int pos) {
720 return PreParserStatement::Default();
721 }
722
NewWhileStatement(ZoneList<const AstRawString * > * labels,int pos)723 PreParserStatement NewWhileStatement(ZoneList<const AstRawString*>* labels,
724 int pos) {
725 return PreParserStatement::Default();
726 }
727
NewSwitchStatement(ZoneList<const AstRawString * > * labels,int pos)728 PreParserStatement NewSwitchStatement(ZoneList<const AstRawString*>* labels,
729 int pos) {
730 return PreParserStatement::Default();
731 }
732
NewCaseClause(PreParserExpression label,PreParserStatementList statements,int pos)733 PreParserStatement NewCaseClause(PreParserExpression label,
734 PreParserStatementList statements, int pos) {
735 return PreParserStatement::Default();
736 }
737
NewForStatement(ZoneList<const AstRawString * > * labels,int pos)738 PreParserStatement NewForStatement(ZoneList<const AstRawString*>* labels,
739 int pos) {
740 return PreParserStatement::Default();
741 }
742
NewForEachStatement(ForEachStatement::VisitMode visit_mode,ZoneList<const AstRawString * > * labels,int pos)743 PreParserStatement NewForEachStatement(ForEachStatement::VisitMode visit_mode,
744 ZoneList<const AstRawString*>* labels,
745 int pos) {
746 return PreParserStatement::Default();
747 }
748
749 // Return the object itself as AstVisitor and implement the needed
750 // dummy method right in this class.
visitor()751 PreParserFactory* visitor() { return this; }
ast_properties()752 int* ast_properties() {
753 static int dummy = 42;
754 return &dummy;
755 }
756
757 private:
758 Zone* zone_;
759 };
760
761
762 struct PreParserFormalParameters : FormalParametersBase {
PreParserFormalParametersPreParserFormalParameters763 explicit PreParserFormalParameters(DeclarationScope* scope)
764 : FormalParametersBase(scope) {}
atPreParserFormalParameters765 PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy
766 };
767
768
769 class PreParser;
770
771 class PreParserTarget {
772 public:
PreParserTarget(ParserBase<PreParser> * preparser,PreParserStatement statement)773 PreParserTarget(ParserBase<PreParser>* preparser,
774 PreParserStatement statement) {}
775 };
776
777 class PreParserTargetScope {
778 public:
PreParserTargetScope(ParserBase<PreParser> * preparser)779 explicit PreParserTargetScope(ParserBase<PreParser>* preparser) {}
780 };
781
782 template <>
783 struct ParserTypes<PreParser> {
784 typedef ParserBase<PreParser> Base;
785 typedef PreParser Impl;
786
787 // PreParser doesn't need to store generator variables.
788 typedef void Variable;
789
790 // Return types for traversing functions.
791 typedef PreParserIdentifier Identifier;
792 typedef PreParserExpression Expression;
793 typedef PreParserExpression FunctionLiteral;
794 typedef PreParserExpression ObjectLiteralProperty;
795 typedef PreParserExpression ClassLiteralProperty;
796 typedef PreParserExpressionList ExpressionList;
797 typedef PreParserExpressionList ObjectPropertyList;
798 typedef PreParserExpressionList ClassPropertyList;
799 typedef PreParserFormalParameters FormalParameters;
800 typedef PreParserStatement Statement;
801 typedef PreParserStatementList StatementList;
802 typedef PreParserStatement Block;
803 typedef PreParserStatement BreakableStatement;
804 typedef PreParserStatement IterationStatement;
805
806 // For constructing objects returned by the traversing functions.
807 typedef PreParserFactory Factory;
808
809 typedef PreParserTarget Target;
810 typedef PreParserTargetScope TargetScope;
811 };
812
813
814 // Preparsing checks a JavaScript program and emits preparse-data that helps
815 // a later parsing to be faster.
816 // See preparse-data-format.h for the data format.
817
818 // The PreParser checks that the syntax follows the grammar for JavaScript,
819 // and collects some information about the program along the way.
820 // The grammar check is only performed in order to understand the program
821 // sufficiently to deduce some information about it, that can be used
822 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
823 // rather it is to speed up properly written and correct programs.
824 // That means that contextual checks (like a label being declared where
825 // it is used) are generally omitted.
826 class PreParser : public ParserBase<PreParser> {
827 friend class ParserBase<PreParser>;
828 friend class v8::internal::ExpressionClassifier<ParserTypes<PreParser>>;
829
830 public:
831 typedef PreParserIdentifier Identifier;
832 typedef PreParserExpression Expression;
833 typedef PreParserStatement Statement;
834
835 enum PreParseResult {
836 kPreParseStackOverflow,
837 kPreParseAbort,
838 kPreParseSuccess
839 };
840
841 PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory,
842 PendingCompilationErrorHandler* pending_error_handler,
843 RuntimeCallStats* runtime_call_stats, uintptr_t stack_limit)
844 : ParserBase<PreParser>(zone, scanner, stack_limit, nullptr,
845 ast_value_factory, runtime_call_stats),
846 use_counts_(nullptr),
847 track_unresolved_variables_(false),
848 pending_error_handler_(pending_error_handler) {}
849
850 static bool const IsPreParser() { return true; }
851
852 PreParserLogger* logger() { return &log_; }
853
854 // Pre-parse the program from the character stream; returns true on
855 // success (even if parsing failed, the pre-parse data successfully
856 // captured the syntax error), and false if a stack-overflow happened
857 // during parsing.
858 PreParseResult PreParseProgram(int* materialized_literals = 0,
859 bool is_module = false) {
860 DCHECK_NULL(scope_state_);
861 DeclarationScope* scope = NewScriptScope();
862
863 // ModuleDeclarationInstantiation for Source Text Module Records creates a
864 // new Module Environment Record whose outer lexical environment record is
865 // the global scope.
866 if (is_module) scope = NewModuleScope(scope);
867
868 FunctionState top_scope(&function_state_, &scope_state_, scope);
869 bool ok = true;
870 int start_position = scanner()->peek_location().beg_pos;
871 parsing_module_ = is_module;
872 PreParserStatementList body;
873 ParseStatementList(body, Token::EOS, &ok);
874 if (stack_overflow()) return kPreParseStackOverflow;
875 if (!ok) {
876 ReportUnexpectedToken(scanner()->current_token());
877 } else if (is_strict(this->scope()->language_mode())) {
878 CheckStrictOctalLiteral(start_position, scanner()->location().end_pos,
879 &ok);
880 CheckDecimalLiteralWithLeadingZero(start_position,
881 scanner()->location().end_pos);
882 }
883 if (materialized_literals) {
884 *materialized_literals = function_state_->materialized_literal_count();
885 }
886 return kPreParseSuccess;
887 }
888
889 // Parses a single function literal, from the opening parentheses before
890 // parameters to the closing brace after the body.
891 // Returns a FunctionEntry describing the body of the function in enough
892 // detail that it can be lazily compiled.
893 // The scanner is expected to have matched the "function" or "function*"
894 // keyword and parameters, and have consumed the initial '{'.
895 // At return, unless an error occurred, the scanner is positioned before the
896 // the final '}'.
897 PreParseResult PreParseFunction(FunctionKind kind,
898 DeclarationScope* function_scope,
899 bool parsing_module,
900 bool track_unresolved_variables,
901 bool may_abort, int* use_counts);
902
903 private:
904 // These types form an algebra over syntactic categories that is just
905 // rich enough to let us recognize and propagate the constructs that
906 // are either being counted in the preparser data, or is important
907 // to throw the correct syntax error exceptions.
908
909 // All ParseXXX functions take as the last argument an *ok parameter
910 // which is set to false if parsing failed; it is unchanged otherwise.
911 // By making the 'exception handling' explicit, we are forced to check
912 // for failure at the call sites.
913
914 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
915 PreParserIdentifier function_name, int pos,
916 const PreParserFormalParameters& parameters, FunctionKind kind,
917 FunctionLiteral::FunctionType function_type, bool* ok);
918
919 // Indicates that we won't switch from the preparser to the preparser; we'll
920 // just stay where we are.
921 bool AllowsLazyParsingWithoutUnresolvedVariables() const { return false; }
922 bool parse_lazily() const { return false; }
923
924 V8_INLINE LazyParsingResult SkipFunction(
925 FunctionKind kind, DeclarationScope* function_scope, int* num_parameters,
926 int* function_length, bool* has_duplicate_parameters,
927 int* materialized_literal_count, int* expected_property_count,
928 bool is_inner_function, bool may_abort, bool* ok) {
929 UNREACHABLE();
930 return kLazyParsingComplete;
931 }
932 Expression ParseFunctionLiteral(
933 Identifier name, Scanner::Location function_name_location,
934 FunctionNameValidity function_name_validity, FunctionKind kind,
935 int function_token_pos, FunctionLiteral::FunctionType function_type,
936 LanguageMode language_mode, bool* ok);
937 LazyParsingResult ParseStatementListAndLogFunction(
938 PreParserFormalParameters* formals, bool has_duplicate_parameters,
939 bool maybe_abort, bool* ok);
940
941 struct TemplateLiteralState {};
942
943 V8_INLINE TemplateLiteralState OpenTemplateLiteral(int pos) {
944 return TemplateLiteralState();
945 }
946 V8_INLINE void AddTemplateExpression(TemplateLiteralState* state,
947 PreParserExpression expression) {}
948 V8_INLINE void AddTemplateSpan(TemplateLiteralState* state, bool tail) {}
949 V8_INLINE PreParserExpression CloseTemplateLiteral(
950 TemplateLiteralState* state, int start, PreParserExpression tag);
951 V8_INLINE void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
952
953 V8_INLINE void SetLanguageMode(Scope* scope, LanguageMode mode) {
954 scope->SetLanguageMode(mode);
955 }
956 V8_INLINE void SetAsmModule() {}
957
958 V8_INLINE void MarkCollectedTailCallExpressions() {}
959 V8_INLINE void MarkTailPosition(PreParserExpression expression) {}
960
961 V8_INLINE PreParserExpressionList
962 PrepareSpreadArguments(PreParserExpressionList list) {
963 return list;
964 }
965
966 V8_INLINE PreParserExpression SpreadCall(PreParserExpression function,
967 PreParserExpressionList args,
968 int pos);
969 V8_INLINE PreParserExpression SpreadCallNew(PreParserExpression function,
970 PreParserExpressionList args,
971 int pos);
972
973 V8_INLINE PreParserExpression
974 RewriteSuperCall(PreParserExpression call_expression) {
975 return call_expression;
976 }
977
978 V8_INLINE void RewriteDestructuringAssignments() {}
979
980 V8_INLINE PreParserExpression RewriteExponentiation(PreParserExpression left,
981 PreParserExpression right,
982 int pos) {
983 return left;
984 }
985 V8_INLINE PreParserExpression RewriteAssignExponentiation(
986 PreParserExpression left, PreParserExpression right, int pos) {
987 return left;
988 }
989
990 V8_INLINE PreParserExpression
991 RewriteAwaitExpression(PreParserExpression value, int pos) {
992 return value;
993 }
994 V8_INLINE void PrepareAsyncFunctionBody(PreParserStatementList body,
995 FunctionKind kind, int pos) {}
996 V8_INLINE void RewriteAsyncFunctionBody(PreParserStatementList body,
997 PreParserStatement block,
998 PreParserExpression return_value,
999 bool* ok) {}
1000 V8_INLINE PreParserExpression RewriteYieldStar(PreParserExpression generator,
1001 PreParserExpression expression,
1002 int pos) {
1003 return PreParserExpression::Default();
1004 }
1005 V8_INLINE void RewriteNonPattern(bool* ok) { ValidateExpression(ok); }
1006
1007 void DeclareAndInitializeVariables(
1008 PreParserStatement block,
1009 const DeclarationDescriptor* declaration_descriptor,
1010 const DeclarationParsingResult::Declaration* declaration,
1011 ZoneList<const AstRawString*>* names, bool* ok);
1012
1013 V8_INLINE ZoneList<const AstRawString*>* DeclareLabel(
1014 ZoneList<const AstRawString*>* labels, PreParserExpression expr,
1015 bool* ok) {
1016 DCHECK(!expr.AsIdentifier().IsEnum());
1017 DCHECK(!parsing_module_ || !expr.AsIdentifier().IsAwait());
1018 DCHECK(is_sloppy(language_mode()) ||
1019 !IsFutureStrictReserved(expr.AsIdentifier()));
1020 return labels;
1021 }
1022
1023 // TODO(nikolaos): The preparser currently does not keep track of labels.
1024 V8_INLINE bool ContainsLabel(ZoneList<const AstRawString*>* labels,
1025 PreParserIdentifier label) {
1026 return false;
1027 }
1028
1029 V8_INLINE PreParserExpression RewriteReturn(PreParserExpression return_value,
1030 int pos) {
1031 return return_value;
1032 }
1033 V8_INLINE PreParserStatement RewriteSwitchStatement(
1034 PreParserExpression tag, PreParserStatement switch_statement,
1035 PreParserStatementList cases, Scope* scope) {
1036 return PreParserStatement::Default();
1037 }
1038 V8_INLINE void RewriteCatchPattern(CatchInfo* catch_info, bool* ok) {}
1039 V8_INLINE void ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) {}
1040 V8_INLINE PreParserStatement RewriteTryStatement(
1041 PreParserStatement try_block, PreParserStatement catch_block,
1042 PreParserStatement finally_block, const CatchInfo& catch_info, int pos) {
1043 return PreParserStatement::Default();
1044 }
1045
1046 V8_INLINE PreParserExpression RewriteDoExpression(PreParserStatement body,
1047 int pos, bool* ok) {
1048 return PreParserExpression::Default();
1049 }
1050
1051 // TODO(nikolaos): The preparser currently does not keep track of labels
1052 // and targets.
1053 V8_INLINE PreParserStatement LookupBreakTarget(PreParserIdentifier label,
1054 bool* ok) {
1055 return PreParserStatement::Default();
1056 }
1057 V8_INLINE PreParserStatement LookupContinueTarget(PreParserIdentifier label,
1058 bool* ok) {
1059 return PreParserStatement::Default();
1060 }
1061
1062 V8_INLINE PreParserStatement DeclareFunction(
1063 PreParserIdentifier variable_name, PreParserExpression function, int pos,
1064 bool is_generator, bool is_async, ZoneList<const AstRawString*>* names,
1065 bool* ok) {
1066 return Statement::Default();
1067 }
1068
1069 V8_INLINE PreParserStatement
1070 DeclareClass(PreParserIdentifier variable_name, PreParserExpression value,
1071 ZoneList<const AstRawString*>* names, int class_token_pos,
1072 int end_pos, bool* ok) {
1073 return PreParserStatement::Default();
1074 }
1075 V8_INLINE void DeclareClassVariable(PreParserIdentifier name,
1076 Scope* block_scope, ClassInfo* class_info,
1077 int class_token_pos, bool* ok) {}
1078 V8_INLINE void DeclareClassProperty(PreParserIdentifier class_name,
1079 PreParserExpression property,
1080 ClassInfo* class_info, bool* ok) {}
1081 V8_INLINE PreParserExpression RewriteClassLiteral(PreParserIdentifier name,
1082 ClassInfo* class_info,
1083 int pos, bool* ok) {
1084 return PreParserExpression::Default();
1085 }
1086
1087 V8_INLINE PreParserStatement DeclareNative(PreParserIdentifier name, int pos,
1088 bool* ok) {
1089 return PreParserStatement::Default();
1090 }
1091
1092 V8_INLINE void QueueDestructuringAssignmentForRewriting(
1093 PreParserExpression assignment) {}
1094 V8_INLINE void QueueNonPatternForRewriting(PreParserExpression expr,
1095 bool* ok) {}
1096
1097 // Helper functions for recursive descent.
1098 V8_INLINE bool IsEval(PreParserIdentifier identifier) const {
1099 return identifier.IsEval();
1100 }
1101
1102 V8_INLINE bool IsArguments(PreParserIdentifier identifier) const {
1103 return identifier.IsArguments();
1104 }
1105
1106 V8_INLINE bool IsEvalOrArguments(PreParserIdentifier identifier) const {
1107 return identifier.IsEvalOrArguments();
1108 }
1109
1110 V8_INLINE bool IsUndefined(PreParserIdentifier identifier) const {
1111 return identifier.IsUndefined();
1112 }
1113
1114 V8_INLINE bool IsAwait(PreParserIdentifier identifier) const {
1115 return identifier.IsAwait();
1116 }
1117
1118 V8_INLINE bool IsFutureStrictReserved(PreParserIdentifier identifier) const {
1119 return identifier.IsFutureStrictReserved();
1120 }
1121
1122 // Returns true if the expression is of type "this.foo".
1123 V8_INLINE static bool IsThisProperty(PreParserExpression expression) {
1124 return expression.IsThisProperty();
1125 }
1126
1127 V8_INLINE static bool IsIdentifier(PreParserExpression expression) {
1128 return expression.IsIdentifier();
1129 }
1130
1131 V8_INLINE static PreParserIdentifier AsIdentifier(
1132 PreParserExpression expression) {
1133 return expression.AsIdentifier();
1134 }
1135
1136 V8_INLINE static PreParserExpression AsIdentifierExpression(
1137 PreParserExpression expression) {
1138 return expression;
1139 }
1140
1141 V8_INLINE bool IsPrototype(PreParserIdentifier identifier) const {
1142 return identifier.IsPrototype();
1143 }
1144
1145 V8_INLINE bool IsConstructor(PreParserIdentifier identifier) const {
1146 return identifier.IsConstructor();
1147 }
1148
1149 V8_INLINE bool IsDirectEvalCall(PreParserExpression expression) const {
1150 return expression.IsDirectEvalCall();
1151 }
1152
1153 V8_INLINE static bool IsBoilerplateProperty(PreParserExpression property) {
1154 // PreParser doesn't count boilerplate properties.
1155 return false;
1156 }
1157
1158 V8_INLINE bool IsNative(PreParserExpression expr) const {
1159 // Preparsing is disabled for extensions (because the extension
1160 // details aren't passed to lazily compiled functions), so we
1161 // don't accept "native function" in the preparser and there is
1162 // no need to keep track of "native".
1163 return false;
1164 }
1165
1166 V8_INLINE static bool IsArrayIndex(PreParserIdentifier string,
1167 uint32_t* index) {
1168 return false;
1169 }
1170
1171 V8_INLINE bool IsUseStrictDirective(PreParserStatement statement) const {
1172 return statement.IsUseStrictLiteral();
1173 }
1174
1175 V8_INLINE bool IsUseAsmDirective(PreParserStatement statement) const {
1176 return statement.IsUseAsmLiteral();
1177 }
1178
1179 V8_INLINE bool IsStringLiteral(PreParserStatement statement) const {
1180 return statement.IsStringLiteral();
1181 }
1182
1183 V8_INLINE static PreParserExpression GetPropertyValue(
1184 PreParserExpression property) {
1185 return PreParserExpression::Default();
1186 }
1187
1188 V8_INLINE static void GetDefaultStrings(
1189 PreParserIdentifier* default_string,
1190 PreParserIdentifier* star_default_star_string) {}
1191
1192 // Functions for encapsulating the differences between parsing and preparsing;
1193 // operations interleaved with the recursive descent.
1194 V8_INLINE static void PushLiteralName(PreParserIdentifier id) {}
1195 V8_INLINE static void PushVariableName(PreParserIdentifier id) {}
1196 V8_INLINE void PushPropertyName(PreParserExpression expression) {}
1197 V8_INLINE void PushEnclosingName(PreParserIdentifier name) {}
1198 V8_INLINE static void AddFunctionForNameInference(
1199 PreParserExpression expression) {}
1200 V8_INLINE static void InferFunctionName() {}
1201
1202 V8_INLINE static void CheckAssigningFunctionLiteralToProperty(
1203 PreParserExpression left, PreParserExpression right) {}
1204
1205 V8_INLINE static PreParserExpression MarkExpressionAsAssigned(
1206 PreParserExpression expression) {
1207 // TODO(marja): To be able to produce the same errors, the preparser needs
1208 // to start tracking which expressions are variables and which are assigned.
1209 return expression;
1210 }
1211
1212 V8_INLINE bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
1213 PreParserExpression y,
1214 Token::Value op,
1215 int pos) {
1216 return false;
1217 }
1218
1219 V8_INLINE PreParserExpression BuildUnaryExpression(
1220 PreParserExpression expression, Token::Value op, int pos) {
1221 return PreParserExpression::Default();
1222 }
1223
1224 V8_INLINE PreParserExpression BuildIteratorResult(PreParserExpression value,
1225 bool done) {
1226 return PreParserExpression::Default();
1227 }
1228
1229 V8_INLINE PreParserStatement
1230 BuildInitializationBlock(DeclarationParsingResult* parsing_result,
1231 ZoneList<const AstRawString*>* names, bool* ok) {
1232 return PreParserStatement::Default();
1233 }
1234
1235 V8_INLINE PreParserStatement
1236 InitializeForEachStatement(PreParserStatement stmt, PreParserExpression each,
1237 PreParserExpression subject,
1238 PreParserStatement body, int each_keyword_pos) {
1239 return stmt;
1240 }
1241
1242 V8_INLINE PreParserStatement RewriteForVarInLegacy(const ForInfo& for_info) {
1243 return PreParserStatement::Null();
1244 }
1245 V8_INLINE void DesugarBindingInForEachStatement(
1246 ForInfo* for_info, PreParserStatement* body_block,
1247 PreParserExpression* each_variable, bool* ok) {}
1248 V8_INLINE PreParserStatement CreateForEachStatementTDZ(
1249 PreParserStatement init_block, const ForInfo& for_info, bool* ok) {
1250 return init_block;
1251 }
1252
1253 V8_INLINE StatementT DesugarLexicalBindingsInForStatement(
1254 PreParserStatement loop, PreParserStatement init,
1255 PreParserExpression cond, PreParserStatement next,
1256 PreParserStatement body, Scope* inner_scope, const ForInfo& for_info,
1257 bool* ok) {
1258 return loop;
1259 }
1260
1261 V8_INLINE PreParserExpression
1262 NewThrowReferenceError(MessageTemplate::Template message, int pos) {
1263 return PreParserExpression::Default();
1264 }
1265
1266 V8_INLINE PreParserExpression NewThrowSyntaxError(
1267 MessageTemplate::Template message, PreParserIdentifier arg, int pos) {
1268 return PreParserExpression::Default();
1269 }
1270
1271 V8_INLINE PreParserExpression NewThrowTypeError(
1272 MessageTemplate::Template message, PreParserIdentifier arg, int pos) {
1273 return PreParserExpression::Default();
1274 }
1275
1276 // Reporting errors.
1277 V8_INLINE void ReportMessageAt(Scanner::Location source_location,
1278 MessageTemplate::Template message,
1279 const char* arg = NULL,
1280 ParseErrorType error_type = kSyntaxError) {
1281 pending_error_handler_->ReportMessageAt(source_location.beg_pos,
1282 source_location.end_pos, message,
1283 arg, error_type);
1284 }
1285
1286 V8_INLINE void ReportMessageAt(Scanner::Location source_location,
1287 MessageTemplate::Template message,
1288 PreParserIdentifier arg,
1289 ParseErrorType error_type = kSyntaxError) {
1290 UNREACHABLE();
1291 }
1292
1293 // "null" return type creators.
1294 V8_INLINE static PreParserIdentifier EmptyIdentifier() {
1295 return PreParserIdentifier::Empty();
1296 }
1297 V8_INLINE static bool IsEmptyIdentifier(PreParserIdentifier name) {
1298 return name.IsEmpty();
1299 }
1300 V8_INLINE static PreParserExpression EmptyExpression() {
1301 return PreParserExpression::Empty();
1302 }
1303 V8_INLINE static PreParserExpression EmptyLiteral() {
1304 return PreParserExpression::Default();
1305 }
1306 V8_INLINE static PreParserExpression EmptyObjectLiteralProperty() {
1307 return PreParserExpression::Default();
1308 }
1309 V8_INLINE static PreParserExpression EmptyClassLiteralProperty() {
1310 return PreParserExpression::Default();
1311 }
1312 V8_INLINE static PreParserExpression EmptyFunctionLiteral() {
1313 return PreParserExpression::Default();
1314 }
1315
1316 V8_INLINE static bool IsEmptyExpression(PreParserExpression expr) {
1317 return expr.IsEmpty();
1318 }
1319
1320 V8_INLINE static PreParserExpressionList NullExpressionList() {
1321 return PreParserExpressionList::Null();
1322 }
1323
1324 V8_INLINE static bool IsNullExpressionList(PreParserExpressionList exprs) {
1325 return exprs.IsNull();
1326 }
1327
1328 V8_INLINE static PreParserStatementList NullStatementList() {
1329 return PreParserStatementList::Null();
1330 }
1331
1332 V8_INLINE static bool IsNullStatementList(PreParserStatementList stmts) {
1333 return stmts.IsNull();
1334 }
1335
1336 V8_INLINE static PreParserStatement NullStatement() {
1337 return PreParserStatement::Null();
1338 }
1339
1340 V8_INLINE bool IsNullStatement(PreParserStatement stmt) {
1341 return stmt.IsNullStatement();
1342 }
1343
1344 V8_INLINE bool IsEmptyStatement(PreParserStatement stmt) {
1345 return stmt.IsEmptyStatement();
1346 }
1347
1348 V8_INLINE static PreParserStatement NullBlock() {
1349 return PreParserStatement::Null();
1350 }
1351
1352 V8_INLINE PreParserIdentifier EmptyIdentifierString() const {
1353 return PreParserIdentifier::Default();
1354 }
1355
1356 // Odd-ball literal creators.
1357 V8_INLINE PreParserExpression GetLiteralTheHole(int position) {
1358 return PreParserExpression::Default();
1359 }
1360
1361 V8_INLINE PreParserExpression GetLiteralUndefined(int position) {
1362 return PreParserExpression::Default();
1363 }
1364
1365 // Producing data during the recursive descent.
1366 PreParserIdentifier GetSymbol() const;
1367
1368 V8_INLINE PreParserIdentifier GetNextSymbol() const {
1369 return PreParserIdentifier::Default();
1370 }
1371
1372 V8_INLINE PreParserIdentifier GetNumberAsSymbol() const {
1373 return PreParserIdentifier::Default();
1374 }
1375
1376 V8_INLINE PreParserExpression ThisExpression(int pos = kNoSourcePosition) {
1377 return PreParserExpression::This();
1378 }
1379
1380 V8_INLINE PreParserExpression NewSuperPropertyReference(int pos) {
1381 return PreParserExpression::Default();
1382 }
1383
1384 V8_INLINE PreParserExpression NewSuperCallReference(int pos) {
1385 return PreParserExpression::SuperCallReference();
1386 }
1387
1388 V8_INLINE PreParserExpression NewTargetExpression(int pos) {
1389 return PreParserExpression::Default();
1390 }
1391
1392 V8_INLINE PreParserExpression FunctionSentExpression(int pos) {
1393 return PreParserExpression::Default();
1394 }
1395
1396 V8_INLINE PreParserExpression ExpressionFromLiteral(Token::Value token,
1397 int pos) {
1398 return PreParserExpression::Default();
1399 }
1400
1401 PreParserExpression ExpressionFromIdentifier(
1402 PreParserIdentifier name, int start_position,
1403 InferName infer = InferName::kYes);
1404
1405 V8_INLINE PreParserExpression ExpressionFromString(int pos) {
1406 if (scanner()->UnescapedLiteralMatches("use strict", 10)) {
1407 return PreParserExpression::UseStrictStringLiteral();
1408 }
1409 return PreParserExpression::StringLiteral();
1410 }
1411
1412 V8_INLINE PreParserExpressionList NewExpressionList(int size) const {
1413 return PreParserExpressionList();
1414 }
1415
1416 V8_INLINE PreParserExpressionList NewObjectPropertyList(int size) const {
1417 return PreParserExpressionList();
1418 }
1419
1420 V8_INLINE PreParserExpressionList NewClassPropertyList(int size) const {
1421 return PreParserExpressionList();
1422 }
1423
1424 V8_INLINE PreParserStatementList NewStatementList(int size) const {
1425 return PreParserStatementList();
1426 }
1427
1428 PreParserStatementList NewCaseClauseList(int size) {
1429 return PreParserStatementList();
1430 }
1431
1432 V8_INLINE PreParserExpression
1433 NewV8Intrinsic(PreParserIdentifier name, PreParserExpressionList arguments,
1434 int pos, bool* ok) {
1435 return PreParserExpression::Default();
1436 }
1437
1438 V8_INLINE PreParserStatement NewThrowStatement(PreParserExpression exception,
1439 int pos) {
1440 return PreParserStatement::Jump();
1441 }
1442
1443 V8_INLINE void AddParameterInitializationBlock(
1444 const PreParserFormalParameters& parameters, PreParserStatementList body,
1445 bool is_async, bool* ok) {}
1446
1447 V8_INLINE void AddFormalParameter(PreParserFormalParameters* parameters,
1448 PreParserExpression pattern,
1449 PreParserExpression initializer,
1450 int initializer_end_position,
1451 bool is_rest) {
1452 parameters->UpdateArityAndFunctionLength(!initializer.IsEmpty(), is_rest);
1453 }
1454
1455 V8_INLINE void DeclareFormalParameter(DeclarationScope* scope,
1456 PreParserIdentifier parameter) {
1457 if (!classifier()->is_simple_parameter_list()) {
1458 scope->SetHasNonSimpleParameters();
1459 }
1460 }
1461
1462 V8_INLINE void DeclareArrowFunctionFormalParameters(
1463 PreParserFormalParameters* parameters, PreParserExpression params,
1464 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
1465 bool* ok) {
1466 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect
1467 // parameter lists that are too long.
1468 }
1469
1470 V8_INLINE void ReindexLiterals(const PreParserFormalParameters& parameters) {}
1471
1472 V8_INLINE PreParserExpression NoTemplateTag() {
1473 return PreParserExpression::NoTemplateTag();
1474 }
1475
1476 V8_INLINE static bool IsTaggedTemplate(const PreParserExpression tag) {
1477 return !tag.IsNoTemplateTag();
1478 }
1479
1480 V8_INLINE void MaterializeUnspreadArgumentsLiterals(int count) {
1481 for (int i = 0; i < count; ++i) {
1482 function_state_->NextMaterializedLiteralIndex();
1483 }
1484 }
1485
1486 V8_INLINE PreParserExpression
1487 ExpressionListToExpression(PreParserExpressionList args) {
1488 return PreParserExpression::Default(args.identifiers_);
1489 }
1490
1491 V8_INLINE void AddAccessorPrefixToFunctionName(bool is_get,
1492 PreParserExpression function,
1493 PreParserIdentifier name) {}
1494 V8_INLINE void SetFunctionNameFromPropertyName(PreParserExpression property,
1495 PreParserIdentifier name) {}
1496 V8_INLINE void SetFunctionNameFromIdentifierRef(
1497 PreParserExpression value, PreParserExpression identifier) {}
1498
1499 V8_INLINE ZoneList<typename ExpressionClassifier::Error>*
1500 GetReportedErrorList() const {
1501 return function_state_->GetReportedErrorList();
1502 }
1503
1504 V8_INLINE ZoneList<PreParserExpression>* GetNonPatternList() const {
1505 return function_state_->non_patterns_to_rewrite();
1506 }
1507
1508 V8_INLINE void CountUsage(v8::Isolate::UseCounterFeature feature) {
1509 if (use_counts_ != nullptr) ++use_counts_[feature];
1510 }
1511
1512 // Preparser's private field members.
1513
1514 int* use_counts_;
1515 bool track_unresolved_variables_;
1516 PreParserLogger log_;
1517 PendingCompilationErrorHandler* pending_error_handler_;
1518 };
1519
1520 PreParserExpression PreParser::SpreadCall(PreParserExpression function,
1521 PreParserExpressionList args,
1522 int pos) {
1523 return factory()->NewCall(function, args, pos);
1524 }
1525
1526 PreParserExpression PreParser::SpreadCallNew(PreParserExpression function,
1527 PreParserExpressionList args,
1528 int pos) {
1529 return factory()->NewCallNew(function, args, pos);
1530 }
1531
1532 PreParserStatementList PreParser::ParseEagerFunctionBody(
1533 PreParserIdentifier function_name, int pos,
1534 const PreParserFormalParameters& parameters, FunctionKind kind,
1535 FunctionLiteral::FunctionType function_type, bool* ok) {
1536 PreParserStatementList result;
1537
1538 Scope* inner_scope = scope();
1539 if (!parameters.is_simple) inner_scope = NewScope(BLOCK_SCOPE);
1540
1541 {
1542 BlockState block_state(&scope_state_, inner_scope);
1543 ParseStatementList(result, Token::RBRACE, ok);
1544 if (!*ok) return PreParserStatementList();
1545 }
1546
1547 Expect(Token::RBRACE, ok);
1548 return result;
1549 }
1550
1551 PreParserExpression PreParser::CloseTemplateLiteral(TemplateLiteralState* state,
1552 int start,
1553 PreParserExpression tag) {
1554 if (IsTaggedTemplate(tag)) {
1555 // Emulate generation of array literals for tag callsite
1556 // 1st is array of cooked strings, second is array of raw strings
1557 function_state_->NextMaterializedLiteralIndex();
1558 function_state_->NextMaterializedLiteralIndex();
1559 }
1560 return EmptyExpression();
1561 }
1562
1563 } // namespace internal
1564 } // namespace v8
1565
1566 #endif // V8_PARSING_PREPARSER_H
1567