AbstractScopePtr.cpp |
|
1750 |
AbstractScopePtr.h |
|
2587 |
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
|
3117 |
AsyncEmitter.cpp |
|
5272 |
AsyncEmitter.h |
|
5709 |
BytecodeCompiler.cpp |
|
64964 |
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)
|
12001 |
BytecodeControlStructures.cpp |
|
12747 |
BytecodeControlStructures.h |
|
6135 |
BytecodeEmitter.cpp |
JS bytecode generation.
|
394642 |
BytecodeEmitter.h |
JS bytecode generation. |
47101 |
BytecodeOffset.h |
namespace frontend |
4160 |
BytecodeSection.cpp |
|
6489 |
BytecodeSection.h |
|
12628 |
CallOrNewEmitter.cpp |
|
9758 |
CallOrNewEmitter.h |
|
12806 |
CForEmitter.cpp |
|
5054 |
CForEmitter.h |
|
5410 |
CompilationStencil.h |
|
83019 |
DecoratorEmitter.cpp |
|
45884 |
DecoratorEmitter.h |
namespace js::frontend |
2775 |
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.
|
1811 |
ElemOpEmitter.cpp |
|
6520 |
ElemOpEmitter.h |
|
7056 |
EmitterScope.cpp |
static |
40708 |
EmitterScope.h |
|
9945 |
ErrorReporter.h |
|
11408 |
ExpressionStatementEmitter.cpp |
|
1488 |
ExpressionStatementEmitter.h |
frontend_ExpressionStatementEmitter_h |
2030 |
FoldConstants.cpp |
|
52868 |
FoldConstants.h |
namespace frontend |
1916 |
ForInEmitter.cpp |
|
4362 |
ForInEmitter.h |
namespace frontend |
3637 |
ForOfEmitter.cpp |
|
8621 |
ForOfEmitter.h |
namespace frontend |
3879 |
ForOfLoopControl.cpp |
= CompletionKind::Normal |
8242 |
ForOfLoopControl.h |
namespace frontend |
3603 |
Frontend2.cpp |
|
24327 |
Frontend2.h |
frontend_Frontend2_h |
1922 |
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.
|
10424 |
FrontendContext.h |
|
9122 |
FullParseHandler.h |
new_ methods for creating parse nodes. These report OOM on context. |
45577 |
FunctionEmitter.cpp |
|
25544 |
FunctionEmitter.h |
|
15549 |
FunctionSyntaxKind.h |
namespace frontend |
1055 |
GenerateReservedWords.py |
|
6832 |
IfEmitter.cpp |
= ConditionKind::Positive |
7300 |
IfEmitter.h |
|
9701 |
IteratorKind.h |
namespace js::frontend |
523 |
JumpList.cpp |
|
1454 |
JumpList.h |
namespace frontend |
2756 |
LabelEmitter.cpp |
|
997 |
LabelEmitter.h |
namespace frontend |
1615 |
LexicalScopeEmitter.cpp |
|
1653 |
LexicalScopeEmitter.h |
namespace frontend |
2930 |
ModuleSharedContext.h |
frontend_ModuleSharedContext_h |
1353 |
moz.build |
|
2802 |
NameAnalysisTypes.h |
|
12568 |
NameCollections.h |
|
13431 |
NameFunctions.cpp |
Test whether a ParseNode represents a function invocation |
18487 |
NameFunctions.h |
namespace frontend |
741 |
NameOpEmitter.cpp |
|
16533 |
NameOpEmitter.h |
|
5164 |
ObjectEmitter.cpp |
isStatic_ = |
26084 |
ObjectEmitter.h |
|
30622 |
ObjLiteral.cpp |
|
16774 |
ObjLiteral.h |
|
25566 |
OptionalEmitter.cpp |
= Kind::Other |
3885 |
OptionalEmitter.h |
|
7438 |
ParseContext-inl.h |
|
6077 |
ParseContext.cpp |
|
27836 |
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.
|
25343 |
ParseNode.cpp |
Allocate a ParseNode from parser's node freelist or, failing that, from
cx's temporary arena.
|
14587 |
ParseNode.h |
|
90187 |
ParseNodeVerify.cpp |
|
1495 |
ParseNodeVerify.h |
namespace frontend |
1520 |
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 |
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.
|
426665 |
Parser.h |
JS parser. |
77050 |
ParserAtom.cpp |
static |
42781 |
ParserAtom.h |
|
30946 |
PrivateOpEmitter.cpp |
|
8802 |
PrivateOpEmitter.h |
|
6972 |
PropOpEmitter.cpp |
|
6339 |
PropOpEmitter.h |
|
6972 |
ReservedWords.h |
A higher-order macro for enumerating reserved word tokens. |
5455 |
ScopeBindingCache.h |
|
11910 |
ScopeIndex.h |
namespace js |
915 |
ScriptIndex.h |
namespace frontend |
1126 |
SelfHostedIter.h |
namespace js::frontend |
1078 |
SharedContext-inl.h |
|
725 |
SharedContext.cpp |
|
14388 |
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.
|
26370 |
smoosh |
|
|
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 |
Stencil.cpp |
|
192643 |
Stencil.h |
|
46199 |
StencilXdr.cpp |
|
51765 |
StencilXdr.h |
|
7993 |
SwitchEmitter.cpp |
|
10985 |
SwitchEmitter.h |
|
14106 |
SyntaxParseHandler.h |
|
29245 |
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).
|
7184 |
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.
|
18638 |
TokenStream.cpp |
|
123389 |
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 |
TryEmitter.cpp |
= Nothing() |
8925 |
TryEmitter.h |
|
7568 |
TypedIndex.h |
|
1258 |
UsedNameTracker.h |
|
9840 |
UsingEmitter.cpp |
|
35926 |
UsingEmitter.h |
|
8222 |
ValueUsage.h |
namespace frontend |
1094 |
WhileEmitter.cpp |
|
2674 |
WhileEmitter.h |
namespace frontend |
2855 |