Bug 770865 - Rename TreeContext as ParseContext. r=luke.

--HG--
extra : rebase_source : 91846a909a39ca08aae0e6ccd7a9e5e533775324
This commit is contained in:
Nicholas Nethercote 2012-08-16 17:04:54 -07:00
parent 49496a347e
commit 05e9db6ab1
13 changed files with 516 additions and 515 deletions

View File

@ -102,8 +102,8 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
SharedContext sc(cx, scopeChain, /* fun = */ NULL, /* funbox = */ NULL, StrictModeFromContext(cx));
TreeContext tc(&parser, &sc, staticLevel, /* bodyid = */ 0);
if (!tc.init())
ParseContext pc(&parser, &sc, staticLevel, /* bodyid = */ 0);
if (!pc.init())
return NULL;
bool savedCallerFun = options.compileAndGo && callerFrame && callerFrame->isFunctionFrame();
@ -195,7 +195,7 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
if (!AnalyzeFunctions(&parser))
return NULL;
tc.functionList = NULL;
pc.functionList = NULL;
if (!EmitTree(cx, &bce, pn))
return NULL;
@ -226,7 +226,7 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
// It's an error to use |arguments| in a function that has a rest parameter.
if (callerFrame && callerFrame->isFunctionFrame() && callerFrame->fun()->hasRest()) {
PropertyName *arguments = cx->runtime->atomState.argumentsAtom;
for (AtomDefnRange r = tc.lexdeps->all(); !r.empty(); r.popFront()) {
for (AtomDefnRange r = pc.lexdeps->all(); !r.empty(); r.popFront()) {
if (r.front().key() == arguments) {
parser.reportError(NULL, JSMSG_ARGUMENTS_AND_REST);
return NULL;
@ -280,8 +280,8 @@ frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions
fun->setArgCount(formals.length());
unsigned staticLevel = 0;
TreeContext funtc(&parser, &funsc, staticLevel, /* bodyid = */ 0);
if (!funtc.init())
ParseContext funpc(&parser, &funsc, staticLevel, /* bodyid = */ 0);
if (!funpc.init())
return false;
/* FIXME: make Function format the source for a function definition. */
@ -326,7 +326,7 @@ frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions
if (!script)
return false;
if (!funtc.generateFunctionBindings(cx, &script->bindings))
if (!funpc.generateFunctionBindings(cx, &script->bindings))
return false;
BytecodeEmitter funbce(/* parent = */ NULL, &parser, &funsc, script, /* callerFrame = */ NULL,

View File

@ -3929,7 +3929,7 @@ EmitTry(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
* Push stmtInfo to track jumps-over-catches and gosubs-to-finally
* for later fixup.
*
* When a finally block is active (STMT_FINALLY in our tree context),
* When a finally block is active (STMT_FINALLY in our parse context),
* non-local jumps (including jumps-over-catches) result in a GOSUB
* being written into the bytecode stream and fixed-up later (c.f.
* EmitBackPatchOp and BackPatch).
@ -5211,7 +5211,7 @@ EmitStatement(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
/*
* Don't eliminate apparently useless expressions if they are
* labeled expression statements. The tc->topStmt->update test
* labeled expression statements. The pc->topStmt->update test
* catches the case where we are nesting in EmitTree for a labeled
* compound statement.
*/

View File

@ -324,7 +324,7 @@ class DefinitionList
/*
* AtomDecls is a map of atoms to (sequences of) Definitions. It is used by
* TreeContext to store declarations. A declaration associates a name with a
* ParseContext to store declarations. A declaration associates a name with a
* Definition.
*
* Declarations with function scope (such as const, var, and function) are

View File

@ -179,17 +179,17 @@ NameNode::dump(int indent)
}
#endif
struct TreeContext;
struct ParseContext;
inline void
NameNode::initCommon(TreeContext *tc)
NameNode::initCommon(ParseContext *pc)
{
pn_expr = NULL;
pn_cookie.makeFree();
pn_dflags = (!tc->topStmt || tc->topStmt->type == STMT_BLOCK)
pn_dflags = (!pc->topStmt || pc->topStmt->type == STMT_BLOCK)
? PND_BLOCKCHILD
: 0;
pn_blockid = tc->blockid();
pn_blockid = pc->blockid();
}
} /* namespace frontend */

View File

@ -297,9 +297,9 @@ ParseNodeAllocator::prepareNodeForMutation(ParseNode *pn)
* reallocation.
*
* Note that all functions in |pn| that are not enclosed by other functions
* in |pn| must be direct children of |tc|, because we only clean up |tc|'s
* in |pn| must be direct children of |pc|, because we only clean up |pc|'s
* function and method lists. You must not reach into a function and
* recycle some part of it (unless you've updated |tc|->functionList, the
* recycle some part of it (unless you've updated |pc|->functionList, the
* way js_FoldConstants does).
*/
ParseNode *
@ -422,15 +422,15 @@ ParseNode::newBinaryOrAppend(ParseNodeKind kind, JSOp op, ParseNode *left, Parse
}
// Nb: unlike most functions that are passed a Parser, this one gets a
// SharedContext passed in separately, because in this case |tc| may not equal
// |parser->tc|.
// SharedContext passed in separately, because in this case |pc| may not equal
// |parser->pc|.
NameNode *
NameNode::create(ParseNodeKind kind, JSAtom *atom, Parser *parser, TreeContext *tc)
NameNode::create(ParseNodeKind kind, JSAtom *atom, Parser *parser, ParseContext *pc)
{
ParseNode *pn = ParseNode::create(kind, PN_NAME, parser);
if (pn) {
pn->pn_atom = atom;
((NameNode *)pn)->initCommon(tc);
((NameNode *)pn)->initCommon(pc);
}
return (NameNode *)pn;
}
@ -460,9 +460,9 @@ Definition::kindString(Kind kind)
static ParseNode *
CloneParseTree(ParseNode *opn, Parser *parser)
{
TreeContext *tc = parser->tc;
ParseContext *pc = parser->pc;
JS_CHECK_RECURSION(tc->sc->context, return NULL);
JS_CHECK_RECURSION(pc->sc->context, return NULL);
ParseNode *pn = parser->new_<ParseNode>(opn->getKind(), opn->getOp(), opn->getArity(),
opn->pn_pos);
@ -477,7 +477,7 @@ CloneParseTree(ParseNode *opn, Parser *parser)
case PN_FUNC:
NULLCHECK(pn->pn_funbox =
parser->newFunctionBox(opn->pn_funbox->object, pn, tc, opn->pn_funbox->strictModeState));
parser->newFunctionBox(opn->pn_funbox->object, pn, pc, opn->pn_funbox->strictModeState));
NULLCHECK(pn->pn_body = CloneParseTree(opn->pn_body, parser));
pn->pn_cookie = opn->pn_cookie;
pn->pn_dflags = opn->pn_dflags;

View File

@ -18,7 +18,7 @@
namespace js {
namespace frontend {
struct TreeContext;
struct ParseContext;
/*
* Indicates a location in the stack that an upvar value can be retrieved from
@ -978,9 +978,9 @@ struct FunctionNode : public ParseNode {
};
struct NameNode : public ParseNode {
static NameNode *create(ParseNodeKind kind, JSAtom *atom, Parser *parser, TreeContext *tc);
static NameNode *create(ParseNodeKind kind, JSAtom *atom, Parser *parser, ParseContext *pc);
inline void initCommon(TreeContext *tc);
inline void initCommon(ParseContext *pc);
#ifdef DEBUG
inline void dump(int indent);
@ -1273,33 +1273,33 @@ void DumpParseTree(ParseNode *pn, int indent = 0);
*
* for (each use of unqualified name x in parse order) {
* if (this use of x is a declaration) {
* if (x in tc->decls) { // redeclaring
* if (x in pc->decls) { // redeclaring
* pn = allocate a PN_NAME ParseNode;
* } else { // defining
* dn = lookup x in tc->lexdeps;
* dn = lookup x in pc->lexdeps;
* if (dn) // use before def
* remove x from tc->lexdeps;
* remove x from pc->lexdeps;
* else // def before use
* dn = allocate a PN_NAME Definition;
* map x to dn via tc->decls;
* map x to dn via pc->decls;
* pn = dn;
* }
* insert pn into its parent PNK_VAR/PNK_CONST list;
* } else {
* pn = allocate a ParseNode for this reference to x;
* dn = lookup x in tc's lexical scope chain;
* dn = lookup x in pc's lexical scope chain;
* if (!dn) {
* dn = lookup x in tc->lexdeps;
* dn = lookup x in pc->lexdeps;
* if (!dn) {
* dn = pre-allocate a Definition for x;
* map x to dn in tc->lexdeps;
* map x to dn in pc->lexdeps;
* }
* }
* append pn to dn's use chain;
* }
* }
*
* See frontend/BytecodeEmitter.h for js::TreeContext and its top*Stmt,
* See frontend/BytecodeEmitter.h for js::ParseContext and its top*Stmt,
* decls, and lexdeps members.
*
* Notes:
@ -1311,9 +1311,9 @@ void DumpParseTree(ParseNode *pn, int indent = 0);
* statement" (ECMA-262 12.2) can be proven to be dead code. RecycleTree in
* ParseNode.cpp will not recycle a node whose pn_defn bit is set.
*
* 2. "lookup x in tc's lexical scope chain" gives up on def/use chaining if a
* with statement is found along the the scope chain, which includes tc,
* tc->parent, etc. Thus we eagerly connect an inner function's use of an
* 2. "lookup x in pc's lexical scope chain" gives up on def/use chaining if a
* with statement is found along the the scope chain, which includes pc,
* pc->parent, etc. Thus we eagerly connect an inner function's use of an
* outer's var x if the var x was parsed before the inner function.
*
* 3. A use may be eliminated as dead by the constant folder, which therefore
@ -1322,15 +1322,15 @@ void DumpParseTree(ParseNode *pn, int indent = 0);
* the pn_link pointing at the use to be removed. This is costly, so as for
* dead definitions, we do not recycle dead pn_used nodes.
*
* At the end of parsing a function body or global or eval program, tc->lexdeps
* At the end of parsing a function body or global or eval program, pc->lexdeps
* holds the lexical dependencies of the parsed unit. The name to def/use chain
* mappings are then merged into the parent tc->lexdeps.
* mappings are then merged into the parent pc->lexdeps.
*
* Thus if a later var x is parsed in the outer function satisfying an earlier
* inner function's use of x, we will remove dn from tc->lexdeps and re-use it
* inner function's use of x, we will remove dn from pc->lexdeps and re-use it
* as the new definition node in the outer function's parse tree.
*
* When the compiler unwinds from the outermost tc, tc->lexdeps contains the
* When the compiler unwinds from the outermost pc, pc->lexdeps contains the
* definition nodes with use chains for all free variables. These are either
* global variables or reference errors.
*/

View File

@ -14,19 +14,19 @@ namespace js {
namespace frontend {
inline unsigned
TreeContext::blockid()
ParseContext::blockid()
{
return topStmt ? topStmt->blockid : bodyid;
}
inline bool
TreeContext::atBodyLevel()
ParseContext::atBodyLevel()
{
return !topStmt || topStmt->isFunctionBodyBlock;
}
inline
TreeContext::TreeContext(Parser *prs, SharedContext *sc, unsigned staticLevel, uint32_t bodyid)
ParseContext::ParseContext(Parser *prs, SharedContext *sc, unsigned staticLevel, uint32_t bodyid)
: sc(sc),
bodyid(0), // initialized in init()
blockidGen(bodyid), // used to set |bodyid| and subsequently incremented in init()
@ -43,9 +43,9 @@ TreeContext::TreeContext(Parser *prs, SharedContext *sc, unsigned staticLevel, u
yieldNode(NULL),
functionList(NULL),
queuedStrictModeError(NULL),
parserTC(&prs->tc),
parserPC(&prs->pc),
lexdeps(prs->context),
parent(prs->tc),
parent(prs->pc),
innermostWith(NULL),
funcStmts(NULL),
hasReturnExpr(false),
@ -53,11 +53,11 @@ TreeContext::TreeContext(Parser *prs, SharedContext *sc, unsigned staticLevel, u
inForInit(false),
inDeclDestructuring(false)
{
prs->tc = this;
prs->pc = this;
}
inline bool
TreeContext::init()
ParseContext::init()
{
if (!frontend::GenerateBlockId(this, this->bodyid))
return false;
@ -66,19 +66,19 @@ TreeContext::init()
}
inline void
TreeContext::setQueuedStrictModeError(CompileError *e)
ParseContext::setQueuedStrictModeError(CompileError *e)
{
JS_ASSERT(!queuedStrictModeError);
queuedStrictModeError = e;
}
inline
TreeContext::~TreeContext()
ParseContext::~ParseContext()
{
// |*parserTC| pointed to this object. Now that this object is about to
// die, make |*parserTC| point to this object's parent.
JS_ASSERT(*parserTC == this);
*parserTC = this->parent;
// |*parserPC| pointed to this object. Now that this object is about to
// die, make |*parserPC| point to this object's parent.
JS_ASSERT(*parserPC == this);
*parserPC = this->parent;
sc->context->delete_(funcStmts);
if (queuedStrictModeError) {
// If the parent context is looking for strict mode violations, pass

File diff suppressed because it is too large Load Diff

View File

@ -25,16 +25,16 @@
namespace js {
namespace frontend {
struct StmtInfoTC : public StmtInfoBase {
StmtInfoTC *down; /* info for enclosing statement */
StmtInfoTC *downScope; /* next enclosing lexical scope */
struct StmtInfoPC : public StmtInfoBase {
StmtInfoPC *down; /* info for enclosing statement */
StmtInfoPC *downScope; /* next enclosing lexical scope */
uint32_t blockid; /* for simplified dominance computation */
/* True if type == STMT_BLOCK and this block is a function body. */
bool isFunctionBodyBlock;
StmtInfoTC(JSContext *cx) : StmtInfoBase(cx), isFunctionBodyBlock(false) {}
StmtInfoPC(JSContext *cx) : StmtInfoBase(cx), isFunctionBodyBlock(false) {}
};
typedef HashSet<JSAtom *> FuncStmtSet;
@ -44,24 +44,24 @@ struct SharedContext;
typedef Vector<Definition *, 16> DeclVector;
/*
* The struct TreeContext stores information about the current parsing context,
* which is part of the parser state (see the field Parser::tc). The current
* 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
* TreeContext, makes it the new current context, and sets its parent to the
* ParseContext, makes it the new current context, and sets its parent to the
* context in which it encountered the definition.
*/
struct TreeContext /* tree context for semantic checks */
struct ParseContext /* tree context for semantic checks */
{
typedef StmtInfoTC StmtInfo;
typedef StmtInfoPC StmtInfo;
SharedContext *sc; /* context shared between parsing and bytecode generation */
uint32_t bodyid; /* block number of program/function body */
uint32_t blockidGen; /* preincremented block number generator */
StmtInfoTC *topStmt; /* top of statement info stack */
StmtInfoTC *topScopeStmt; /* top lexical scope statement */
StmtInfoPC *topStmt; /* top of statement info stack */
StmtInfoPC *topScopeStmt; /* top lexical scope statement */
Rooted<StaticBlockObject *> blockChain;
/* compile time block scope chain */
@ -95,7 +95,7 @@ struct TreeContext /* tree context for semantic checks */
/*
* This function adds a definition to the lexical scope represented by this
* TreeContext.
* ParseContext.
*
* Pre-conditions:
* + The caller must have already taken care of name collisions:
@ -109,7 +109,7 @@ struct TreeContext /* tree context for semantic checks */
* LeaveFunction) that we should consider rewriting.
*
* Post-conditions:
* + tc->decls().lookupFirst(name) == pn
* + pc->decls().lookupFirst(name) == pn
* + The given name 'pn' has been converted in-place into a
* non-placeholder definition.
* + If this is a function scope (sc->inFunction), 'pn' is bound to a
@ -141,7 +141,7 @@ struct TreeContext /* tree context for semantic checks */
* After a function body has been parsed, the parser generates the
* function's "bindings". Bindings are a data-structure, ultimately stored
* in the compiled JSScript, that serve three purposes:
* - After parsing, the TreeContext is destroyed and 'decls' along with
* - After parsing, the ParseContext is destroyed and 'decls' along with
* it. Mostly, the emitter just uses the binding information stored in
* the use/def nodes, but the emitter occasionally needs 'bindings' for
* various scope-related queries.
@ -165,14 +165,14 @@ struct TreeContext /* tree context for semantic checks */
CompileError *queuedStrictModeError;
private:
TreeContext **parserTC; /* this points to the Parser's active tc
ParseContext **parserPC; /* this points to the Parser's active pc
and holds either |this| or one of
|this|'s descendents */
public:
OwnedAtomDefnMapPtr lexdeps; /* unresolved lexical name dependencies */
TreeContext *parent; /* Enclosing function or global context. */
ParseContext *parent; /* Enclosing function or global context. */
ParseNode *innermostWith; /* innermost WITH parse node */
@ -200,8 +200,8 @@ struct TreeContext /* tree context for semantic checks */
// they need to be treated differently.
bool inDeclDestructuring:1;
inline TreeContext(Parser *prs, SharedContext *sc, unsigned staticLevel, uint32_t bodyid);
inline ~TreeContext();
inline ParseContext(Parser *prs, SharedContext *sc, unsigned staticLevel, uint32_t bodyid);
inline ~ParseContext();
inline bool init();
@ -220,7 +220,7 @@ struct TreeContext /* tree context for semantic checks */
};
bool
GenerateBlockId(TreeContext *tc, uint32_t &blockid);
GenerateBlockId(ParseContext *pc, uint32_t &blockid);
struct BindData;
@ -237,7 +237,7 @@ struct Parser : private AutoGCRooter
ParseNodeAllocator allocator;
ObjectBox *traceListHead; /* list of parsed object for GC tracing */
TreeContext *tc; /* innermost tree context (stack-allocated) */
ParseContext *pc; /* innermost parse context (stack-allocated) */
SourceCompressionToken *sct; /* compression token for aborting */
@ -300,14 +300,14 @@ struct Parser : private AutoGCRooter
*/
ObjectBox *newObjectBox(JSObject *obj);
FunctionBox *newFunctionBox(JSObject *obj, ParseNode *fn, TreeContext *tc,
FunctionBox *newFunctionBox(JSObject *obj, ParseNode *fn, ParseContext *pc,
StrictMode::StrictModeState sms);
/*
* Create a new function object given tree context (tc) and a name (which
* Create a new function object given parse context (pc) and a name (which
* is optional if this is a function expression).
*/
JSFunction *newFunction(TreeContext *tc, JSAtom *atom, FunctionSyntaxKind kind);
JSFunction *newFunction(ParseContext *pc, JSAtom *atom, FunctionSyntaxKind kind);
void trace(JSTracer *trc);
@ -365,8 +365,8 @@ struct Parser : private AutoGCRooter
/*
* JS parsers, from lowest to highest precedence.
*
* Each parser must be called during the dynamic scope of a TreeContext
* object, pointed to by this->tc.
* Each parser must be called during the dynamic scope of a ParseContext
* object, pointed to by this->pc.
*
* Each returns a parse node tree or null on error.
*
@ -456,7 +456,7 @@ struct Parser : private AutoGCRooter
// strict. This also effectively bans XML in function defaults. See bug
// 772691.
bool allowsXML() const {
return tc->sc->strictModeState == StrictMode::NOTSTRICT && tokenStream.allowsXML();
return pc->sc->strictModeState == StrictMode::NOTSTRICT && tokenStream.allowsXML();
}
ParseNode *endBracketedExpr();

View File

@ -61,10 +61,10 @@ MarkExtensibleScopeDescendants(JSContext *context, FunctionBox *funbox, bool has
bool
frontend::AnalyzeFunctions(Parser *parser)
{
TreeContext *tc = parser->tc;
if (!tc->functionList)
ParseContext *pc = parser->pc;
if (!pc->functionList)
return true;
if (!MarkExtensibleScopeDescendants(tc->sc->context, tc->functionList, false))
if (!MarkExtensibleScopeDescendants(pc->sc->context, pc->functionList, false))
return false;
return true;
}

View File

@ -118,7 +118,7 @@ class ContextFlags {
/*
* The struct SharedContext is part of the current parser context (see
* TreeContext). It stores information that is reused between the parser and
* ParseContext). It stores information that is reused between the parser and
* the bytecode emitter. Note however, that this information is not shared
* between the two; they simply reuse the same data structure.
*/
@ -237,7 +237,7 @@ enum StmtType {
* pending the "reformed with" in ES4/JS2). It includes all try-catch-finally
* types, which are high-numbered maybe-scope types.
*
* StmtInfoBase::linksScope() tells whether a js::StmtInfo{TC,BCE} of the given
* StmtInfoBase::linksScope() tells whether a js::StmtInfo{PC,BCE} of the given
* type eagerly links to other scoping statement info records. It excludes the
* two early "maybe" types, block and switch, as well as the try and both
* finally types, since try and the other trailing maybe-scope types don't need
@ -248,7 +248,7 @@ enum StmtType {
* proposal for ES4, we would be able to model it statically, too.
*/
// StmtInfoTC is used by the Parser. StmtInfoBCE is used by the
// StmtInfoPC is used by the Parser. StmtInfoBCE is used by the
// BytecodeEmitter. The two types have some overlap, encapsulated by
// StmtInfoBase. Several functions below (e.g. PushStatement) are templated to
// work with both types.
@ -308,7 +308,7 @@ struct FunctionBox : public ObjectBox
ContextFlags cxFlags;
FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseNode *fn, TreeContext *tc,
FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseNode *fn, ParseContext *pc,
StrictMode::StrictModeState sms);
bool funIsGenerator() const { return cxFlags.funIsGenerator; }
@ -325,7 +325,7 @@ struct FunctionBox : public ObjectBox
void recursivelySetStrictMode(StrictMode::StrictModeState strictness);
};
// Push the C-stack-allocated struct at stmt onto the StmtInfoTC stack.
// Push the C-stack-allocated struct at stmt onto the StmtInfoPC stack.
template <class ContextT>
void
PushStatement(ContextT *ct, typename ContextT::StmtInfo *stmt, StmtType type);
@ -334,7 +334,7 @@ template <class ContextT>
void
FinishPushBlockScope(ContextT *ct, typename ContextT::StmtInfo *stmt, StaticBlockObject &blockObj);
// Pop tc->topStmt. If the top StmtInfoTC struct is not stack-allocated, it
// Pop pc->topStmt. If the top StmtInfoPC struct is not stack-allocated, it
// is up to the caller to free it. The dummy argument is just to make the
// template matching work.
template <class ContextT>

View File

@ -451,7 +451,7 @@ StrictModeFromContext(JSContext *cx)
// This class is a tiny back-channel from TokenStream to the strict mode flag
// that avoids exposing the rest of SharedContext to TokenStream. get()
// returns the current strict mode state. The other two methods get and set
// the queuedStrictModeError member of TreeContext. StrictModeGetter's
// the queuedStrictModeError member of ParseContext. StrictModeGetter's
// non-inline methods are implemented in Parser.cpp.
//
class StrictModeGetter {

View File

@ -310,7 +310,7 @@ class StaticBlockObject : public BlockObject
frontend::Definition *maybeDefinitionParseNode(unsigned i);
/*
* The parser uses 'enclosingBlock' as the prev-link in the tc->blockChain
* The parser uses 'enclosingBlock' as the prev-link in the pc->blockChain
* stack. Note: in the case of hoisting, this prev-link will not ultimately
* be the same as enclosingBlock, initEnclosingStaticScope must be called
* separately in the emitter. 'reset' is just for asserting stackiness.