зеркало из https://github.com/mozilla/gecko-dev.git
Fixed parameter frame leaking.
This commit is contained in:
Родитель
12df0824d1
Коммит
27ebcb1015
|
@ -316,6 +316,12 @@ js2val dump(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint
|
|||
DynamicPropertyBinding *dpb = *dpi;
|
||||
stdOut << "\t" << dpb->name << " = " << *meta->toString(dpb->v.value) << "\n";
|
||||
}
|
||||
if (pInst->type == meta->functionClass) {
|
||||
FunctionWrapper *fWrap = (checked_cast<FunctionInstance *>(fObj))->fWrap;
|
||||
stdOut << "Function:" << "\n";
|
||||
stdOut << "Environment depth " << fWrap->env->getSize() << "\n";
|
||||
dumpBytecode(fWrap->bCon);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -561,7 +561,9 @@ namespace MetaData {
|
|||
for (uint32 i = 0; i < (30 - bCon->fName.length()); i++)
|
||||
stdOut << " ";
|
||||
}
|
||||
printFormat(stdOut, "%.4d %.4d ", pc - start, (int32)(engine->sp - engine->execStack));
|
||||
printFormat(stdOut, "%.4d %.4d %.4d ", pc - start,
|
||||
(int32)(engine->sp - engine->execStack),
|
||||
(int32)(engine->activationStackTop - engine->activationStack));
|
||||
}
|
||||
else
|
||||
printFormat(stdOut, "%.4d ", pc - start);
|
||||
|
@ -859,10 +861,10 @@ namespace MetaData {
|
|||
activationStackTop->bCon = bCon;
|
||||
activationStackTop->pc = pc;
|
||||
activationStackTop->phase = phase;
|
||||
// activationStackTop->topFrame = meta->env->getTopFrame();
|
||||
activationStackTop->execStackBase = stackBase;
|
||||
activationStackTop->retval = returnVal;
|
||||
activationStackTop->env = meta->env;
|
||||
activationStackTop->env = meta->env; // save current env.
|
||||
activationStackTop->topFrame = env->getTopFrame(); // remember how big the new env. is supposed to be
|
||||
activationStackTop++;
|
||||
bCon = new_bCon;
|
||||
if ((int32)bCon->getMaxStack() >= (execStackLimit - sp)) {
|
||||
|
@ -888,9 +890,11 @@ namespace MetaData {
|
|||
bCon = activationStackTop->bCon;
|
||||
pc = activationStackTop->pc;
|
||||
phase = activationStackTop->phase;
|
||||
// reset the env. top
|
||||
while (meta->env->getTopFrame() != activationStackTop->topFrame)
|
||||
meta->env->removeTopFrame();
|
||||
// reset to previous env.
|
||||
meta->env = activationStackTop->env;
|
||||
// while (meta->env->getTopFrame() != activationStackTop->topFrame)
|
||||
// meta->env->removeTopFrame();
|
||||
sp = execStack + activationStackTop->execStackBase;
|
||||
if (!JS2VAL_IS_VOID(activationStackTop->retval)) // XXX might need an actual 'returnValue' flag instead
|
||||
retval = activationStackTop->retval;
|
||||
|
|
|
@ -273,6 +273,7 @@ public:
|
|||
js2val retval;
|
||||
uint32 execStackBase;
|
||||
Environment *env;
|
||||
Frame *topFrame;
|
||||
};
|
||||
void jsr(Phase execPhase, BytecodeContainer *bCon, uint32 stackBase, js2val returnVal, Environment *env);
|
||||
bool activationStackEmpty() { return (activationStackTop == activationStack); }
|
||||
|
|
|
@ -263,7 +263,8 @@ namespace MetaData {
|
|||
GoStmtNode *g = checked_cast<GoStmtNode *>(p);
|
||||
g->blockCount = 0;
|
||||
g->tgtID = -1;
|
||||
for (TargetListReverseIterator si = targetList.rbegin(), end = targetList.rend(); (g->tgtID == -1) && (si != end); si++) {
|
||||
for (TargetListReverseIterator si = targetList.rbegin(), end = targetList.rend();
|
||||
((g->tgtID == -1) && (si != end)); si++) {
|
||||
if (g->name) {
|
||||
// Make sure the name is on the targetList as a viable break target...
|
||||
// (only label statements can introduce names)
|
||||
|
@ -301,14 +302,13 @@ namespace MetaData {
|
|||
g->tgtID = f->breakLabelID;
|
||||
}
|
||||
break;
|
||||
case StmtNode::Switch:
|
||||
case StmtNode::Switch:
|
||||
{
|
||||
SwitchStmtNode *s = checked_cast<SwitchStmtNode *>(*si);
|
||||
g->tgtID = s->breakLabelID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (g->tgtID == -1)
|
||||
|
@ -320,7 +320,8 @@ namespace MetaData {
|
|||
GoStmtNode *g = checked_cast<GoStmtNode *>(p);
|
||||
g->blockCount = 0;
|
||||
g->tgtID = -1;
|
||||
for (TargetListIterator si = targetList.begin(), end = targetList.end(); (g->tgtID == -1) && (si != end); si++) {
|
||||
for (TargetListIterator si = targetList.begin(), end = targetList.end();
|
||||
((g->tgtID == -1) && (si != end)); si++) {
|
||||
if (g->name) {
|
||||
// Make sure the name is on the targetList as a viable continue target...
|
||||
if ((*si)->getKind() == StmtNode::label) {
|
||||
|
@ -351,7 +352,6 @@ namespace MetaData {
|
|||
g->tgtID = f->continueLabelID;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (g->tgtID == -1)
|
||||
|
@ -749,7 +749,7 @@ namespace MetaData {
|
|||
{
|
||||
GoStmtNode *g = checked_cast<GoStmtNode *>(p);
|
||||
bCon->emitBranch(eBreak, g->tgtID, p->pos);
|
||||
// bCon->
|
||||
bCon->addShort(g->blockCount);
|
||||
}
|
||||
break;
|
||||
case StmtNode::ForIn:
|
||||
|
@ -813,7 +813,6 @@ namespace MetaData {
|
|||
v->emitWriteBytecode(bCon, p->pos);
|
||||
bCon->emitOp(ePop, p->pos); // clear iterator value from stack
|
||||
SetupStmt(env, phase, f->stmt);
|
||||
targetList.pop_back();
|
||||
bCon->setLabel(f->continueLabelID);
|
||||
bCon->emitOp(eNext, p->pos);
|
||||
bCon->emitBranch(eBranchTrue, loopTop, p->pos);
|
||||
|
@ -832,9 +831,7 @@ namespace MetaData {
|
|||
if (f->expr2)
|
||||
bCon->emitBranch(eBranch, testLocation, p->pos);
|
||||
bCon->setLabel(loopTop);
|
||||
targetList.push_back(p);
|
||||
SetupStmt(env, phase, f->stmt);
|
||||
targetList.pop_back();
|
||||
bCon->setLabel(f->continueLabelID);
|
||||
if (f->expr3) {
|
||||
Reference *r = SetupExprNode(env, phase, f->expr3, &exprType);
|
||||
|
@ -915,7 +912,6 @@ namespace MetaData {
|
|||
else
|
||||
bCon->emitBranch(eBranch, defaultLabel, p->pos);
|
||||
// Now emit the contents
|
||||
targetList.push_back(p);
|
||||
s = sw->statements;
|
||||
while (s) {
|
||||
if (s->getKind() == StmtNode::Case) {
|
||||
|
@ -926,7 +922,6 @@ namespace MetaData {
|
|||
SetupStmt(env, phase, s);
|
||||
s = s->next;
|
||||
}
|
||||
targetList.pop_back();
|
||||
|
||||
bCon->setLabel(sw->breakLabelID);
|
||||
}
|
||||
|
@ -937,9 +932,7 @@ namespace MetaData {
|
|||
BytecodeContainer::LabelID loopTop = bCon->getLabel();
|
||||
bCon->emitBranch(eBranch, w->continueLabelID, p->pos);
|
||||
bCon->setLabel(loopTop);
|
||||
targetList.push_back(p);
|
||||
SetupStmt(env, phase, w->stmt);
|
||||
targetList.pop_back();
|
||||
bCon->setLabel(w->continueLabelID);
|
||||
Reference *r = SetupExprNode(env, phase, w->expr, &exprType);
|
||||
if (r) r->emitReadBytecode(bCon, p->pos);
|
||||
|
@ -952,9 +945,7 @@ namespace MetaData {
|
|||
UnaryStmtNode *w = checked_cast<UnaryStmtNode *>(p);
|
||||
BytecodeContainer::LabelID loopTop = bCon->getLabel();
|
||||
bCon->setLabel(loopTop);
|
||||
targetList.push_back(p);
|
||||
SetupStmt(env, phase, w->stmt);
|
||||
targetList.pop_back();
|
||||
bCon->setLabel(w->continueLabelID);
|
||||
Reference *r = SetupExprNode(env, phase, w->expr, &exprType);
|
||||
if (r) r->emitReadBytecode(bCon, p->pos);
|
||||
|
|
|
@ -608,6 +608,8 @@ public:
|
|||
|
||||
void markChildren();
|
||||
|
||||
uint32 getSize() { return frameList.size(); }
|
||||
|
||||
private:
|
||||
FrameList frameList;
|
||||
};
|
||||
|
|
|
@ -66,11 +66,12 @@
|
|||
|
||||
case eBreak:
|
||||
{
|
||||
// don't update the pc in order to get the blockcount
|
||||
// since the branch calculation doesn't include that.
|
||||
int32 offset = BytecodeContainer::getOffset(pc);
|
||||
pc += sizeof(int32);
|
||||
uint32 blockCount = BytecodeContainer::getShort(pc);
|
||||
pc += sizeof(short);
|
||||
//
|
||||
uint32 blockCount = BytecodeContainer::getShort(pc + sizeof(int32));
|
||||
for (uint32 i = 0; i < blockCount; i++)
|
||||
meta->env->removeTopFrame();
|
||||
pc += offset;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -210,7 +210,7 @@
|
|||
if (pc == NULL)
|
||||
return retval;
|
||||
push(retval);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case eReturnVoid:
|
||||
|
@ -219,7 +219,7 @@
|
|||
if (pc == NULL)
|
||||
return retval;
|
||||
push(retval);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ePushFrame:
|
||||
|
|
Загрузка…
Ссылка в новой задаче