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