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 4030026 : 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 4030026 : initializer_end_position(initializer_end_position) {}
93 :
94 : PointerWithPayload<Expression, bool, 1> initializer_and_is_rest;
95 :
96 : Expression* pattern;
97 2847780 : Expression* initializer() const {
98 2847780 : return initializer_and_is_rest.GetPointer();
99 : }
100 : int position;
101 : int initializer_end_position;
102 5695562 : inline bool is_rest() const { return initializer_and_is_rest.GetPayload(); }
103 :
104 : Parameter* next_parameter = nullptr;
105 60784 : bool is_simple() const {
106 186772 : return pattern->IsVariableProxy() && initializer() == nullptr &&
107 60784 : !is_rest();
108 : }
109 :
110 2763217 : const AstRawString* name() const {
111 : DCHECK(is_simple());
112 5526434 : return pattern->AsVariableProxy()->raw_name();
113 : }
114 :
115 : 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 360082 : strict_error_loc = loc;
122 360082 : 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 1823782 : : 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 4875264 : ~Parser() {
176 2437633 : delete reusable_preparser_;
177 2437631 : reusable_preparser_ = nullptr;
178 2437634 : }
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 4113283 : 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 3720661 : : parser_(parser), old_mode_(parser->mode_) {
228 3720661 : parser_->mode_ = mode;
229 : }
230 3720659 : ~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 149132 : 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 7411221 : PreParser* reusable_preparser() {
273 7411221 : if (reusable_preparser_ == nullptr) {
274 : reusable_preparser_ = new PreParser(
275 3164387 : &preparser_zone_, &scanner_, stack_limit_, ast_value_factory(),
276 : pending_error_handler(), runtime_call_stats_, logger_, -1,
277 395432 : parsing_module_, parsing_on_main_thread_);
278 : #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
279 : SET_ALLOW(natives);
280 395565 : SET_ALLOW(harmony_public_fields);
281 395565 : SET_ALLOW(harmony_static_fields);
282 395565 : SET_ALLOW(harmony_dynamic_import);
283 395565 : SET_ALLOW(harmony_import_meta);
284 395565 : SET_ALLOW(harmony_private_fields);
285 395565 : SET_ALLOW(harmony_private_methods);
286 395565 : SET_ALLOW(eval_cache);
287 : #undef SET_ALLOW
288 395565 : preparse_data_buffer_.reserve(128);
289 : }
290 7411296 : 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 88459 : bool HasCheckedSyntax() {
377 2190057 : 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 587041 : 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 37905 : TemplateLiteral(Zone* zone, int pos)
474 37905 : : cooked_(8, zone), raw_(8, zone), expressions_(8, zone), pos_(pos) {}
475 :
476 : const ZonePtrList<const AstRawString>* cooked() const { return &cooked_; }
477 : const ZonePtrList<const AstRawString>* raw() const { return &raw_; }
478 : 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 82295 : cooked_.Add(cooked, zone);
485 82295 : raw_.Add(raw, zone);
486 : }
487 :
488 : void AddExpression(Expression* expression, Zone* zone) {
489 47485 : 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 14311763 : 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 41788750 : return identifier == ast_value_factory()->arguments_string();
558 : }
559 :
560 : V8_INLINE bool IsEvalOrArguments(const AstRawString* identifier) const {
561 18490427 : 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 9515095 : Property* property = expression->AsProperty();
568 13460965 : 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 96895637 : VariableProxy* operand = expression->AsVariableProxy();
576 96895848 : return operand != nullptr && !operand->is_new_target();
577 : }
578 :
579 : V8_INLINE static const AstRawString* AsIdentifier(Expression* expression) {
580 : DCHECK(IsIdentifier(expression));
581 12662709 : return expression->AsVariableProxy()->raw_name();
582 : }
583 :
584 : V8_INLINE VariableProxy* AsIdentifierExpression(Expression* expression) {
585 15714 : return expression->AsVariableProxy();
586 : }
587 :
588 : V8_INLINE bool IsConstructor(const AstRawString* identifier) const {
589 334493 : return identifier == ast_value_factory()->constructor_string();
590 : }
591 :
592 : V8_INLINE bool IsName(const AstRawString* identifier) const {
593 62464 : return identifier == ast_value_factory()->name_string();
594 : }
595 :
596 : V8_INLINE static bool IsBoilerplateProperty(
597 : ObjectLiteral::Property* property) {
598 3036093 : return !property->IsPrototype();
599 : }
600 :
601 : V8_INLINE bool IsNative(Expression* expr) const {
602 : DCHECK_NOT_NULL(expr);
603 3478 : return expr->IsVariableProxy() &&
604 3478 : expr->AsVariableProxy()->raw_name() ==
605 1739 : ast_value_factory()->native_string();
606 : }
607 :
608 : V8_INLINE static bool IsArrayIndex(const AstRawString* string,
609 : uint32_t* index) {
610 54717 : 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 2626867 : ExpressionStatement* e_stat = statement->AsExpressionStatement();
619 1313436 : if (e_stat == nullptr) return false;
620 1313434 : Literal* literal = e_stat->expression()->AsLiteral();
621 1313434 : if (literal == nullptr || !literal->IsString()) return false;
622 : return arg == nullptr || literal->AsRawString() == arg;
623 : }
624 :
625 : V8_INLINE void GetDefaultStrings(
626 : const AstRawString** default_string,
627 : const AstRawString** star_default_star_string) {
628 65 : *default_string = ast_value_factory()->default_string();
629 65 : *star_default_star_string = ast_value_factory()->star_default_star_string();
630 : }
631 :
632 : // Functions for encapsulating the differences between parsing and preparsing;
633 : // operations interleaved with the recursive descent.
634 : V8_INLINE void PushLiteralName(const AstRawString* id) {
635 9003081 : fni_.PushLiteralName(id);
636 : }
637 :
638 : V8_INLINE void PushVariableName(const AstRawString* id) {
639 : fni_.PushVariableName(id);
640 : }
641 :
642 : V8_INLINE void PushPropertyName(Expression* expression) {
643 1781838 : if (expression->IsPropertyName()) {
644 37829 : fni_.PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
645 : } else {
646 1762912 : fni_.PushLiteralName(ast_value_factory()->anonymous_function_string());
647 : }
648 : }
649 :
650 : V8_INLINE void PushEnclosingName(const AstRawString* name) {
651 979070 : fni_.PushEnclosingName(name);
652 : }
653 :
654 : V8_INLINE void AddFunctionForNameInference(FunctionLiteral* func_to_infer) {
655 638222 : fni_.AddFunction(func_to_infer);
656 : }
657 :
658 392547 : V8_INLINE void InferFunctionName() { fni_.Infer(); }
659 :
660 : // If we assign a function literal to a property we pretenure the
661 : // literal so it can be added as a constant function property.
662 : V8_INLINE static void CheckAssigningFunctionLiteralToProperty(
663 : Expression* left, Expression* right) {
664 : DCHECK_NOT_NULL(left);
665 9515117 : if (left->IsProperty() && right->IsFunctionLiteral()) {
666 165786 : right->AsFunctionLiteral()->set_pretenure();
667 : }
668 : }
669 :
670 : // A shortcut for performing a ToString operation
671 : V8_INLINE Expression* ToString(Expression* expr) {
672 : if (expr->IsStringLiteral()) return expr;
673 : ScopedPtrList<Expression> args(pointer_buffer());
674 : args.Add(expr);
675 : return factory()->NewCallRuntime(Runtime::kInlineToString, args,
676 : expr->position());
677 : }
678 :
679 : // Returns true if we have a binary expression between two numeric
680 : // literals. In that case, *x will be changed to an expression which is the
681 : // computed value.
682 : bool ShortcutNumericLiteralBinaryExpression(Expression** x, Expression* y,
683 : Token::Value op, int pos);
684 :
685 : // Returns true if we have a binary operation between a binary/n-ary
686 : // expression (with the same operation) and a value, which can be collapsed
687 : // into a single n-ary expression. In that case, *x will be changed to an
688 : // n-ary expression.
689 : bool CollapseNaryExpression(Expression** x, Expression* y, Token::Value op,
690 : int pos, const SourceRange& range);
691 :
692 : // Returns a UnaryExpression or, in one of the following cases, a Literal.
693 : // ! <literal> -> true / false
694 : // + <Number literal> -> <Number literal>
695 : // - <Number literal> -> <Number literal with value negated>
696 : // ~ <literal> -> true / false
697 : Expression* BuildUnaryExpression(Expression* expression, Token::Value op,
698 : int pos);
699 :
700 : // Generate AST node that throws a ReferenceError with the given type.
701 : V8_INLINE Expression* NewThrowReferenceError(MessageTemplate message,
702 : int pos) {
703 : return NewThrowError(Runtime::kNewReferenceError, message,
704 1219 : ast_value_factory()->empty_string(), pos);
705 : }
706 :
707 : // Generate AST node that throws a SyntaxError with the given
708 : // type. The first argument may be null (in the handle sense) in
709 : // which case no arguments are passed to the constructor.
710 : V8_INLINE Expression* NewThrowSyntaxError(MessageTemplate message,
711 : const AstRawString* arg, int pos) {
712 : return NewThrowError(Runtime::kNewSyntaxError, message, arg, pos);
713 : }
714 :
715 : // Generate AST node that throws a TypeError with the given
716 : // type. Both arguments must be non-null (in the handle sense).
717 : V8_INLINE Expression* NewThrowTypeError(MessageTemplate message,
718 : const AstRawString* arg, int pos) {
719 : return NewThrowError(Runtime::kNewTypeError, message, arg, pos);
720 : }
721 :
722 : // Reporting errors.
723 2069546 : void ReportMessageAt(Scanner::Location source_location,
724 : MessageTemplate message, const char* arg = nullptr,
725 : ParseErrorType error_type = kSyntaxError) {
726 : pending_error_handler()->ReportMessageAt(source_location.beg_pos,
727 : source_location.end_pos, message,
728 2069546 : arg, error_type);
729 : scanner_.set_parser_error();
730 2069544 : }
731 :
732 : // Dummy implementation. The parser should never have a unidentifiable
733 : // error.
734 : V8_INLINE void ReportUnidentifiableError() { UNREACHABLE(); }
735 :
736 78306 : void ReportMessageAt(Scanner::Location source_location,
737 : MessageTemplate message, const AstRawString* arg,
738 : ParseErrorType error_type = kSyntaxError) {
739 : pending_error_handler()->ReportMessageAt(source_location.beg_pos,
740 : source_location.end_pos, message,
741 78306 : arg, error_type);
742 : scanner_.set_parser_error();
743 78306 : }
744 :
745 : void ReportUnexpectedTokenAt(
746 : Scanner::Location location, Token::Value token,
747 : MessageTemplate message = MessageTemplate::kUnexpectedToken);
748 :
749 : // "null" return type creators.
750 : V8_INLINE static std::nullptr_t NullIdentifier() { return nullptr; }
751 : V8_INLINE static std::nullptr_t NullExpression() { return nullptr; }
752 : V8_INLINE static std::nullptr_t NullLiteralProperty() { return nullptr; }
753 : V8_INLINE static ZonePtrList<Expression>* NullExpressionList() {
754 : return nullptr;
755 : }
756 : V8_INLINE static ZonePtrList<Statement>* NullStatementList() {
757 : return nullptr;
758 : }
759 : V8_INLINE static std::nullptr_t NullStatement() { return nullptr; }
760 : V8_INLINE static std::nullptr_t NullBlock() { return nullptr; }
761 707166 : Expression* FailureExpression() { return factory()->FailureExpression(); }
762 :
763 : template <typename T>
764 : V8_INLINE static bool IsNull(T subject) {
765 183699 : return subject == nullptr;
766 : }
767 :
768 : // Non-null empty string.
769 : V8_INLINE const AstRawString* EmptyIdentifierString() const {
770 625330 : return ast_value_factory()->empty_string();
771 : }
772 :
773 : // Producing data during the recursive descent.
774 : V8_INLINE const AstRawString* GetSymbol() const {
775 48049859 : const AstRawString* result = scanner()->CurrentSymbol(ast_value_factory());
776 : DCHECK_NOT_NULL(result);
777 : return result;
778 : }
779 :
780 : V8_INLINE const AstRawString* GetNextSymbol() const {
781 49122 : return scanner()->NextSymbol(ast_value_factory());
782 : }
783 :
784 : V8_INLINE const AstRawString* GetNumberAsSymbol() const {
785 3698 : double double_value = scanner()->DoubleValue();
786 : char array[100];
787 3698 : const char* string = DoubleToCString(double_value, ArrayVector(array));
788 3697 : return ast_value_factory()->GetOneByteString(string);
789 : }
790 :
791 2484736 : class ThisExpression* ThisExpression() {
792 : UseThis();
793 2484744 : return factory()->ThisExpression();
794 : }
795 :
796 : Expression* NewSuperPropertyReference(int pos);
797 : Expression* NewSuperCallReference(int pos);
798 : Expression* NewTargetExpression(int pos);
799 : Expression* ImportMetaExpression(int pos);
800 :
801 : Expression* ExpressionFromLiteral(Token::Value token, int pos);
802 :
803 : V8_INLINE VariableProxy* ExpressionFromIdentifier(
804 : const AstRawString* name, int start_position,
805 : InferName infer = InferName::kYes) {
806 : if (infer == InferName::kYes) {
807 30607914 : fni_.PushVariableName(name);
808 : }
809 30666996 : return expression_scope()->NewVariable(name, start_position);
810 : }
811 :
812 : V8_INLINE void DeclareIdentifier(const AstRawString* name,
813 : int start_position) {
814 1976128 : expression_scope()->Declare(name, start_position);
815 : }
816 :
817 : V8_INLINE Variable* DeclareCatchVariableName(Scope* scope,
818 : const AstRawString* name) {
819 85308 : return scope->DeclareCatchVariableName(name);
820 : }
821 :
822 : V8_INLINE ZonePtrList<Expression>* NewExpressionList(int size) const {
823 : return new (zone()) ZonePtrList<Expression>(size, zone());
824 : }
825 : V8_INLINE ZonePtrList<ObjectLiteral::Property>* NewObjectPropertyList(
826 : int size) const {
827 : return new (zone()) ZonePtrList<ObjectLiteral::Property>(size, zone());
828 : }
829 : V8_INLINE ZonePtrList<ClassLiteral::Property>* NewClassPropertyList(
830 : int size) const {
831 549013 : return new (zone()) ZonePtrList<ClassLiteral::Property>(size, zone());
832 : }
833 : V8_INLINE ZonePtrList<Statement>* NewStatementList(int size) const {
834 : return new (zone()) ZonePtrList<Statement>(size, zone());
835 : }
836 :
837 : Expression* NewV8Intrinsic(const AstRawString* name,
838 : const ScopedPtrList<Expression>& args, int pos);
839 :
840 : V8_INLINE Statement* NewThrowStatement(Expression* exception, int pos) {
841 : return factory()->NewExpressionStatement(
842 40181 : factory()->NewThrow(exception, pos), pos);
843 : }
844 :
845 : V8_INLINE void AddFormalParameter(ParserFormalParameters* parameters,
846 : Expression* pattern,
847 : Expression* initializer,
848 : int initializer_end_position,
849 : bool is_rest) {
850 4030032 : parameters->UpdateArityAndFunctionLength(initializer != nullptr, is_rest);
851 4030027 : auto parameter = new (parameters->scope->zone())
852 : ParserFormalParameters::Parameter(pattern, initializer,
853 4030026 : scanner()->location().beg_pos,
854 8060054 : initializer_end_position, is_rest);
855 :
856 4030029 : parameters->params.Add(parameter);
857 : }
858 :
859 : V8_INLINE void DeclareFormalParameters(ParserFormalParameters* parameters) {
860 1559499 : bool is_simple = parameters->is_simple;
861 1559499 : DeclarationScope* scope = parameters->scope;
862 1559499 : if (!is_simple) scope->MakeParametersNonSimple();
863 7170496 : for (auto parameter : parameters->params) {
864 2847778 : bool is_optional = parameter->initializer() != nullptr;
865 : // If the parameter list is simple, declare the parameters normally with
866 : // their names. If the parameter list is not simple, declare a temporary
867 : // for each parameter - the corresponding named variable is declared by
868 : // BuildParamerterInitializationBlock.
869 : scope->DeclareParameter(
870 84564 : is_simple ? parameter->name() : ast_value_factory()->empty_string(),
871 : is_simple ? VariableMode::kVar : VariableMode::kTemporary,
872 2847782 : is_optional, parameter->is_rest(), ast_value_factory(),
873 8543343 : parameter->position);
874 : }
875 : }
876 :
877 : void DeclareArrowFunctionFormalParameters(
878 : ParserFormalParameters* parameters, Expression* params,
879 : const Scanner::Location& params_loc);
880 :
881 : Expression* ExpressionListToExpression(const ScopedPtrList<Expression>& args);
882 :
883 : void SetFunctionNameFromPropertyName(LiteralProperty* property,
884 : const AstRawString* name,
885 : const AstRawString* prefix = nullptr);
886 : void SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
887 : const AstRawString* name,
888 : const AstRawString* prefix = nullptr);
889 :
890 : void SetFunctionNameFromIdentifierRef(Expression* value,
891 : Expression* identifier);
892 :
893 : V8_INLINE void CountUsage(v8::Isolate::UseCounterFeature feature) {
894 1219 : ++use_counts_[feature];
895 : }
896 :
897 : // Returns true iff we're parsing the first function literal during
898 : // CreateDynamicFunction().
899 : V8_INLINE bool ParsingDynamicFunctionDeclaration() const {
900 : return parameters_end_pos_ != kNoSourcePosition;
901 : }
902 :
903 : V8_INLINE void ConvertBinaryToNaryOperationSourceRange(
904 : BinaryOperation* binary_op, NaryOperation* nary_op) {
905 250366 : if (source_range_map_ == nullptr) return;
906 : DCHECK_NULL(source_range_map_->Find(nary_op));
907 :
908 : BinaryOperationSourceRanges* ranges =
909 : static_cast<BinaryOperationSourceRanges*>(
910 104 : source_range_map_->Find(binary_op));
911 104 : if (ranges == nullptr) return;
912 :
913 104 : SourceRange range = ranges->GetRange(SourceRangeKind::kRight);
914 : source_range_map_->Insert(
915 104 : nary_op, new (zone()) NaryOperationSourceRanges(zone(), range));
916 : }
917 :
918 : V8_INLINE void AppendNaryOperationSourceRange(NaryOperation* node,
919 : const SourceRange& range) {
920 341950 : if (source_range_map_ == nullptr) return;
921 : NaryOperationSourceRanges* ranges =
922 140 : static_cast<NaryOperationSourceRanges*>(source_range_map_->Find(node));
923 140 : if (ranges == nullptr) return;
924 :
925 140 : ranges->AddRange(range);
926 : DCHECK_EQ(node->subsequent_length(), ranges->RangeCount());
927 : }
928 :
929 : V8_INLINE void RecordBlockSourceRange(Block* node,
930 : int32_t continuation_position) {
931 919600 : if (source_range_map_ == nullptr) return;
932 : source_range_map_->Insert(
933 580 : node, new (zone()) BlockSourceRanges(continuation_position));
934 : }
935 :
936 : V8_INLINE void RecordCaseClauseSourceRange(CaseClause* node,
937 : const SourceRange& body_range) {
938 88853 : if (source_range_map_ == nullptr) return;
939 : source_range_map_->Insert(node,
940 24 : new (zone()) CaseClauseSourceRanges(body_range));
941 : }
942 :
943 : V8_INLINE void RecordConditionalSourceRange(Expression* node,
944 : const SourceRange& then_range,
945 : const SourceRange& else_range) {
946 46080 : if (source_range_map_ == nullptr) return;
947 : source_range_map_->Insert(
948 : node->AsConditional(),
949 160 : new (zone()) ConditionalSourceRanges(then_range, else_range));
950 : }
951 :
952 : V8_INLINE void RecordBinaryOperationSourceRange(
953 : Expression* node, const SourceRange& right_range) {
954 156430 : if (source_range_map_ == nullptr) return;
955 : source_range_map_->Insert(node->AsBinaryOperation(),
956 : new (zone())
957 464 : BinaryOperationSourceRanges(right_range));
958 : }
959 :
960 : V8_INLINE void RecordJumpStatementSourceRange(Statement* node,
961 : int32_t continuation_position) {
962 1037812 : if (source_range_map_ == nullptr) return;
963 : source_range_map_->Insert(
964 : static_cast<JumpStatement*>(node),
965 576 : new (zone()) JumpStatementSourceRanges(continuation_position));
966 : }
967 :
968 : V8_INLINE void RecordIfStatementSourceRange(Statement* node,
969 : const SourceRange& then_range,
970 : const SourceRange& else_range) {
971 623292 : if (source_range_map_ == nullptr) return;
972 : source_range_map_->Insert(
973 : node->AsIfStatement(),
974 912 : new (zone()) IfStatementSourceRanges(then_range, else_range));
975 : }
976 :
977 : V8_INLINE void RecordIterationStatementSourceRange(
978 : IterationStatement* node, const SourceRange& body_range) {
979 484161 : if (source_range_map_ == nullptr) return;
980 : source_range_map_->Insert(
981 244 : node, new (zone()) IterationStatementSourceRanges(body_range));
982 : }
983 :
984 : V8_INLINE void RecordSuspendSourceRange(Expression* node,
985 : int32_t continuation_position) {
986 47120 : if (source_range_map_ == nullptr) return;
987 : source_range_map_->Insert(static_cast<Suspend*>(node),
988 : new (zone())
989 116 : SuspendSourceRanges(continuation_position));
990 : }
991 :
992 : V8_INLINE void RecordSwitchStatementSourceRange(
993 : Statement* node, int32_t continuation_position) {
994 13546 : if (source_range_map_ == nullptr) return;
995 : source_range_map_->Insert(
996 : node->AsSwitchStatement(),
997 24 : new (zone()) SwitchStatementSourceRanges(continuation_position));
998 : }
999 :
1000 : V8_INLINE void RecordThrowSourceRange(Statement* node,
1001 : int32_t continuation_position) {
1002 40177 : if (source_range_map_ == nullptr) return;
1003 28 : ExpressionStatement* expr_stmt = static_cast<ExpressionStatement*>(node);
1004 28 : Throw* throw_expr = expr_stmt->expression()->AsThrow();
1005 : source_range_map_->Insert(
1006 28 : throw_expr, new (zone()) ThrowSourceRanges(continuation_position));
1007 : }
1008 :
1009 : V8_INLINE void RecordTryCatchStatementSourceRange(
1010 : TryCatchStatement* node, const SourceRange& body_range) {
1011 88298 : if (source_range_map_ == nullptr) return;
1012 : source_range_map_->Insert(
1013 52 : node, new (zone()) TryCatchStatementSourceRanges(body_range));
1014 : }
1015 :
1016 : V8_INLINE void RecordTryFinallyStatementSourceRange(
1017 : TryFinallyStatement* node, const SourceRange& body_range) {
1018 5245 : if (source_range_map_ == nullptr) return;
1019 : source_range_map_->Insert(
1020 28 : node, new (zone()) TryFinallyStatementSourceRanges(body_range));
1021 : }
1022 :
1023 : // Generate the next internal variable name for binding an exported namespace
1024 : // object (used to implement the "export * as" syntax).
1025 : const AstRawString* NextInternalNamespaceExportName();
1026 :
1027 : ParseInfo* info() const { return info_; }
1028 :
1029 : std::vector<uint8_t>* preparse_data_buffer() {
1030 : return &preparse_data_buffer_;
1031 : }
1032 :
1033 : // Parser's private field members.
1034 : friend class PreParserZoneScope; // Uses reusable_preparser().
1035 : friend class PreparseDataBuilder; // Uses preparse_data_buffer()
1036 :
1037 : ParseInfo* info_;
1038 : Scanner scanner_;
1039 : Zone preparser_zone_;
1040 : PreParser* reusable_preparser_;
1041 : Mode mode_;
1042 :
1043 : SourceRangeMap* source_range_map_ = nullptr;
1044 :
1045 : friend class ParserTarget;
1046 : friend class ParserTargetScope;
1047 : ParserTarget* target_stack_; // for break, continue statements
1048 :
1049 : ScriptCompiler::CompileOptions compile_options_;
1050 :
1051 : // For NextInternalNamespaceExportName().
1052 : int number_of_named_namespace_exports_ = 0;
1053 :
1054 : // Other information which will be stored in Parser and moved to Isolate after
1055 : // parsing.
1056 : int use_counts_[v8::Isolate::kUseCounterFeatureCount];
1057 : int total_preparse_skipped_;
1058 : bool allow_lazy_;
1059 : bool temp_zoned_;
1060 : ConsumedPreparseData* consumed_preparse_data_;
1061 : std::vector<uint8_t> preparse_data_buffer_;
1062 :
1063 : // If not kNoSourcePosition, indicates that the first function literal
1064 : // encountered is a dynamic function, see CreateDynamicFunction(). This field
1065 : // indicates the correct position of the ')' that closes the parameter list.
1066 : // After that ')' is encountered, this field is reset to kNoSourcePosition.
1067 : int parameters_end_pos_;
1068 : };
1069 :
1070 : // ----------------------------------------------------------------------------
1071 : // Target is a support class to facilitate manipulation of the
1072 : // Parser's target_stack_ (the stack of potential 'break' and
1073 : // 'continue' statement targets). Upon construction, a new target is
1074 : // added; it is removed upon destruction.
1075 :
1076 : class ParserTarget {
1077 : public:
1078 : ParserTarget(ParserBase<Parser>* parser, BreakableStatement* statement)
1079 : : variable_(&parser->impl()->target_stack_),
1080 : statement_(statement),
1081 1452536 : previous_(parser->impl()->target_stack_) {
1082 1452536 : parser->impl()->target_stack_ = this;
1083 : }
1084 :
1085 1452513 : ~ParserTarget() { *variable_ = previous_; }
1086 :
1087 : ParserTarget* previous() { return previous_; }
1088 : BreakableStatement* statement() { return statement_; }
1089 :
1090 : private:
1091 : ParserTarget** variable_;
1092 : BreakableStatement* statement_;
1093 : ParserTarget* previous_;
1094 : };
1095 :
1096 : class ParserTargetScope {
1097 : public:
1098 3052617 : explicit ParserTargetScope(ParserBase<Parser>* parser)
1099 : : variable_(&parser->impl()->target_stack_),
1100 3052617 : previous_(parser->impl()->target_stack_) {
1101 3052617 : parser->impl()->target_stack_ = nullptr;
1102 3052617 : }
1103 :
1104 3052653 : ~ParserTargetScope() { *variable_ = previous_; }
1105 :
1106 : private:
1107 : ParserTarget** variable_;
1108 : ParserTarget* previous_;
1109 : };
1110 :
1111 : } // namespace internal
1112 : } // namespace v8
1113 :
1114 : #endif // V8_PARSING_PARSER_H_
|