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