Name Description Size
AbstractScopePtr.cpp 1750
AbstractScopePtr.h 2587 Usage: FILE This script aligns the stack transition comment in BytecodeEmitter and its helper classes. The stack transition comment looks like the following: // [stack] VAL1 VAL2 VAL3 3116
AsyncEmitter.cpp 5433
AsyncEmitter.h 5708
BytecodeCompilation.h 5243
BytecodeCompiler.cpp 57441
BytecodeCompiler.h Structure of all of the support classes. Parser: described in Parser.h. BytecodeCompiler.cpp: BytecodeCompiler.h *and* BytecodeCompilation.h. This is the "driver", the high-level operations like "compile this source to bytecode". It calls the parser, bytecode emitter, etc. ParseContext.h and SharedContext.h: Both have similar purposes. They're split because ParseContext contains information used only by the parser, and SharedContext contains information used by both the parser and BytecodeEmitter. SharedContext.h: class Directives: this contains boolean flags for tracking if we're in asm.js or "use strict" code. The "use strict" bit is stored in SharedContext, and additionally, the full Directives class is stored in ParseContext - if a direcive is encountered while parsing, this is updated, and checked in GeneralParser::functionDefinition, and if it changed, the whole function is re-parsed with the new flags. SharedContext.h: abstract class SharedContext: This class contains two different groups of flags: Parse context information. This is information conceptually "passed down" into parsing sub-nodes. This is like "are we parsing strict code?", and so the parser can make decisions of how to parse based off that. Gathered-while-parsing information. This is information conceptually "returned up" from parsing sub-nodes. This is like "did we see a use strict directive"? Additionally, subclasses (GlobalSharedContext, ModuleSharedContext, EvalSharedContext, and FunctionBox) contain binding information, scope information, and other such bits of data. ParseContext.h: class UsedNameTracker: Track which bindings are used in which scopes. This helps determine which bindings are closed-over, which affects how they're stored; and whether special bindings like `this` and `arguments` can be optimized away. ParseContext.h: class ParseContext: Extremely complex class that serves a lot of purposes, but it's a single class - essentially no derived classes - so it's a little easier to comprehend all at once. (SourceParseContext does derive from ParseContext, but they does nothing except adjust the constructor's arguments). Note it uses a thing called Nestable, which implements a stack of objects: you can push (and pop) instances to a stack (linked list) as you parse further into the parse tree. You may push to this stack via calling the constructor with a GeneralParser as an argument (usually `this`), which pushes itself onto `this->pc` (so it does get assigned/pushed, even though no assignment ever appears directly in the parser) ParseContext contains a pointer to a SharedContext. There's a decent chunk of flags/data collection in here too, some "pass-down" data and some "return-up" data. ParseContext also contains a significant number of *sub*-Nestables as fields of itself (nestables inside nestables). Note you also push/pop to these via passing `Parser->pc`, which the constructor of the sub-nestable knows which ParseContext field to push to. The sub-nestables are: ParseContext::Statement: stack of statements. `if (x) { while (true) { try { ..stack of [if, while, try].. } ... } }` ParseContext::LabelStatement: interspersed in Statement stack, for labeled statements, for e.g. `label: while (true) { break label; }` ParseContext::ClassStatement: interspersed in Statement stack, for classes the parser is currently inside of. ParseContext::Scope: Set of variables in each scope (stack of sets): `{ let a; let b; { let c; } }` (this gets complicated with `var`, etc., check the class for docs) 9456
BytecodeControlStructures.cpp 12695
BytecodeControlStructures.h 6135
BytecodeEmitter.cpp JS bytecode generation. 356151
BytecodeEmitter.h JS bytecode generation. 46031
BytecodeOffset.h namespace frontend 4160
BytecodeSection.cpp 6374
BytecodeSection.h 12369
CallOrNewEmitter.cpp 9758
CallOrNewEmitter.h 12806
CForEmitter.cpp 5054
CForEmitter.h 5410
CompilationStencil.h 68309
DecoratorEmitter.cpp 26608
DecoratorEmitter.h namespace js::frontend 1823
DefaultEmitter.cpp 1720
DefaultEmitter.h namespace frontend 1678
DestructuringFlavor.h namespace frontend 690
DoWhileEmitter.cpp 1602
DoWhileEmitter.h namespace frontend 1966
EitherParser.h A variant-like class abstracting operations on a Parser with a given ParseHandler but unspecified character type. 1721
ElemOpEmitter.cpp 6627
ElemOpEmitter.h 8167
EmitterScope.cpp static 36880
EmitterScope.h 8157
ErrorReporter.h 11297
ExpressionStatementEmitter.cpp 1511
ExpressionStatementEmitter.h frontend_ExpressionStatementEmitter_h 2030
FoldConstants.cpp 52012
FoldConstants.h namespace frontend 1971
ForInEmitter.cpp 4362
ForInEmitter.h namespace frontend 3637
ForOfEmitter.cpp 6854
ForOfEmitter.h namespace frontend 3588
ForOfLoopControl.cpp = CompletionKind::Normal 6769
ForOfLoopControl.h namespace frontend 3603
Frontend2.cpp 24279
Frontend2.h frontend_Frontend2_h 2011
FrontendContext.cpp OOMs are non-deterministic, especially across different execution modes (e.g. interpreter vs JIT). When doing differential testing, print to stderr so that the fuzzers can detect this. 5020
FrontendContext.h 6711
FullParseHandler.h new_ methods for creating parse nodes. These report OOM on context. 42277
FunctionEmitter.cpp 23579
FunctionEmitter.h 15484
FunctionSyntaxKind.h namespace frontend 1055 6273
IfEmitter.cpp = ConditionKind::Positive 7263
IfEmitter.h 9586
IteratorKind.h namespace js::frontend 523
JumpList.cpp 1454
JumpList.h namespace frontend 2756
LabelEmitter.cpp 997
LabelEmitter.h namespace frontend 1615
LexicalScopeEmitter.cpp 1340
LexicalScopeEmitter.h namespace frontend 2774
ModuleSharedContext.h frontend_ModuleSharedContext_h 1353 2541
NameAnalysisTypes.h 11946
NameCollections.h 14068
NameFunctions.cpp Test whether a ParseNode represents a function invocation 18624
NameFunctions.h namespace frontend 854
NameOpEmitter.cpp 14409
NameOpEmitter.h namespace frontend 5036
ObjectEmitter.cpp isStatic_ = 25083
ObjectEmitter.h 30124
ObjLiteral.cpp 16770
ObjLiteral.h 25566
OptionalEmitter.cpp = Kind::Other 3885
OptionalEmitter.h 7437
ParseContext-inl.h 6077
ParseContext.cpp 24716
ParseContext.h The struct ParseContext stores information about the current parsing context, which is part of the parser state (see the field Parser::pc). The current parsing context is either the global context, or the function currently being parsed. When the parser encounters a function definition, it creates a new ParseContext, makes it the new current context. 21527
ParseNode.cpp Allocate a ParseNode from parser's node freelist or, failing that, from cx's temporary arena. 13425
ParseNode.h 88019
ParseNodeVerify.cpp 1682
ParseNodeVerify.h namespace frontend 1808
ParseNodeVisitor.h Utility class for walking a JS AST. Simple usage: class HowTrueVisitor : public ParseNodeVisitor<HowTrueVisitor> { public: bool visitTrueExpr(BooleanLiteral* pn) { std::cout << "How true.\n"; return true; } bool visitClassDecl(ClassNode* pn) { // The base-class implementation of each visit method // simply visits the node's children. So the subclass // gets to decide whether to descend into a subtree // and can do things either before or after: std::cout << "How classy.\n"; return ParseNodeVisitor::visitClassDecl(pn); } }; HowTrueVisitor v; v.visit(programRootNode); // walks the entire tree A ParseNodeVisitor can modify nodes, but it can't replace the current node with a different one; for that, use a RewritingParseNodeVisitor. Note that the Curiously Recurring Template Pattern is used for performance, as it eliminates the need for virtual method calls. Some rough testing shows about a 12% speedup in the FoldConstants.cpp pass. 4743
Parser.cpp JS parser. This is a recursive-descent parser for the JavaScript language specified by "The ECMAScript Language Specification" (Standard ECMA-262). It uses lexical and semantic feedback to disambiguate non-LL(1) structures. It generates trees of nodes induced by the recursive parsing (not precise syntax trees, see Parser.h). After tree construction, it rewrites trees to fold constants and evaluate compile-time expressions. This parser attempts no error recovery. 407466
Parser.h JS parser. 76193
ParserAtom.cpp static 42778
ParserAtom.h 30936
PrivateOpEmitter.cpp 8987
PrivateOpEmitter.h 7065
PropOpEmitter.cpp 6596
PropOpEmitter.h 7674
ReservedWords.h A higher-order macro for enumerating reserved word tokens. 4739
ScopeBindingCache.h 10709
ScopeIndex.h namespace js 915
ScriptIndex.h namespace frontend 1126
SelfHostedIter.h namespace js::frontend 887
SharedContext-inl.h 725
SharedContext.cpp 14348
SharedContext.h The struct SharedContext is part of the current parser context (see ParseContext). It stores information that is reused between the parser and the bytecode emitter. 25844
SourceNotes.cpp 548
SourceNotes.h Source notes generated along with bytecode for decompiling and debugging. A source note is a uint8_t with 4 bits of type and 4 of offset from the pc of the previous note. If 4 bits of offset aren't enough, extended delta notes (XDelta) consisting of 1 set high order bit followed by 7 offset bits are emitted before the next note. Some notes have operand offsets encoded immediately after them, in note bytes or byte-triples. Source Note Extended Delta +7-6-5-4+3-2-1-0+ +7+6-5-4-3-2-1-0+ | type | delta | |1| ext-delta | +-------+-------+ +-+-------------+ At most one "gettable" note (i.e., a note of type other than NewLine, ColSpan, SetLine, and XDelta) applies to a given bytecode. NB: the js::SrcNote::specs_ array is indexed by this enum, so its initializers need to match the order here. 13553
Stencil.cpp 178528
Stencil.h 40082
StencilXdr.cpp 48010
StencilXdr.h 7383
SwitchEmitter.cpp 10809
SwitchEmitter.h 14106
SyntaxParseHandler.h 27547
TaggedParserAtomIndexHasher.h 1293
TDZCheckCache.cpp 2000
TDZCheckCache.h namespace frontend 2282
Token.h Token-affiliated data structures except for TokenKind (defined in its own header). 7158
TokenKind.h List of token kinds and their ranges. The format for each line is: MACRO(<TOKEN_KIND_NAME>, <DESCRIPTION>) or RANGE(<TOKEN_RANGE_NAME>, <TOKEN_KIND_NAME>) where ; <TOKEN_KIND_NAME> is a legal C identifier of the token, that will be used in the JS engine source. <DESCRIPTION> is a string that describe about the token, and will be used in error message. <TOKEN_RANGE_NAME> is a legal C identifier of the range that will be used to JS engine source. It should end with `First` or `Last`. This is used to check TokenKind by range-testing: BinOpFirst <= tt && tt <= BinOpLast Second argument of `RANGE` is the actual value of the <TOKEN_RANGE_NAME>, should be same as one of <TOKEN_KIND_NAME> in other `MACRO`s. To use this macro, define two macros for `MACRO` and `RANGE`, and pass them as arguments. #define EMIT_TOKEN(name, desc) ... #define EMIT_RANGE(name, value) ... FOR_EACH_TOKEN_KIND_WITH_RANGE(EMIT_TOKEN, EMIT_RANGE) #undef EMIT_TOKEN #undef EMIT_RANGE If you don't need range data, use FOR_EACH_TOKEN_KIND instead. #define EMIT_TOKEN(name, desc) ... FOR_EACH_TOKEN_KIND(EMIT_TOKEN) #undef EMIT_TOKEN Note that this list does not contain ERROR and LIMIT. 18575
TokenStream.cpp 124104
TokenStream.h Streaming access to the raw tokens of JavaScript source. Because JS tokenization is context-sensitive -- a '/' could be either a regular expression *or* a division operator depending on context -- the various token stream classes are mostly not useful outside of the Parser where they reside. We should probably eventually merge the two concepts. 108356
TryEmitter.cpp = Nothing() 8192
TryEmitter.h 7283
TypedIndex.h 1233
UsedNameTracker.h 9574
ValueUsage.h namespace frontend 1094
WhileEmitter.cpp 2306
WhileEmitter.h namespace frontend 2348