Bug 770849 - Move StmtInfoBCE to BytecodeEmitter.cpp. r=njn.

This commit is contained in:
Jason Orendorff 2012-07-06 16:32:57 -05:00
parent 991d5e3c25
commit 70febaa7ed
3 changed files with 52 additions and 45 deletions

View File

@ -65,6 +65,42 @@ NewTryNote(JSContext *cx, BytecodeEmitter *bce, JSTryNoteKind kind, unsigned sta
static bool
SetSrcNoteOffset(JSContext *cx, BytecodeEmitter *bce, unsigned index, unsigned which, ptrdiff_t offset);
struct js::StmtInfoBCE : public js::StmtInfoBase
{
StmtInfoBCE *down; /* info for enclosing statement */
StmtInfoBCE *downScope; /* next enclosing lexical scope */
ptrdiff_t update; /* loop update offset (top if none) */
ptrdiff_t breaks; /* offset of last break in loop */
ptrdiff_t continues; /* offset of last continue in loop */
StmtInfoBCE(JSContext *cx) : StmtInfoBase(cx) {}
/*
* To reuse space, alias the three ptrdiff_t fields for use during
* try/catch/finally code generation and backpatching.
*
* Only a loop, switch, or label statement info record can have breaks and
* continues, and only a for loop has an update backpatch chain, so it's
* safe to overlay these for the "trying" StmtTypes.
*/
ptrdiff_t &gosubs() {
JS_ASSERT(type == STMT_FINALLY);
return breaks;
}
ptrdiff_t &catchNote() {
JS_ASSERT(type == STMT_TRY || type == STMT_FINALLY);
return update;
}
ptrdiff_t &guardJump() {
JS_ASSERT(type == STMT_TRY || type == STMT_FINALLY);
return continues;
}
};
BytecodeEmitter::BytecodeEmitter(BytecodeEmitter *parent, Parser *parser, SharedContext *sc,
HandleScript script, StackFrame *callerFrame, bool hasGlobalScope,
unsigned lineno)
@ -1560,6 +1596,19 @@ CheckSideEffects(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool *answe
return ok;
}
bool
BytecodeEmitter::checkSingletonContext()
{
if (!script->compileAndGo || sc->inFunction())
return false;
for (StmtInfoBCE *stmt = topStmt; stmt; stmt = stmt->down) {
if (stmt->isLoop())
return false;
}
hasSingletons = true;
return true;
}
bool
BytecodeEmitter::needsImplicitThis()
{

View File

@ -51,6 +51,8 @@ class GCConstList {
void finish(ConstArray *array);
};
class StmtInfoBCE;
struct BytecodeEmitter
{
typedef StmtInfoBCE StmtInfo;
@ -151,16 +153,7 @@ struct BytecodeEmitter
return true;
}
bool checkSingletonContext() {
if (!script->compileAndGo || sc->inFunction())
return false;
for (StmtInfoBCE *stmt = topStmt; stmt; stmt = stmt->down) {
if (stmt->isLoop())
return false;
}
hasSingletons = true;
return true;
}
bool checkSingletonContext();
bool needsImplicitThis();

View File

@ -375,41 +375,6 @@ struct StmtInfoTC : public StmtInfoBase {
StmtInfoTC(JSContext *cx) : StmtInfoBase(cx), isFunctionBodyBlock(false) {}
};
struct StmtInfoBCE : public StmtInfoBase {
StmtInfoBCE *down; /* info for enclosing statement */
StmtInfoBCE *downScope; /* next enclosing lexical scope */
ptrdiff_t update; /* loop update offset (top if none) */
ptrdiff_t breaks; /* offset of last break in loop */
ptrdiff_t continues; /* offset of last continue in loop */
StmtInfoBCE(JSContext *cx) : StmtInfoBase(cx) {}
/*
* To reuse space, alias the three ptrdiff_t fields for use during
* try/catch/finally code generation and backpatching.
*
* Only a loop, switch, or label statement info record can have breaks and
* continues, and only a for loop has an update backpatch chain, so it's
* safe to overlay these for the "trying" StmtTypes.
*/
ptrdiff_t &gosubs() {
JS_ASSERT(type == STMT_FINALLY);
return breaks;
}
ptrdiff_t &catchNote() {
JS_ASSERT(type == STMT_TRY || type == STMT_FINALLY);
return update;
}
ptrdiff_t &guardJump() {
JS_ASSERT(type == STMT_TRY || type == STMT_FINALLY);
return continues;
}
};
namespace frontend {
bool