Fixed parameter frame leaking.

This commit is contained in:
rogerl%netscape.com 2003-03-19 00:14:23 +00:00
Родитель 12df0824d1
Коммит 27ebcb1015
7 изменённых файлов: 31 добавлений и 26 удалений

Просмотреть файл

@ -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: