Name Description Size 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 2702
BCEParserHandle.h 919
binast A parser generator used to generate the following files: 5
BinAST-macros.h 2631
BinAST.webidl_ 27383
BinAST.yaml 52361
BinASTEnum.h 2113
BinASTParser.cpp AssertedMaybePositionalParameterName ::= AssertedParameterName AssertedPositionalParameterName AssertedRestParameterName 204114
BinASTParser.h 33994
BinASTParserBase.cpp 802
BinASTParserBase.h 1254
BinASTParserPerTokenizer.cpp = nullptr 27214
BinASTParserPerTokenizer.h A Binary AST parser. At the time of this writing, this parser implements the grammar of ES5 and trusts its input (in particular, variable declarations). 12263
BinASTRuntimeSupport.cpp static 1310
BinASTRuntimeSupport.h 4961
BinASTToken.cpp It is expected that all bin tables are initialized on the main thread, and that any helper threads will find the read-only tables properly initialized, so that they can do their accesses safely without taking any locks. 4765
BinASTToken.h Definition of Binary AST tokens. In the Binary AST world, an AST is composed of nodes, where a node is defined by: - a Kind (see `BinASTKind`); - a list of fields, where each field is: - a Name (see `BinASTField`); - a Value, which may be either a node or a primitive value. The mapping between Kind and list of fields is determined entirely by the grammar of Binary AST. The mapping between (Kind, Name) and the structure of Value is also determined entirely by the grammar of Binary AST. As per the specifications of Binary AST, kinds may be added as the language grows, but never removed. The mapping between Kind and list of fields may also change to add new fields or make some fields optional, but may never remove a field. Finally, the mapping between (Kind, Name) and the structure of Value may be modified to add new possible values, but never to remove a value. A Binary AST parser must be able to fail gracefully when confronted with unknown Kinds or Names. 308555
BinASTTokenReaderBase.cpp 3193
BinASTTokenReaderBase.h Return the position of the latest token. 6014
BinASTTokenReaderContext.cpp 53584
BinASTTokenReaderContext.h 19437
BinASTTokenReaderMultipart.cpp 15445
BinASTTokenReaderMultipart.h A token reader implementing the "multipart" serialization format for BinAST. This serialization format, which is also supported by the reference implementation of the BinAST compression suite, is designed to be space- and time-efficient. As other token readers for the BinAST: - the reader does not support error recovery; - the reader does not support lookahead or pushback. 9733
BytecodeCompilation.h 6434
BytecodeCompiler.cpp 38241
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 and BinASTParseContext do derive from ParseContext, but they do 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) 9651
BytecodeControlStructures.cpp 4894
BytecodeControlStructures.h 7154
BytecodeEmitter.cpp JS bytecode generation. 280206
BytecodeEmitter.h JS bytecode generation. 33849
BytecodeOffset.h namespace frontend 4160
BytecodeSection.cpp Find the index of the given object for code generator. Since the emitter refers to each parsed object only once, for the index we use the number of already indexed objects. We also add the object to a list to convert the list to a fixed-size array when we complete code generation, see js::CGObjectList::finish below. 5002
BytecodeSection.h 10967
CallOrNewEmitter.cpp 8214
CallOrNewEmitter.h 10956
CForEmitter.cpp 7082
CForEmitter.h 6286
DefaultEmitter.cpp 1740
DefaultEmitter.h namespace frontend 1690
DestructuringFlavor.h namespace frontend 1029
DoWhileEmitter.cpp 2624
DoWhileEmitter.h namespace frontend 2168
EitherParser.h A variant-like class abstracting operations on a Parser with a given ParseHandler but unspecified character type. 5011
ElemOpEmitter.cpp 8107
ElemOpEmitter.h 8329
EmitterScope.cpp static 35622
EmitterScope.h 5720
ErrorReporter.h 16432
ExpressionStatementEmitter.cpp 1557
ExpressionStatementEmitter.h frontend_ExpressionStatementEmitter_h 2129
FoldConstants.cpp 49445
FoldConstants.h namespace frontend 1503
ForInEmitter.cpp 5188
ForInEmitter.h namespace frontend 3774
ForOfEmitter.cpp 7736
ForOfEmitter.h namespace frontend 3589
ForOfLoopControl.cpp = CompletionKind::Normal 7520
ForOfLoopControl.h namespace frontend 3539
FullParseHandler.h If this is a full parse to construct the bytecode for a function that was previously lazily parsed, we still don't want to full parse the inner functions. These members are used for this functionality: - lazyOuterFunction_ holds the lazyScript for this current parse - lazyInnerFunctionIndex is used as we skip over inner functions (see skipLazyInnerFunction), 36299
FunctionEmitter.cpp 27023
FunctionEmitter.h 16634 6293
IfEmitter.cpp 6860
IfEmitter.h 9013
JumpList.cpp 1489
JumpList.h namespace frontend 2631
LabelEmitter.cpp 1679
LabelEmitter.h namespace frontend 1847
LexicalScopeEmitter.cpp 1405
LexicalScopeEmitter.h namespace frontend 2888
ModuleSharedContext.h frontend_ModuleSharedContext_h 1545 2911
NameAnalysisTypes.h 10313
NameCollections.h 10773
NameFunctions.cpp Test whether a ParseNode represents a function invocation 15683
NameFunctions.h namespace frontend 654
NameOpEmitter.cpp 11506
NameOpEmitter.h namespace frontend 4867
ObjectEmitter.cpp = Kind::Prototype 22639
ObjectEmitter.h 24573
ParseContext-inl.h 6090
ParseContext.cpp 20956
ParseContext.h 22007
ParseNode.cpp Allocate a ParseNode from parser's node freelist or, failing that, from cx's temporary arena. 12434
ParseNode.h clang-format off 76432
ParseNodeVerify.cpp 1482
ParseNodeVerify.h namespace frontend 1530
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. 4304
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. 323198
Parser.h JS parser. 73866
PropOpEmitter.cpp 7022
PropOpEmitter.h 7560
ReservedWords.h A higher-order macro for enumerating reserved word tokens. 5540
SharedContext-inl.h 725
SharedContext.cpp 10059
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. 21466
SourceNotes.h Source notes generated along with bytecode for decompiling and debugging. A source note is a uint8_t with 5 bits of type and 3 of offset from the pc of the previous note. If 3 bits of offset aren't enough, extended delta notes (SRC_XDELTA) consisting of 2 set high order bits followed by 6 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+ |note-type|delta| |1 1| ext-delta | +---------+-----+ +---+-----------+ At most one "gettable" note (i.e., a note of type other than SRC_NEWLINE, SRC_COLSPAN, SRC_SETLINE, and SRC_XDELTA) applies to a given bytecode. NB: the js_SrcNoteSpec array in BytecodeEmitter.cpp is indexed by this enum, so its initializers need to match the order here. 11520
SwitchEmitter.cpp 12470
SwitchEmitter.h 13958
SyntaxParseHandler.h 24501
TDZCheckCache.cpp 1943
TDZCheckCache.h namespace frontend 2204
Token.h Token-affiliated data structures except for TokenKind (defined in its own header). 7663
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. 18415
TokenStream.cpp 121637
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. 103621
TryEmitter.cpp = Nothing() 7610
TryEmitter.h 6922
ValueUsage.h namespace frontend 983
WhileEmitter.cpp 3602
WhileEmitter.h namespace frontend 2693