Line data Source code
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_PARSER_H_
6 : #define V8_PARSING_PARSER_H_
7 :
8 : #include <cstddef>
9 :
10 : #include "src/ast/ast-source-ranges.h"
11 : #include "src/ast/ast.h"
12 : #include "src/ast/scopes.h"
13 : #include "src/base/compiler-specific.h"
14 : #include "src/base/threaded-list.h"
15 : #include "src/globals.h"
16 : #include "src/parsing/parser-base.h"
17 : #include "src/parsing/parsing.h"
18 : #include "src/parsing/preparser.h"
19 : #include "src/pointer-with-payload.h"
20 : #include "src/zone/zone-chunk-list.h"
21 :
22 : namespace v8 {
23 :
24 : class ScriptCompiler;
25 :
26 : namespace internal {
27 :
28 : class ConsumedPreparseData;
29 : class ParseInfo;
30 : class ParserTarget;
31 : class ParserTargetScope;
32 : class PendingCompilationErrorHandler;
33 : class PreparseData;
34 :
35 : class FunctionEntry {
36 : public:
37 : enum {
38 : kStartPositionIndex,
39 : kEndPositionIndex,
40 : kNumParametersIndex,
41 : kFlagsIndex,
42 : kNumInnerFunctionsIndex,
43 : kSize
44 : };
45 :
46 : explicit FunctionEntry(Vector<unsigned> backing)
47 : : backing_(backing) { }
48 :
49 : FunctionEntry() : backing_() { }
50 :
51 : class LanguageModeField : public BitField<LanguageMode, 0, 1> {};
52 : class UsesSuperPropertyField
53 : : public BitField<bool, LanguageModeField::kNext, 1> {};
54 :
55 : static uint32_t EncodeFlags(LanguageMode language_mode,
56 : bool uses_super_property) {
57 : return LanguageModeField::encode(language_mode) |
58 : UsesSuperPropertyField::encode(uses_super_property);
59 : }
60 :
61 : int start_pos() const { return backing_[kStartPositionIndex]; }
62 : int end_pos() const { return backing_[kEndPositionIndex]; }
63 : int num_parameters() const { return backing_[kNumParametersIndex]; }
64 : LanguageMode language_mode() const {
65 : return LanguageModeField::decode(backing_[kFlagsIndex]);
66 : }
67 : bool uses_super_property() const {
68 : return UsesSuperPropertyField::decode(backing_[kFlagsIndex]);
69 : }
70 : int num_inner_functions() const { return backing_[kNumInnerFunctionsIndex]; }
71 :
72 : bool is_valid() const { return !backing_.is_empty(); }
73 :
74 : private:
75 : Vector<unsigned> backing_;
76 : };
77 :
78 :
79 : // ----------------------------------------------------------------------------
80 : // JAVASCRIPT PARSING
81 :
82 : class Parser;
83 :
84 :
85 : struct ParserFormalParameters : FormalParametersBase {
86 : struct Parameter : public ZoneObject {
87 4020394 : Parameter(Expression* pattern, Expression* initializer, int position,
88 : int initializer_end_position, bool is_rest)
89 : : initializer_and_is_rest(initializer, is_rest),
90 : pattern(pattern),
91 : position(position),
92 4039199 : initializer_end_position(initializer_end_position) {}
93 :
94 : PointerWithPayload<Expression, bool, 1> initializer_and_is_rest;
95 :
96 : Expression* pattern;
97 : Expression* initializer() const {
98 : return initializer_and_is_rest.GetPointer();
99 : }
100 : int position;
101 : int initializer_end_position;
102 : inline bool is_rest() const { return initializer_and_is_rest.GetPayload(); }
103 :
104 : Parameter* next_parameter = nullptr;
105 : bool is_simple() const {
106 186774 : return pattern->IsVariableProxy() && initializer() == nullptr &&
107 : !is_rest();
108 : }
109 :
110 : const AstRawString* name() const {
111 : DCHECK(is_simple());
112 2772391 : return pattern->AsVariableProxy()->raw_name();
113 : }
114 :
115 6957286 : Parameter** next() { return &next_parameter; }
116 : Parameter* const* next() const { return &next_parameter; }
117 : };
118 :
119 : void set_strict_parameter_error(const Scanner::Location& loc,
120 : MessageTemplate message) {
121 362431 : strict_error_loc = loc;
122 362431 : strict_error_message = message;
123 : }
124 :
125 : bool has_duplicate() const { return duplicate_loc.IsValid(); }
126 : void ValidateDuplicate(Parser* parser) const;
127 : void ValidateStrictMode(Parser* parser) const;
128 :
129 : explicit ParserFormalParameters(DeclarationScope* scope)
130 1839060 : : FormalParametersBase(scope) {}
131 :
132 : base::ThreadedList<Parameter> params;
133 : Scanner::Location duplicate_loc = Scanner::Location::invalid();
134 : Scanner::Location strict_error_loc = Scanner::Location::invalid();
135 : MessageTemplate strict_error_message = MessageTemplate::kNone;
136 : };
137 :
138 : template <>
139 : struct ParserTypes<Parser> {
140 : typedef ParserBase<Parser> Base;
141 : typedef Parser Impl;
142 :
143 : // Return types for traversing functions.
144 : typedef v8::internal::Block* Block;
145 : typedef v8::internal::BreakableStatement* BreakableStatement;
146 : typedef ClassLiteral::Property* ClassLiteralProperty;
147 : typedef ZonePtrList<ClassLiteral::Property>* ClassPropertyList;
148 : typedef v8::internal::Expression* Expression;
149 : typedef ScopedPtrList<v8::internal::Expression> ExpressionList;
150 : typedef ParserFormalParameters FormalParameters;
151 : typedef v8::internal::ForStatement* ForStatement;
152 : typedef v8::internal::FunctionLiteral* FunctionLiteral;
153 : typedef const AstRawString* Identifier;
154 : typedef v8::internal::IterationStatement* IterationStatement;
155 : typedef ObjectLiteral::Property* ObjectLiteralProperty;
156 : typedef ScopedPtrList<v8::internal::ObjectLiteralProperty> ObjectPropertyList;
157 : typedef v8::internal::Statement* Statement;
158 : typedef ScopedPtrList<v8::internal::Statement> StatementList;
159 : typedef v8::internal::Suspend* Suspend;
160 :
161 : // For constructing objects returned by the traversing functions.
162 : typedef AstNodeFactory Factory;
163 :
164 : // Other implementation-specific functions.
165 : typedef v8::internal::FuncNameInferrer FuncNameInferrer;
166 : typedef v8::internal::SourceRange SourceRange;
167 : typedef v8::internal::SourceRangeScope SourceRangeScope;
168 : typedef ParserTarget Target;
169 : typedef ParserTargetScope TargetScope;
170 : };
171 :
172 : class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
173 : public:
174 : explicit Parser(ParseInfo* info);
175 4902613 : ~Parser() {
176 2451307 : delete reusable_preparser_;
177 2451306 : reusable_preparser_ = nullptr;
178 2451303 : }
179 :
180 : static bool IsPreParser() { return false; }
181 :
182 : void ParseOnBackground(ParseInfo* info);
183 :
184 : // Initializes an empty scope chain for top-level scripts, or scopes which
185 : // consist of only the native context.
186 : void InitializeEmptyScopeChain(ParseInfo* info);
187 :
188 : // Deserialize the scope chain prior to parsing in which the script is going
189 : // to be executed. If the script is a top-level script, or the scope chain
190 : // consists of only a native context, maybe_outer_scope_info should be an
191 : // empty handle.
192 : //
193 : // This only deserializes the scope chain, but doesn't connect the scopes to
194 : // their corresponding scope infos. Therefore, looking up variables in the
195 : // deserialized scopes is not possible.
196 : void DeserializeScopeChain(Isolate* isolate, ParseInfo* info,
197 : MaybeHandle<ScopeInfo> maybe_outer_scope_info,
198 : Scope::DeserializationMode mode =
199 : Scope::DeserializationMode::kScopesOnly);
200 :
201 : // Move statistics to Isolate
202 : void UpdateStatistics(Isolate* isolate, Handle<Script> script);
203 : void HandleSourceURLComments(Isolate* isolate, Handle<Script> script);
204 :
205 : private:
206 : friend class ParserBase<Parser>;
207 : friend struct ParserFormalParameters;
208 : friend class i::ExpressionScope<ParserTypes<Parser>>;
209 : friend class i::VariableDeclarationParsingScope<ParserTypes<Parser>>;
210 : friend class i::ParameterDeclarationParsingScope<ParserTypes<Parser>>;
211 : friend class i::ArrowHeadParsingScope<ParserTypes<Parser>>;
212 : friend bool v8::internal::parsing::ParseProgram(ParseInfo*, Isolate*);
213 : friend bool v8::internal::parsing::ParseFunction(
214 : ParseInfo*, Handle<SharedFunctionInfo> shared_info, Isolate*);
215 :
216 : bool AllowsLazyParsingWithoutUnresolvedVariables() const {
217 : return scope()->AllowsLazyParsingWithoutUnresolvedVariables(
218 4158561 : original_scope_);
219 : }
220 :
221 : bool parse_lazily() const { return mode_ == PARSE_LAZILY; }
222 : enum Mode { PARSE_LAZILY, PARSE_EAGERLY };
223 :
224 : class ParsingModeScope {
225 : public:
226 : ParsingModeScope(Parser* parser, Mode mode)
227 3746224 : : parser_(parser), old_mode_(parser->mode_) {
228 3746224 : parser_->mode_ = mode;
229 : }
230 3746224 : ~ParsingModeScope() { parser_->mode_ = old_mode_; }
231 :
232 : private:
233 : Parser* parser_;
234 : Mode old_mode_;
235 : };
236 :
237 : // Runtime encoding of different completion modes.
238 : enum CompletionKind {
239 : kNormalCompletion,
240 : kThrowCompletion,
241 : kAbruptCompletion
242 : };
243 :
244 : Variable* NewTemporary(const AstRawString* name) {
245 151246 : return scope()->NewTemporary(name);
246 : }
247 :
248 : void PrepareGeneratorVariables();
249 :
250 : // Returns nullptr if parsing failed.
251 : FunctionLiteral* ParseProgram(Isolate* isolate, ParseInfo* info);
252 :
253 : FunctionLiteral* ParseFunction(Isolate* isolate, ParseInfo* info,
254 : Handle<SharedFunctionInfo> shared_info);
255 : FunctionLiteral* DoParseFunction(Isolate* isolate, ParseInfo* info,
256 : const AstRawString* raw_name);
257 :
258 : // Called by ParseProgram after setting up the scanner.
259 : FunctionLiteral* DoParseProgram(Isolate* isolate, ParseInfo* info);
260 :
261 : // Parse with the script as if the source is implicitly wrapped in a function.
262 : // We manually construct the AST and scopes for a top-level function and the
263 : // function wrapper.
264 : void ParseWrapped(Isolate* isolate, ParseInfo* info,
265 : ScopedPtrList<Statement>* body, DeclarationScope* scope,
266 : Zone* zone);
267 :
268 : ZonePtrList<const AstRawString>* PrepareWrappedArguments(Isolate* isolate,
269 : ParseInfo* info,
270 : Zone* zone);
271 :
272 7507492 : PreParser* reusable_preparser() {
273 7507492 : if (reusable_preparser_ == nullptr) {
274 : reusable_preparser_ = new PreParser(
275 : &preparser_zone_, &scanner_, stack_limit_, ast_value_factory(),
276 : pending_error_handler(), runtime_call_stats_, logger_, -1,
277 397448 : parsing_module_, parsing_on_main_thread_);
278 : #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
279 : SET_ALLOW(natives);
280 : SET_ALLOW(harmony_public_fields);
281 : SET_ALLOW(harmony_static_fields);
282 : SET_ALLOW(harmony_dynamic_import);
283 : SET_ALLOW(harmony_import_meta);
284 : SET_ALLOW(harmony_private_fields);
285 397458 : SET_ALLOW(harmony_private_methods);
286 : SET_ALLOW(eval_cache);
287 : #undef SET_ALLOW
288 397458 : preparse_data_buffer_.reserve(128);
289 : }
290 7507486 : return reusable_preparser_;
291 : }
292 :
293 : void ParseModuleItemList(ScopedPtrList<Statement>* body);
294 : Statement* ParseModuleItem();
295 : const AstRawString* ParseModuleSpecifier();
296 : void ParseImportDeclaration();
297 : Statement* ParseExportDeclaration();
298 : Statement* ParseExportDefault();
299 : void ParseExportStar();
300 : struct ExportClauseData {
301 : const AstRawString* export_name;
302 : const AstRawString* local_name;
303 : Scanner::Location location;
304 : };
305 : ZoneChunkList<ExportClauseData>* ParseExportClause(
306 : Scanner::Location* reserved_loc);
307 : struct NamedImport : public ZoneObject {
308 : const AstRawString* import_name;
309 : const AstRawString* local_name;
310 : const Scanner::Location location;
311 : NamedImport(const AstRawString* import_name, const AstRawString* local_name,
312 : Scanner::Location location)
313 : : import_name(import_name),
314 : local_name(local_name),
315 1244 : location(location) {}
316 : };
317 : ZonePtrList<const NamedImport>* ParseNamedImports(int pos);
318 : Statement* BuildInitializationBlock(DeclarationParsingResult* parsing_result);
319 : void DeclareLabel(ZonePtrList<const AstRawString>** labels,
320 : ZonePtrList<const AstRawString>** own_labels,
321 : VariableProxy* expr);
322 : bool ContainsLabel(ZonePtrList<const AstRawString>* labels,
323 : const AstRawString* label);
324 : Expression* RewriteReturn(Expression* return_value, int pos);
325 : Statement* RewriteSwitchStatement(SwitchStatement* switch_statement,
326 : Scope* scope);
327 : Block* RewriteCatchPattern(CatchInfo* catch_info);
328 : void ReportVarRedeclarationIn(const AstRawString* name, Scope* scope);
329 : Statement* RewriteTryStatement(Block* try_block, Block* catch_block,
330 : const SourceRange& catch_range,
331 : Block* finally_block,
332 : const SourceRange& finally_range,
333 : const CatchInfo& catch_info, int pos);
334 : void ParseAndRewriteGeneratorFunctionBody(int pos, FunctionKind kind,
335 : ScopedPtrList<Statement>* body);
336 : void ParseAndRewriteAsyncGeneratorFunctionBody(
337 : int pos, FunctionKind kind, ScopedPtrList<Statement>* body);
338 : void DeclareFunctionNameVar(const AstRawString* function_name,
339 : FunctionLiteral::FunctionType function_type,
340 : DeclarationScope* function_scope);
341 :
342 : Statement* DeclareFunction(const AstRawString* variable_name,
343 : FunctionLiteral* function, VariableMode mode,
344 : VariableKind kind, int beg_pos, int end_pos,
345 : ZonePtrList<const AstRawString>* names);
346 : Variable* CreateSyntheticContextVariable(const AstRawString* synthetic_name);
347 : FunctionLiteral* CreateInitializerFunction(
348 : const char* name, DeclarationScope* scope,
349 : ZonePtrList<ClassLiteral::Property>* fields);
350 :
351 : bool IdentifierEquals(const AstRawString* identifier,
352 : const AstRawString* other) {
353 : return identifier == other;
354 : }
355 :
356 : Statement* DeclareClass(const AstRawString* variable_name, Expression* value,
357 : ZonePtrList<const AstRawString>* names,
358 : int class_token_pos, int end_pos);
359 : void DeclareClassVariable(const AstRawString* name, ClassInfo* class_info,
360 : int class_token_pos);
361 : void DeclareClassProperty(const AstRawString* class_name,
362 : ClassLiteralProperty* property, bool is_constructor,
363 : ClassInfo* class_info);
364 : void DeclareClassField(ClassLiteralProperty* property,
365 : const AstRawString* property_name, bool is_static,
366 : bool is_computed_name, bool is_private,
367 : ClassInfo* class_info);
368 : Expression* RewriteClassLiteral(Scope* block_scope, const AstRawString* name,
369 : ClassInfo* class_info, int pos, int end_pos);
370 : Statement* DeclareNative(const AstRawString* name, int pos);
371 :
372 : Block* IgnoreCompletion(Statement* statement);
373 :
374 : Scope* NewHiddenCatchScope();
375 :
376 : bool HasCheckedSyntax() {
377 2118168 : return scope()->GetDeclarationScope()->has_checked_syntax();
378 : }
379 :
380 : // PatternRewriter and associated methods defined in pattern-rewriter.cc.
381 : friend class PatternRewriter;
382 : void InitializeVariables(
383 : ScopedPtrList<Statement>* statements, VariableKind kind,
384 : const DeclarationParsingResult::Declaration* declaration);
385 :
386 : Block* RewriteForVarInLegacy(const ForInfo& for_info);
387 : void DesugarBindingInForEachStatement(ForInfo* for_info, Block** body_block,
388 : Expression** each_variable);
389 : Block* CreateForEachStatementTDZ(Block* init_block, const ForInfo& for_info);
390 :
391 : Statement* DesugarLexicalBindingsInForStatement(
392 : ForStatement* loop, Statement* init, Expression* cond, Statement* next,
393 : Statement* body, Scope* inner_scope, const ForInfo& for_info);
394 :
395 : FunctionLiteral* ParseFunctionLiteral(
396 : const AstRawString* name, Scanner::Location function_name_location,
397 : FunctionNameValidity function_name_validity, FunctionKind kind,
398 : int function_token_position, FunctionLiteral::FunctionType type,
399 : LanguageMode language_mode,
400 : ZonePtrList<const AstRawString>* arguments_for_wrapped_function);
401 :
402 : ObjectLiteral* InitializeObjectLiteral(ObjectLiteral* object_literal) {
403 591056 : object_literal->CalculateEmitStore(main_zone());
404 : return object_literal;
405 : }
406 :
407 : bool IsPropertyWithPrivateFieldKey(Expression* property);
408 :
409 : // Insert initializer statements for var-bindings shadowing parameter bindings
410 : // from a non-simple parameter list.
411 : void InsertShadowingVarBindingInitializers(Block* block);
412 :
413 : // Implement sloppy block-scoped functions, ES2015 Annex B 3.3
414 : void InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope);
415 :
416 : void DeclareUnboundVariable(const AstRawString* name, VariableMode mode,
417 : InitializationFlag init, int pos);
418 : V8_WARN_UNUSED_RESULT
419 : VariableProxy* DeclareBoundVariable(const AstRawString* name,
420 : VariableMode mode, int pos);
421 : void DeclareAndBindVariable(VariableProxy* proxy, VariableKind kind,
422 : VariableMode mode, InitializationFlag init,
423 : Scope* declaration_scope, bool* was_added,
424 : int begin, int end = kNoSourcePosition);
425 : V8_WARN_UNUSED_RESULT
426 : Variable* DeclareVariable(const AstRawString* name, VariableKind kind,
427 : VariableMode mode, InitializationFlag init,
428 : Scope* declaration_scope, bool* was_added,
429 : int begin, int end = kNoSourcePosition);
430 : void Declare(Declaration* declaration, const AstRawString* name,
431 : VariableKind kind, VariableMode mode, InitializationFlag init,
432 : Scope* declaration_scope, bool* was_added, int var_begin_pos,
433 : int var_end_pos = kNoSourcePosition);
434 :
435 : bool TargetStackContainsLabel(const AstRawString* label);
436 : BreakableStatement* LookupBreakTarget(const AstRawString* label);
437 : IterationStatement* LookupContinueTarget(const AstRawString* label);
438 :
439 : // Factory methods.
440 : FunctionLiteral* DefaultConstructor(const AstRawString* name, bool call_super,
441 : int pos, int end_pos);
442 :
443 : // Skip over a lazy function, either using cached data if we have it, or
444 : // by parsing the function with PreParser. Consumes the ending }.
445 : // In case the preparser detects an error it cannot identify, it resets the
446 : // scanner- and preparser state to the initial one, before PreParsing the
447 : // function.
448 : // SkipFunction returns true if it correctly parsed the function, including
449 : // cases where we detect an error. It returns false, if we needed to stop
450 : // parsing or could not identify an error correctly, meaning the caller needs
451 : // to fully reparse. In this case it resets the scanner and preparser state.
452 : bool SkipFunction(const AstRawString* function_name, FunctionKind kind,
453 : FunctionLiteral::FunctionType function_type,
454 : DeclarationScope* function_scope, int* num_parameters,
455 : ProducedPreparseData** produced_preparsed_scope_data);
456 :
457 : Block* BuildParameterInitializationBlock(
458 : const ParserFormalParameters& parameters);
459 : Block* BuildRejectPromiseOnException(Block* block);
460 :
461 : void ParseFunction(
462 : ScopedPtrList<Statement>* body, const AstRawString* function_name,
463 : int pos, FunctionKind kind, FunctionLiteral::FunctionType function_type,
464 : DeclarationScope* function_scope, int* num_parameters,
465 : int* function_length, bool* has_duplicate_parameters,
466 : int* expected_property_count, int* suspend_count,
467 : ZonePtrList<const AstRawString>* arguments_for_wrapped_function);
468 :
469 : void ThrowPendingError(Isolate* isolate, Handle<Script> script);
470 :
471 : class TemplateLiteral : public ZoneObject {
472 : public:
473 38558 : TemplateLiteral(Zone* zone, int pos)
474 38558 : : cooked_(8, zone), raw_(8, zone), expressions_(8, zone), pos_(pos) {}
475 :
476 35461 : const ZonePtrList<const AstRawString>* cooked() const { return &cooked_; }
477 35461 : const ZonePtrList<const AstRawString>* raw() const { return &raw_; }
478 35461 : const ZonePtrList<Expression>* expressions() const { return &expressions_; }
479 : int position() const { return pos_; }
480 :
481 : void AddTemplateSpan(const AstRawString* cooked, const AstRawString* raw,
482 : int end, Zone* zone) {
483 : DCHECK_NOT_NULL(raw);
484 83838 : cooked_.Add(cooked, zone);
485 83838 : raw_.Add(raw, zone);
486 : }
487 :
488 : void AddExpression(Expression* expression, Zone* zone) {
489 48377 : expressions_.Add(expression, zone);
490 : }
491 :
492 : private:
493 : ZonePtrList<const AstRawString> cooked_;
494 : ZonePtrList<const AstRawString> raw_;
495 : ZonePtrList<Expression> expressions_;
496 : int pos_;
497 : };
498 :
499 : typedef TemplateLiteral* TemplateLiteralState;
500 :
501 : TemplateLiteralState OpenTemplateLiteral(int pos);
502 : // "should_cook" means that the span can be "cooked": in tagged template
503 : // literals, both the raw and "cooked" representations are available to user
504 : // code ("cooked" meaning that escape sequences are converted to their
505 : // interpreted values). Invalid escape sequences cause the cooked span
506 : // to be represented by undefined, instead of being a syntax error.
507 : // "tail" indicates that this span is the last in the literal.
508 : void AddTemplateSpan(TemplateLiteralState* state, bool should_cook,
509 : bool tail);
510 : void AddTemplateExpression(TemplateLiteralState* state,
511 : Expression* expression);
512 : Expression* CloseTemplateLiteral(TemplateLiteralState* state, int start,
513 : Expression* tag);
514 :
515 : ArrayLiteral* ArrayLiteralFromListWithSpread(
516 : const ScopedPtrList<Expression>& list);
517 : Expression* SpreadCall(Expression* function,
518 : const ScopedPtrList<Expression>& args, int pos,
519 : Call::PossiblyEval is_possibly_eval);
520 : Expression* SpreadCallNew(Expression* function,
521 : const ScopedPtrList<Expression>& args, int pos);
522 : Expression* RewriteSuperCall(Expression* call_expression);
523 :
524 : void SetLanguageMode(Scope* scope, LanguageMode mode);
525 : void SetAsmModule();
526 :
527 : Expression* RewriteSpreads(ArrayLiteral* lit);
528 :
529 : Expression* BuildInitialYield(int pos, FunctionKind kind);
530 : Assignment* BuildCreateJSGeneratorObject(int pos, FunctionKind kind);
531 :
532 : // Generic AST generator for throwing errors from compiled code.
533 : Expression* NewThrowError(Runtime::FunctionId function_id,
534 : MessageTemplate message, const AstRawString* arg,
535 : int pos);
536 :
537 : Statement* CheckCallable(Variable* var, Expression* error, int pos);
538 :
539 : void RewriteAsyncFunctionBody(ScopedPtrList<Statement>* body, Block* block,
540 : Expression* return_value);
541 :
542 : void AddArrowFunctionFormalParameters(ParserFormalParameters* parameters,
543 : Expression* params, int end_pos);
544 : void SetFunctionName(Expression* value, const AstRawString* name,
545 : const AstRawString* prefix = nullptr);
546 :
547 : // Helper functions for recursive descent.
548 : V8_INLINE bool IsEval(const AstRawString* identifier) const {
549 : return identifier == ast_value_factory()->eval_string();
550 : }
551 :
552 : V8_INLINE bool IsAsync(const AstRawString* identifier) const {
553 : return identifier == ast_value_factory()->async_string();
554 : }
555 :
556 : V8_INLINE bool IsArguments(const AstRawString* identifier) const {
557 32824690 : return identifier == ast_value_factory()->arguments_string();
558 : }
559 :
560 : V8_INLINE bool IsEvalOrArguments(const AstRawString* identifier) const {
561 9326202 : return IsEval(identifier) || IsArguments(identifier);
562 : }
563 :
564 : // Returns true if the expression is of type "this.foo".
565 : V8_INLINE static bool IsThisProperty(Expression* expression) {
566 : DCHECK_NOT_NULL(expression);
567 5620330 : Property* property = expression->AsProperty();
568 9605011 : return property != nullptr && property->obj()->IsThisExpression();
569 : }
570 :
571 : // This returns true if the expression is an indentifier (wrapped
572 : // inside a variable proxy). We exclude the case of 'this', which
573 : // has been converted to a variable proxy.
574 : V8_INLINE static bool IsIdentifier(Expression* expression) {
575 66402506 : VariableProxy* operand = expression->AsVariableProxy();
576 96728587 : return operand != nullptr && !operand->is_new_target();
577 : }
578 :
579 : V8_INLINE static const AstRawString* AsIdentifier(Expression* expression) {
580 : DCHECK(IsIdentifier(expression));
581 : return expression->AsVariableProxy()->raw_name();
582 : }
583 :
584 : V8_INLINE VariableProxy* AsIdentifierExpression(Expression* expression) {
585 15713 : return expression->AsVariableProxy();
586 : }
587 :
588 : V8_INLINE bool IsConstructor(const AstRawString* identifier) const {
589 : return identifier == ast_value_factory()->constructor_string();
590 : }
591 :
592 : V8_INLINE bool IsName(const AstRawString* identifier) const {
593 : return identifier == ast_value_factory()->name_string();
594 : }
595 :
596 : V8_INLINE static bool IsBoilerplateProperty(
597 : ObjectLiteral::Property* property) {
598 : return !property->IsPrototype();
599 : }
600 :
601 : V8_INLINE bool IsNative(Expression* expr) const {
602 : DCHECK_NOT_NULL(expr);
603 3638 : return expr->IsVariableProxy() &&
604 1819 : expr->AsVariableProxy()->raw_name() ==
605 : ast_value_factory()->native_string();
606 : }
607 :
608 : V8_INLINE static bool IsArrayIndex(const AstRawString* string,
609 : uint32_t* index) {
610 55098 : return string->AsArrayIndex(index);
611 : }
612 :
613 : // Returns true if the statement is an expression statement containing
614 : // a single string literal. If a second argument is given, the literal
615 : // is also compared with it and the result is true only if they are equal.
616 : V8_INLINE bool IsStringLiteral(Statement* statement,
617 : const AstRawString* arg = nullptr) const {
618 1313674 : ExpressionStatement* e_stat = statement->AsExpressionStatement();
619 1313674 : if (e_stat == nullptr) return false;
620 1313673 : Literal* literal = e_stat->expression()->AsLiteral();
621 2621293 : if (literal == nullptr || !literal->IsString()) return false;
622 : return arg == nullptr || literal->AsRawString() == arg;
623 : }
624 :
625 : V8_INLINE void GetDefaultStrings(const AstRawString** default_string,
626 : const AstRawString** dot_default_string) {
627 : *default_string = ast_value_factory()->default_string();
628 : *dot_default_string = ast_value_factory()->dot_default_string();
629 : }
630 :
631 : // Functions for encapsulating the differences between parsing and preparsing;
632 : // operations interleaved with the recursive descent.
633 : V8_INLINE void PushLiteralName(const AstRawString* id) {
634 9174371 : fni_.PushLiteralName(id);
635 : }
636 :
637 : V8_INLINE void PushVariableName(const AstRawString* id) {
638 : fni_.PushVariableName(id);
639 : }
640 :
641 : V8_INLINE void PushPropertyName(Expression* expression) {
642 1769734 : if (expression->IsPropertyName()) {
643 37978 : fni_.PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
644 : } else {
645 1750741 : fni_.PushLiteralName(ast_value_factory()->computed_string());
646 : }
647 : }
648 :
649 : V8_INLINE void PushEnclosingName(const AstRawString* name) {
650 982578 : fni_.PushEnclosingName(name);
651 : }
652 :
653 : V8_INLINE void AddFunctionForNameInference(FunctionLiteral* func_to_infer) {
654 642730 : fni_.AddFunction(func_to_infer);
655 : }
656 :
657 410081 : V8_INLINE void InferFunctionName() { fni_.Infer(); }
658 :
659 : // If we assign a function literal to a property we pretenure the
660 : // literal so it can be added as a constant function property.
661 : V8_INLINE static void CheckAssigningFunctionLiteralToProperty(
662 : Expression* left, Expression* right) {
663 : DCHECK_NOT_NULL(left);
664 9605021 : if (left->IsProperty() && right->IsFunctionLiteral()) {
665 83835 : right->AsFunctionLiteral()->set_pretenure();
666 : }
667 : }
668 :
669 : // A shortcut for performing a ToString operation
670 : V8_INLINE Expression* ToString(Expression* expr) {
671 : if (expr->IsStringLiteral()) return expr;
672 : ScopedPtrList<Expression> args(pointer_buffer());
673 : args.Add(expr);
674 : return factory()->NewCallRuntime(Runtime::kInlineToString, args,
675 : expr->position());
676 : }
677 :
678 : // Returns true if we have a binary expression between two numeric
679 : // literals. In that case, *x will be changed to an expression which is the
680 : // computed value.
681 : bool ShortcutNumericLiteralBinaryExpression(Expression** x, Expression* y,
682 : Token::Value op, int pos);
683 :
684 : // Returns true if we have a binary operation between a binary/n-ary
685 : // expression (with the same operation) and a value, which can be collapsed
686 : // into a single n-ary expression. In that case, *x will be changed to an
687 : // n-ary expression.
688 : bool CollapseNaryExpression(Expression** x, Expression* y, Token::Value op,
689 : int pos, const SourceRange& range);
690 :
691 : // Returns a UnaryExpression or, in one of the following cases, a Literal.
692 : // ! <literal> -> true / false
693 : // + <Number literal> -> <Number literal>
694 : // - <Number literal> -> <Number literal with value negated>
695 : // ~ <literal> -> true / false
696 : Expression* BuildUnaryExpression(Expression* expression, Token::Value op,
697 : int pos);
698 :
699 : // Generate AST node that throws a ReferenceError with the given type.
700 : V8_INLINE Expression* NewThrowReferenceError(MessageTemplate message,
701 : int pos) {
702 : return NewThrowError(Runtime::kNewReferenceError, message,
703 1230 : ast_value_factory()->empty_string(), pos);
704 : }
705 :
706 : // Generate AST node that throws a SyntaxError with the given
707 : // type. The first argument may be null (in the handle sense) in
708 : // which case no arguments are passed to the constructor.
709 : V8_INLINE Expression* NewThrowSyntaxError(MessageTemplate message,
710 : const AstRawString* arg, int pos) {
711 : return NewThrowError(Runtime::kNewSyntaxError, message, arg, pos);
712 : }
713 :
714 : // Generate AST node that throws a TypeError with the given
715 : // type. Both arguments must be non-null (in the handle sense).
716 : V8_INLINE Expression* NewThrowTypeError(MessageTemplate message,
717 : const AstRawString* arg, int pos) {
718 : return NewThrowError(Runtime::kNewTypeError, message, arg, pos);
719 : }
720 :
721 : // Reporting errors.
722 2085135 : void ReportMessageAt(Scanner::Location source_location,
723 : MessageTemplate message, const char* arg = nullptr,
724 : ParseErrorType error_type = kSyntaxError) {
725 2085135 : pending_error_handler()->ReportMessageAt(source_location.beg_pos,
726 : source_location.end_pos, message,
727 2085135 : arg, error_type);
728 : scanner_.set_parser_error();
729 2085135 : }
730 :
731 : // Dummy implementation. The parser should never have a unidentifiable
732 : // error.
733 : V8_INLINE void ReportUnidentifiableError() { UNREACHABLE(); }
734 :
735 78286 : void ReportMessageAt(Scanner::Location source_location,
736 : MessageTemplate message, const AstRawString* arg,
737 : ParseErrorType error_type = kSyntaxError) {
738 78286 : pending_error_handler()->ReportMessageAt(source_location.beg_pos,
739 : source_location.end_pos, message,
740 78286 : arg, error_type);
741 : scanner_.set_parser_error();
742 78286 : }
743 :
744 : void ReportUnexpectedTokenAt(
745 : Scanner::Location location, Token::Value token,
746 : MessageTemplate message = MessageTemplate::kUnexpectedToken);
747 :
748 : // "null" return type creators.
749 : V8_INLINE static std::nullptr_t NullIdentifier() { return nullptr; }
750 : V8_INLINE static std::nullptr_t NullExpression() { return nullptr; }
751 : V8_INLINE static std::nullptr_t NullLiteralProperty() { return nullptr; }
752 : V8_INLINE static ZonePtrList<Expression>* NullExpressionList() {
753 : return nullptr;
754 : }
755 : V8_INLINE static ZonePtrList<Statement>* NullStatementList() {
756 : return nullptr;
757 : }
758 : V8_INLINE static std::nullptr_t NullStatement() { return nullptr; }
759 : V8_INLINE static std::nullptr_t NullBlock() { return nullptr; }
760 : Expression* FailureExpression() { return factory()->FailureExpression(); }
761 :
762 : template <typename T>
763 : V8_INLINE static bool IsNull(T subject) {
764 185458 : return subject == nullptr;
765 : }
766 :
767 : // Non-null empty string.
768 : V8_INLINE const AstRawString* EmptyIdentifierString() const {
769 : return ast_value_factory()->empty_string();
770 : }
771 :
772 : // Producing data during the recursive descent.
773 : V8_INLINE const AstRawString* GetSymbol() const {
774 48023449 : const AstRawString* result = scanner()->CurrentSymbol(ast_value_factory());
775 : DCHECK_NOT_NULL(result);
776 : return result;
777 : }
778 :
779 : V8_INLINE const AstRawString* GetIdentifier() const { return GetSymbol(); }
780 :
781 : V8_INLINE const AstRawString* GetNextSymbol() const {
782 49306 : return scanner()->NextSymbol(ast_value_factory());
783 : }
784 :
785 : V8_INLINE const AstRawString* GetNumberAsSymbol() const {
786 3698 : double double_value = scanner()->DoubleValue();
787 : char array[100];
788 3698 : const char* string = DoubleToCString(double_value, ArrayVector(array));
789 3698 : return ast_value_factory()->GetOneByteString(string);
790 : }
791 :
792 2543581 : class ThisExpression* ThisExpression() {
793 : UseThis();
794 2543582 : return factory()->ThisExpression();
795 : }
796 :
797 : Expression* NewSuperPropertyReference(int pos);
798 : Expression* NewSuperCallReference(int pos);
799 : Expression* NewTargetExpression(int pos);
800 : Expression* ImportMetaExpression(int pos);
801 :
802 : Expression* ExpressionFromLiteral(Token::Value token, int pos);
803 :
804 : V8_INLINE VariableProxy* ExpressionFromIdentifier(
805 : const AstRawString* name, int start_position,
806 : InferName infer = InferName::kYes) {
807 : if (infer == InferName::kYes) {
808 30871648 : fni_.PushVariableName(name);
809 : }
810 30932017 : return expression_scope()->NewVariable(name, start_position);
811 : }
812 :
813 : V8_INLINE void DeclareIdentifier(const AstRawString* name,
814 : int start_position) {
815 1988895 : expression_scope()->Declare(name, start_position);
816 : }
817 :
818 : V8_INLINE Variable* DeclareCatchVariableName(Scope* scope,
819 : const AstRawString* name) {
820 86078 : return scope->DeclareCatchVariableName(name);
821 : }
822 :
823 : V8_INLINE ZonePtrList<Expression>* NewExpressionList(int size) const {
824 : return new (zone()) ZonePtrList<Expression>(size, zone());
825 : }
826 : V8_INLINE ZonePtrList<ObjectLiteral::Property>* NewObjectPropertyList(
827 : int size) const {
828 : return new (zone()) ZonePtrList<ObjectLiteral::Property>(size, zone());
829 : }
830 : V8_INLINE ZonePtrList<ClassLiteral::Property>* NewClassPropertyList(
831 : int size) const {
832 : return new (zone()) ZonePtrList<ClassLiteral::Property>(size, zone());
833 : }
834 : V8_INLINE ZonePtrList<Statement>* NewStatementList(int size) const {
835 : return new (zone()) ZonePtrList<Statement>(size, zone());
836 : }
837 :
838 : Expression* NewV8Intrinsic(const AstRawString* name,
839 : const ScopedPtrList<Expression>& args, int pos);
840 :
841 : V8_INLINE Statement* NewThrowStatement(Expression* exception, int pos) {
842 : return factory()->NewExpressionStatement(
843 : factory()->NewThrow(exception, pos), pos);
844 : }
845 :
846 : V8_INLINE void AddFormalParameter(ParserFormalParameters* parameters,
847 : Expression* pattern,
848 : Expression* initializer,
849 : int initializer_end_position,
850 : bool is_rest) {
851 4039181 : parameters->UpdateArityAndFunctionLength(initializer != nullptr, is_rest);
852 4039200 : auto parameter = new (parameters->scope->zone())
853 : ParserFormalParameters::Parameter(pattern, initializer,
854 127516 : scanner()->location().beg_pos,
855 8059594 : initializer_end_position, is_rest);
856 :
857 4020394 : parameters->params.Add(parameter);
858 : }
859 :
860 : V8_INLINE void DeclareFormalParameters(ParserFormalParameters* parameters) {
861 1574522 : bool is_simple = parameters->is_simple;
862 1574522 : DeclarationScope* scope = parameters->scope;
863 1574522 : if (!is_simple) scope->MakeParametersNonSimple();
864 8825245 : for (auto parameter : parameters->params) {
865 2856939 : bool is_optional = parameter->initializer() != nullptr;
866 : // If the parameter list is simple, declare the parameters normally with
867 : // their names. If the parameter list is not simple, declare a temporary
868 : // for each parameter - the corresponding named variable is declared by
869 : // BuildParamerterInitializationBlock.
870 5713878 : scope->DeclareParameter(
871 : is_simple ? parameter->name() : ast_value_factory()->empty_string(),
872 : is_simple ? VariableMode::kVar : VariableMode::kTemporary,
873 : is_optional, parameter->is_rest(), ast_value_factory(),
874 2856939 : parameter->position);
875 : }
876 : }
877 :
878 : void DeclareArrowFunctionFormalParameters(
879 : ParserFormalParameters* parameters, Expression* params,
880 : const Scanner::Location& params_loc);
881 :
882 : Expression* ExpressionListToExpression(const ScopedPtrList<Expression>& args);
883 :
884 : void SetFunctionNameFromPropertyName(LiteralProperty* property,
885 : const AstRawString* name,
886 : const AstRawString* prefix = nullptr);
887 : void SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
888 : const AstRawString* name,
889 : const AstRawString* prefix = nullptr);
890 :
891 : void SetFunctionNameFromIdentifierRef(Expression* value,
892 : Expression* identifier);
893 :
894 : V8_INLINE void CountUsage(v8::Isolate::UseCounterFeature feature) {
895 1230 : ++use_counts_[feature];
896 : }
897 :
898 : // Returns true iff we're parsing the first function literal during
899 : // CreateDynamicFunction().
900 : V8_INLINE bool ParsingDynamicFunctionDeclaration() const {
901 1873101 : return parameters_end_pos_ != kNoSourcePosition;
902 : }
903 :
904 : V8_INLINE void ConvertBinaryToNaryOperationSourceRange(
905 : BinaryOperation* binary_op, NaryOperation* nary_op) {
906 256204 : if (source_range_map_ == nullptr) return;
907 : DCHECK_NULL(source_range_map_->Find(nary_op));
908 :
909 : BinaryOperationSourceRanges* ranges =
910 : static_cast<BinaryOperationSourceRanges*>(
911 104 : source_range_map_->Find(binary_op));
912 104 : if (ranges == nullptr) return;
913 :
914 104 : SourceRange range = ranges->GetRange(SourceRangeKind::kRight);
915 104 : source_range_map_->Insert(
916 208 : nary_op, new (zone()) NaryOperationSourceRanges(zone(), range));
917 : }
918 :
919 : V8_INLINE void AppendNaryOperationSourceRange(NaryOperation* node,
920 : const SourceRange& range) {
921 345752 : if (source_range_map_ == nullptr) return;
922 : NaryOperationSourceRanges* ranges =
923 140 : static_cast<NaryOperationSourceRanges*>(source_range_map_->Find(node));
924 140 : if (ranges == nullptr) return;
925 :
926 140 : ranges->AddRange(range);
927 : DCHECK_EQ(node->subsequent_length(), ranges->RangeCount());
928 : }
929 :
930 : V8_INLINE void RecordBlockSourceRange(Block* node,
931 : int32_t continuation_position) {
932 935773 : if (source_range_map_ == nullptr) return;
933 600 : source_range_map_->Insert(
934 : node, new (zone()) BlockSourceRanges(continuation_position));
935 : }
936 :
937 : V8_INLINE void RecordCaseClauseSourceRange(CaseClause* node,
938 : const SourceRange& body_range) {
939 91625 : if (source_range_map_ == nullptr) return;
940 24 : source_range_map_->Insert(node,
941 : new (zone()) CaseClauseSourceRanges(body_range));
942 : }
943 :
944 : V8_INLINE void RecordConditionalSourceRange(Expression* node,
945 : const SourceRange& then_range,
946 : const SourceRange& else_range) {
947 46787 : if (source_range_map_ == nullptr) return;
948 160 : source_range_map_->Insert(
949 : node->AsConditional(),
950 80 : new (zone()) ConditionalSourceRanges(then_range, else_range));
951 : }
952 :
953 : V8_INLINE void RecordBinaryOperationSourceRange(
954 : Expression* node, const SourceRange& right_range) {
955 158354 : if (source_range_map_ == nullptr) return;
956 464 : source_range_map_->Insert(node->AsBinaryOperation(),
957 : new (zone())
958 232 : BinaryOperationSourceRanges(right_range));
959 : }
960 :
961 : V8_INLINE void RecordJumpStatementSourceRange(Statement* node,
962 : int32_t continuation_position) {
963 1044078 : if (source_range_map_ == nullptr) return;
964 576 : source_range_map_->Insert(
965 : static_cast<JumpStatement*>(node),
966 116 : new (zone()) JumpStatementSourceRanges(continuation_position));
967 : }
968 :
969 : V8_INLINE void RecordIfStatementSourceRange(Statement* node,
970 : const SourceRange& then_range,
971 : const SourceRange& else_range) {
972 637700 : if (source_range_map_ == nullptr) return;
973 920 : source_range_map_->Insert(
974 : node->AsIfStatement(),
975 : new (zone()) IfStatementSourceRanges(then_range, else_range));
976 : }
977 :
978 : V8_INLINE void RecordIterationStatementSourceRange(
979 : IterationStatement* node, const SourceRange& body_range) {
980 487204 : if (source_range_map_ == nullptr) return;
981 244 : source_range_map_->Insert(
982 : node, new (zone()) IterationStatementSourceRanges(body_range));
983 : }
984 :
985 : V8_INLINE void RecordSuspendSourceRange(Expression* node,
986 : int32_t continuation_position) {
987 47701 : if (source_range_map_ == nullptr) return;
988 116 : source_range_map_->Insert(static_cast<Suspend*>(node),
989 : new (zone())
990 8 : SuspendSourceRanges(continuation_position));
991 : }
992 :
993 : V8_INLINE void RecordSwitchStatementSourceRange(
994 : Statement* node, int32_t continuation_position) {
995 13619 : if (source_range_map_ == nullptr) return;
996 24 : source_range_map_->Insert(
997 : node->AsSwitchStatement(),
998 : new (zone()) SwitchStatementSourceRanges(continuation_position));
999 : }
1000 :
1001 : V8_INLINE void RecordThrowSourceRange(Statement* node,
1002 : int32_t continuation_position) {
1003 41768 : if (source_range_map_ == nullptr) return;
1004 : ExpressionStatement* expr_stmt = static_cast<ExpressionStatement*>(node);
1005 32 : Throw* throw_expr = expr_stmt->expression()->AsThrow();
1006 32 : source_range_map_->Insert(
1007 32 : throw_expr, new (zone()) ThrowSourceRanges(continuation_position));
1008 : }
1009 :
1010 : V8_INLINE void RecordTryCatchStatementSourceRange(
1011 : TryCatchStatement* node, const SourceRange& body_range) {
1012 88943 : if (source_range_map_ == nullptr) return;
1013 60 : source_range_map_->Insert(
1014 60 : node, new (zone()) TryCatchStatementSourceRanges(body_range));
1015 : }
1016 :
1017 : V8_INLINE void RecordTryFinallyStatementSourceRange(
1018 : TryFinallyStatement* node, const SourceRange& body_range) {
1019 5243 : if (source_range_map_ == nullptr) return;
1020 28 : source_range_map_->Insert(
1021 28 : node, new (zone()) TryFinallyStatementSourceRanges(body_range));
1022 : }
1023 :
1024 : // Generate the next internal variable name for binding an exported namespace
1025 : // object (used to implement the "export * as" syntax).
1026 : const AstRawString* NextInternalNamespaceExportName();
1027 :
1028 : ParseInfo* info() const { return info_; }
1029 :
1030 : std::vector<uint8_t>* preparse_data_buffer() {
1031 95824 : return &preparse_data_buffer_;
1032 : }
1033 :
1034 : // Parser's private field members.
1035 : friend class PreParserZoneScope; // Uses reusable_preparser().
1036 : friend class PreparseDataBuilder; // Uses preparse_data_buffer()
1037 :
1038 : ParseInfo* info_;
1039 : Scanner scanner_;
1040 : Zone preparser_zone_;
1041 : PreParser* reusable_preparser_;
1042 : Mode mode_;
1043 :
1044 : SourceRangeMap* source_range_map_ = nullptr;
1045 :
1046 : friend class ParserTarget;
1047 : friend class ParserTargetScope;
1048 : ParserTarget* target_stack_; // for break, continue statements
1049 :
1050 : ScriptCompiler::CompileOptions compile_options_;
1051 :
1052 : // For NextInternalNamespaceExportName().
1053 : int number_of_named_namespace_exports_ = 0;
1054 :
1055 : // Other information which will be stored in Parser and moved to Isolate after
1056 : // parsing.
1057 : int use_counts_[v8::Isolate::kUseCounterFeatureCount];
1058 : int total_preparse_skipped_;
1059 : bool allow_lazy_;
1060 : bool temp_zoned_;
1061 : ConsumedPreparseData* consumed_preparse_data_;
1062 : std::vector<uint8_t> preparse_data_buffer_;
1063 :
1064 : // If not kNoSourcePosition, indicates that the first function literal
1065 : // encountered is a dynamic function, see CreateDynamicFunction(). This field
1066 : // indicates the correct position of the ')' that closes the parameter list.
1067 : // After that ')' is encountered, this field is reset to kNoSourcePosition.
1068 : int parameters_end_pos_;
1069 : };
1070 :
1071 : // ----------------------------------------------------------------------------
1072 : // Target is a support class to facilitate manipulation of the
1073 : // Parser's target_stack_ (the stack of potential 'break' and
1074 : // 'continue' statement targets). Upon construction, a new target is
1075 : // added; it is removed upon destruction.
1076 :
1077 : class ParserTarget {
1078 : public:
1079 : ParserTarget(ParserBase<Parser>* parser, BreakableStatement* statement)
1080 : : variable_(&parser->impl()->target_stack_),
1081 : statement_(statement),
1082 1471853 : previous_(parser->impl()->target_stack_) {
1083 1471853 : parser->impl()->target_stack_ = this;
1084 : }
1085 :
1086 1471851 : ~ParserTarget() { *variable_ = previous_; }
1087 :
1088 : ParserTarget* previous() { return previous_; }
1089 : BreakableStatement* statement() { return statement_; }
1090 :
1091 : private:
1092 : ParserTarget** variable_;
1093 : BreakableStatement* statement_;
1094 : ParserTarget* previous_;
1095 : };
1096 :
1097 : class ParserTargetScope {
1098 : public:
1099 : explicit ParserTargetScope(ParserBase<Parser>* parser)
1100 : : variable_(&parser->impl()->target_stack_),
1101 3069622 : previous_(parser->impl()->target_stack_) {
1102 3069622 : parser->impl()->target_stack_ = nullptr;
1103 : }
1104 :
1105 2599497 : ~ParserTargetScope() { *variable_ = previous_; }
1106 :
1107 : private:
1108 : ParserTarget** variable_;
1109 : ParserTarget* previous_;
1110 : };
1111 :
1112 : } // namespace internal
1113 : } // namespace v8
1114 :
1115 : #endif // V8_PARSING_PARSER_H_
|