This commit is contained in:
rogerl%netscape.com 2002-10-21 22:33:41 +00:00
Родитель 2d711c26ac
Коммит 1ad15ae47f
12 изменённых файлов: 127 добавлений и 41 удалений

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

@ -43,6 +43,7 @@
#include <algorithm>
#include <assert.h>
#include <list>
#include <stack>
#include "world.h"
#include "utilities.h"

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

@ -38,6 +38,7 @@
#include <map>
#include <algorithm>
#include <list>
#include <stack>
#include "reader.h"
#include "parser.h"

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

@ -41,6 +41,7 @@
#include <algorithm>
#include <list>
#include <map>
#include <stack>
#include "world.h"
#include "utilities.h"

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

@ -41,6 +41,7 @@
#include <algorithm>
#include <list>
#include <map>
#include <stack>
#include <assert.h>
#include <ctype.h>

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

@ -44,6 +44,7 @@
#include <algorithm>
#include <assert.h>
#include <list>
#include <stack>
#include "world.h"
#include "utilities.h"
@ -97,27 +98,26 @@ namespace MetaData {
}
}
catch (Exception &jsx) {
#if 0
if (mTryStack.size() > 0) {
HandlerData *hndlr = (HandlerData *)mTryStack.top();
Activation *curAct = (mActivationStack.size() > 0) ? mActivationStack.top() : NULL;
ActivationFrame *curAct = (activationStackEmpty()) ? NULL : (activationStackTop - 1);
js2val x;
if (curAct != hndlr->mActivation) {
ASSERT(mActivationStack.size() > 0);
Activation *prev;// = mActivationStack.top();
ASSERT(!activationStackEmpty());
ActivationFrame *prev;
do {
prev = curAct;
if (prev->mPC == NULL) {
if (prev->pc == NULL) {
// Yikes! the exception is getting thrown across a re-invocation
// of the interpreter loop.
throw jsx;
}
mActivationStack.pop();
curAct = mActivationStack.top();
curAct = --activationStackTop;
} while (hndlr->mActivation != curAct);
if (jsx.hasKind(Exception::userException)) // snatch the exception before the stack gets clobbered
x = popValue();
x = pop();
/*
mNamespaceList = prev->mNamespaceList;
mCurModule = prev->mModule;
endPC = mCurModule->mCodeBase + mCurModule->mLength;
@ -126,12 +126,13 @@ namespace MetaData {
mStackMax = mCurModule->mStackDepth;
mArgumentBase = prev->mArgumentBase;
mThis = prev->mThis;
*/
}
else {
if (jsx.hasKind(Exception::userException))
x = popValue();
x = pop();
}
#if 0
// make sure there's a JS object for the catch clause to work with
if (!jsx.hasKind(Exception::userException)) {
js2val argv[1];
@ -154,14 +155,13 @@ namespace MetaData {
break;
}
}
resizeStack(hndlr->mStackSize);
#endif
sp = hndlr->mStackTop;
pc = hndlr->mPC;
pushValue(x);
push(x);
}
else
throw jsx; //reportError(Exception::uncaughtError, "No handler for throw");
#endif
}
return retval;
@ -409,6 +409,15 @@ namespace MetaData {
case eLogicalNot:
return 0;
case eIs: // pop expr, pop type, bush boolean
return 1;
case eTry: // no exec. stack impact
case eHandler:
case eCallFinally:
case eReturnFinally:
return 0;
case eString:
case eTrue:
case eFalse:
@ -601,6 +610,20 @@ namespace MetaData {
JS2Object::mark(length_StringAtom);
}
void JS2Engine::pushHandler(uint8 *pc)
{
ActivationFrame *curAct = (activationStackEmpty()) ? NULL : (activationStackTop - 1);
mTryStack.push(new HandlerData(pc, sp, curAct));
}
void JS2Engine::popHandler()
{
HandlerData *hndlr = mTryStack.top();
mTryStack.pop();
delete hndlr;
}
//
// XXX Only scanning dynamic properties
//

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

@ -118,6 +118,7 @@ enum JS2Op {
eNew, // <argCount:u16>
eCall, // <argCount:u16>
eTypeof,
eIs,
ePopv,
ePop,
@ -264,9 +265,20 @@ public:
// insert 'x' before the top 'count' stack items
void insert(js2val x, int count);
struct HandlerData {
HandlerData(uint8 *pc, js2val *stackTop, ActivationFrame *curAct)
: mPC(pc), mStackTop(stackTop), mActivation(curAct) { }
void pushHandler(uint8 *pc) { }
void popHandler() { }
uint8 *mPC;
js2val *mStackTop;
ActivationFrame *mActivation;
};
std::stack<HandlerData *> mTryStack;
std::stack<uint8 *> mSubStack;
void pushHandler(uint8 *pc);
void popHandler();
void mark();

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

@ -41,6 +41,7 @@
#include <algorithm>
#include <list>
#include <map>
#include <stack>
#include "world.h"
#include "utilities.h"

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

@ -44,6 +44,7 @@
#include <assert.h>
#include <map>
#include <list>
#include <stack>
#include "world.h"
#include "utilities.h"
@ -851,29 +852,29 @@ namespace MetaData {
break;
case StmtNode::Try:
/*
try { // [catch,finally] handler labels are pushed on try stack [eTry]
try { // [catchLabel,finallyInvoker] handler labels are pushed on handler stack [eTry]
<tryblock>
} // catch handler label is popped off try stack [eHandler]
} // catch handler label is popped off handler stack [eHandler]
jsr finally
jump-->finished
finally: // finally handler label popped off
{ // a throw from in here goes to the 'next' handler
finally: // finally handler label popped off here.
{ // A throw from in here goes to the next handler on the
// handler stack
}
rts
finallyInvoker: <---
push exception |
jsr finally |--- the handler labels
throw exception |
|
catchLabel: <---
finallyInvoker: // invoked when an exception is caught in the try block
push exception // it arranges to call the finally block and then re-throw
jsr finally // the exception - reaching the catch block
throw exception
catchLabel:
the incoming exception is on the top of the stack at this point
catch (exception) { // catch handler label popped off
// any throw from in here must jump to the finallyInvoker
// (i.e. not the catch handler!)
catch (exception) { // catch handler label popped off [eHandler]
// any throw from in here must jump to the next handler
// (i.e. not the this same catch handler!)
Of the many catch clauses specified, only the one whose exception variable type
matches the type of the incoming exception is executed...
@ -941,19 +942,43 @@ namespace MetaData {
bCon->emitBranch(eBranch, finishedLabel, p->pos);
}
/*
ValidateStmt(cxt, env, t->stmt);
if (t->finally)
ValidateStmt(cxt, env, t->finally);
if (t->catches) {
bCon->setLabel(catchClauseLabel);
bCon->emitOp(eHandler, p->pos);
CatchClause *c = t->catches;
// the exception object will be the only thing on the stack
ASSERT(bCon->mStackTop == 0);
bCon->mStackTop = 1;
if (bCon->mStackMax < 1) bCon->mStackMax = 1;
BytecodeContainer::LabelID nextCatch = NotALabel;
while (c) {
ValidateStmt(cxt, env, c->stmt);
if (c->type)
ValidateExpression(cxt, env, c->type);
c = c->next;
if (c->next && c->type) {
nextCatch = bCon->getLabel();
bCon->emitOp(eDup, p->pos);
Reference *r = EvalExprNode(env, phase, c->type);
if (r) r->emitReadBytecode(bCon, p->pos);
bCon->emitOp(eIs, p->pos);
bCon->emitBranch(eBranchFalse, nextCatch, p->pos);
}
*/
// write the exception object (on stack top) into the named
// local variable
Reference *r = new LexicalReference(&c->name, false);
r->emitWriteBytecode(bCon, p->pos);
bCon->emitOp(ePop, p->pos);
EvalStmt(env, phase, c->stmt);
if (t->finally) {
bCon->emitBranch(eCallFinally, t_finallyLabel, p->pos);
}
c = c->next;
if (c) {
bCon->emitBranch(eBranch, finishedLabel, p->pos);
bCon->mStackTop = 1;
if (nextCatch != NotALabel)
bCon->setLabel(nextCatch);
}
}
}
bCon->setLabel(finishedLabel);
}
break;
case StmtNode::Return:

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

@ -133,3 +133,15 @@
popHandler();
}
break;
case eCallFinally:
{
}
break;
case eReturnFinally:
{
}
break;

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

@ -189,6 +189,13 @@
}
break;
case eIs:
{
a = pop();
b = pop();
}
break;
case eTypeof:
{
a = pop();

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

@ -41,6 +41,7 @@
#include <algorithm>
#include <list>
#include <map>
#include <stack>
#include <assert.h>
#include <ctype.h>

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

@ -41,6 +41,7 @@
#include <algorithm>
#include <list>
#include <map>
#include <stack>
#include "world.h"
#include "utilities.h"