Name Description Size Coverage
AbstractScopePtr.cpp 1750 91 %
AbstractScopePtr.h 2587 100 %
align_stack_comment.py Usage: align_stack_comment.py 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 2944 -
AsyncEmitter.cpp 5272 74 %
AsyncEmitter.h 5709 100 %
BytecodeCompiler.cpp 63629 82 %
BytecodeCompiler.h Structure of all of the support classes. Parser: described in Parser.h. BytecodeCompiler.cpp: BytecodeCompiler.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) 11972 100 %
BytecodeControlStructures.cpp 12747 85 %
BytecodeControlStructures.h 6560 100 %
BytecodeEmitter.cpp JS bytecode generation. 397442 79 %
BytecodeEmitter.h JS bytecode generation. 46344 96 %
BytecodeOffset.h namespace frontend 3573 100 %
BytecodeSection.cpp 6489 93 %
BytecodeSection.h 12628 95 %
CallOrNewEmitter.cpp 9783 88 %
CallOrNewEmitter.h 12806 100 %
CForEmitter.cpp 5054 86 %
CForEmitter.h 5410 -
CompilationStencil.h 97312 69 %
DecoratorEmitter.cpp 45884 -
DecoratorEmitter.h namespace js::frontend 2748 -
DefaultEmitter.cpp 1807 75 %
DefaultEmitter.h namespace frontend 1678 -
DestructuringFlavor.h namespace frontend 690 -
DoWhileEmitter.cpp 1602 80 %
DoWhileEmitter.h namespace frontend 1966 -
EitherParser.h A variant-like class abstracting operations on a Parser with a given ParseHandler but unspecified character type. 1768 100 %
ElemOpEmitter.cpp 6520 80 %
ElemOpEmitter.h 7056 100 %
EmitterScope.cpp static 38903 81 %
EmitterScope.h 9536 96 %
ErrorReporter.h 11408 97 %
ExpressionStatementEmitter.cpp 1488 88 %
ExpressionStatementEmitter.h frontend_ExpressionStatementEmitter_h 2030 -
FoldConstants.cpp 52878 89 %
FoldConstants.h namespace frontend 1913 -
ForInEmitter.cpp 4362 78 %
ForInEmitter.h namespace frontend 3637 -
ForOfEmitter.cpp 8627 77 %
ForOfEmitter.h namespace frontend 3879 -
ForOfLoopControl.cpp 8713 74 %
ForOfLoopControl.h namespace frontend 4036 100 %
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. 10653 66 %
FrontendContext.h 9117 95 %
FullParseHandler.h new_ methods for creating parse nodes. These report OOM on context. 45303 100 %
FunctionEmitter.cpp 25544 81 %
FunctionEmitter.h 15549 100 %
FunctionSyntaxKind.h namespace frontend 1055 -
GenerateReservedWords.py 5573 -
IfEmitter.cpp = ConditionKind::Positive 7300 89 %
IfEmitter.h 9701 -
IteratorKind.h namespace js::frontend 523 -
JumpList.cpp 1454 96 %
JumpList.h namespace frontend 2756 100 %
LabelEmitter.cpp 997 91 %
LabelEmitter.h namespace frontend 1615 100 %
LexicalScopeEmitter.cpp 1653 92 %
LexicalScopeEmitter.h namespace frontend 2930 100 %
ModuleSharedContext.h frontend_ModuleSharedContext_h 1353 100 %
moz.build 2736 -
NameAnalysisTypes.h 12631 99 %
NameCollections.h 13431 98 %
NameFunctions.cpp Test whether a ParseNode represents a function invocation 18591 89 %
NameFunctions.h namespace frontend 741 -
NameOpEmitter.cpp 16533 78 %
NameOpEmitter.h 5164 100 %
ObjectEmitter.cpp isStatic_ = 26207 82 %
ObjectEmitter.h 30644 -
ObjLiteral.cpp 17409 91 %
ObjLiteral.h 25566 84 %
OptionalEmitter.cpp = Kind::Other 3885 72 %
OptionalEmitter.h 7438 -
ParseContext-inl.h 6077 100 %
ParseContext.cpp 27836 83 %
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. 25542 98 %
ParseNode.cpp Allocate a ParseNode from parser's node freelist or, failing that, from cx's temporary arena. 14549 94 %
ParseNode.h 90696 98 %
ParseNodeVerify.cpp 1495 -
ParseNodeVerify.h namespace frontend 1520 100 %
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. https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern 4447 77 %
Parser-macros.h frontend_Parser_macros_h 900 -
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. 420204 90 %
Parser.h JS parser. 77079 90 %
ParserAtom.cpp static 42906 80 %
ParserAtom.h 30946 98 %
PrivateOpEmitter.cpp 8808 76 %
PrivateOpEmitter.h 6972 100 %
PropOpEmitter.cpp 6339 80 %
PropOpEmitter.h 6972 100 %
ReservedWordReader.py 1529 -
ReservedWords.h A higher-order macro for enumerating reserved word tokens. 5455 -
ScopeBindingCache.h 11945 55 %
ScopeIndex.h namespace js 915 100 %
ScriptIndex.h namespace frontend 1106 100 %
SelfHostedIter.h namespace js::frontend 1078 -
SharedContext-inl.h 725 100 %
SharedContext.cpp 15141 93 %
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. 26404 100 %
SourceNotes.cpp 548 -
SourceNotes.h [SMDOC] Source Notes Source notes are generated along with bytecode for associating line/column to opcode, and annotating opcode as breakpoint for debugging. A source note is a uint8_t with 4 bits of type and 4 bits 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. 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 | +-------+-------+ +-+-------------+ Extended Delta with `ext-delta == 0` is used as terminator, which is padded between the end of source notes and the next notes in the ImmutableScriptData. Terminator +7+6-5-4-3-2-1-0+ |1|0 0 0 0 0 0 0| +-+-------------+ Some notes have operand offsets encoded immediately after them. Each operand is encoded either in single-byte or 4-bytes, depending on the range. Single-byte Operand (0 <= operand <= 127) +7+6-5-4-3-2-1-0+ |0| operand | +-+-------------+ 4-bytes Operand (128 <= operand) (operand_3 << 24) | (operand_2 << 16) | (operand_1 << 8) | operand_0 +7-6-5-4-3-2-1-0+ +7-6-5-4-3-2-1-0+ +7-6-5-4-3-2-1-0+ +7-6-5-4-3-2-1-0+ |1| operand_3 | | operand_2 | | operand_1 | | operand_0 | +---------------+ +---------------+ +---------------+ +---------------+ NB: the js::SrcNote::specs_ array is indexed by this enum, so its initializers need to match the order here. 16407 97 %
Stencil.cpp 210419 56 %
Stencil.h 46222 88 %
StencilXdr.cpp 52237 83 %
StencilXdr.h 8082 100 %
SwitchEmitter.cpp 10931 90 %
SwitchEmitter.h 14106 100 %
SyntaxParseHandler.h 29531 55 %
TaggedParserAtomIndexHasher.h 1293 100 %
TDZCheckCache.cpp 2000 84 %
TDZCheckCache.h namespace frontend 2298 -
Token.h Token-affiliated data structures except for TokenKind (defined in its own header). 6880 100 %
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 Limit. 18490 100 %
TokenStream.cpp 123056 88 %
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. 109642 90 %
TryEmitter.cpp = Nothing() 9101 80 %
TryEmitter.h 8056 100 %
TypedIndex.h 1077 100 %
UsedNameTracker.h 9840 100 %
UsingEmitter.cpp 35852 62 %
UsingEmitter.h 7899 100 %
ValueUsage.h namespace frontend 1094 -
WhileEmitter.cpp 2674 82 %
WhileEmitter.h namespace frontend 2855 100 %