This commit is contained in:
rogerl%netscape.com 2003-06-19 21:43:15 +00:00
Родитель a14f61fcf1
Коммит afa1dec7bb
7 изменённых файлов: 101 добавлений и 27 удалений

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

@ -688,6 +688,9 @@ namespace MetaData {
{ eSlotPreInc, "SlotPreInc", U16 }, // <slot index:u16>
{ eSlotPreDec, "SlotPreDec", U16 }, // <slot index:u16>
{ eNop, "Nop", 0 },
};
uint8 *printInstruction(uint8 *pc, uint8 *start, BytecodeContainer *bCon, JS2Engine *engine)
@ -1009,6 +1012,10 @@ namespace MetaData {
case eBracketWriteRef: // pop base and index, leave value
return -2;
case eNop:
return 0;
default:
ASSERT(false);
}

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

@ -190,6 +190,9 @@ enum JS2Op {
eSlotPreInc, // <slot index:u16>
eSlotPreDec, // <slot index:u16>
eNop
};

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

@ -250,6 +250,7 @@ namespace MetaData {
{
BlockStmtNode *b = checked_cast<BlockStmtNode *>(p);
b->compileFrame = new (this) BlockFrame();
b->compileFrame->isFunctionFrame = (env->getTopFrame()->kind == ParameterFrameKind);
bCon->saveFrame(b->compileFrame); // stash this frame so it doesn't get gc'd before eval pass.
env->addFrame(b->compileFrame);
targetList.push_back(p);
@ -347,7 +348,6 @@ namespace MetaData {
case StmtNode::Break:
{
GoStmtNode *g = checked_cast<GoStmtNode *>(p);
g->blockCount = 0;
g->tgtID = -1;
if (g->name) {
// need to find the closest 'breakable' statement covered by the named label
@ -366,9 +366,6 @@ namespace MetaData {
}
}
break;
case StmtNode::block:
g->blockCount++;
break;
}
}
}
@ -377,9 +374,6 @@ namespace MetaData {
for (TargetListReverseIterator si = targetList.rbegin(), end = targetList.rend();
((g->tgtID == -1) && (si != end)); si++) {
switch ((*si)->getKind()) {
case StmtNode::block:
g->blockCount++;
break;
case StmtNode::While:
case StmtNode::DoWhile:
{
@ -410,7 +404,6 @@ namespace MetaData {
case StmtNode::Continue:
{
GoStmtNode *g = checked_cast<GoStmtNode *>(p);
g->blockCount = 0;
g->tgtID = -1;
if (g->name) {
// need to find the closest 'continuable' statement covered by the named label
@ -429,9 +422,6 @@ namespace MetaData {
}
}
break;
case StmtNode::block:
g->blockCount++;
break;
case StmtNode::While:
case StmtNode::DoWhile:
{
@ -456,9 +446,6 @@ namespace MetaData {
// only some non-label statements will do
StmtNode *s = *si;
switch (s->getKind()) {
case StmtNode::block:
g->blockCount++;
break;
case StmtNode::While:
case StmtNode::DoWhile:
{
@ -909,24 +896,32 @@ namespace MetaData {
case StmtNode::block:
case StmtNode::group:
{
targetList.push_back(p);
bool pushed = false;
BlockStmtNode *b = checked_cast<BlockStmtNode *>(p);
// BlockFrame *runtimeFrame = new (this) BlockFrame(b->compileFrame);
env->addFrame(b->compileFrame); // XXX is this right? shouldn't this be the compile frame until execution occurs?
bCon->emitOp(ePushFrame, p->pos);
bCon->addFrame(b->compileFrame);
if (b->compileFrame->isFunctionFrame || b->compileFrame->localBindings.size()) {
bCon->emitOp(ePushFrame, p->pos);
bCon->addFrame(b->compileFrame);
pushed = true;
}
env->addFrame(b->compileFrame);
StmtNode *bp = b->statements;
while (bp) {
SetupStmt(env, phase, bp);
bp = bp->next;
}
bCon->emitOp(ePopFrame, p->pos);
if (pushed)
bCon->emitOp(ePopFrame, p->pos);
env->removeTopFrame();
targetList.pop_back();
}
break;
case StmtNode::label:
{
LabelStmtNode *l = checked_cast<LabelStmtNode *>(p);
targetList.push_back(p);
SetupStmt(env, phase, l->stmt);
targetList.pop_back();
// labelled statements target are break targets
bCon->setLabel(l->labelID);
}
@ -965,7 +960,53 @@ namespace MetaData {
{
GoStmtNode *g = checked_cast<GoStmtNode *>(p);
bCon->emitBranch(eBreak, g->tgtID, p->pos);
bCon->addShort(g->blockCount);
uint32 blockCount = 0;
bool foundit = false;
for (TargetListReverseIterator si = targetList.rbegin(), end = targetList.rend();
((si != end) && !foundit); si++)
{
switch ((*si)->getKind()) {
case StmtNode::label:
{
LabelStmtNode *l = checked_cast<LabelStmtNode *>(*si);
if (g->tgtID == l->labelID)
foundit = true;
}
break;
case StmtNode::While:
case StmtNode::DoWhile:
{
UnaryStmtNode *w = checked_cast<UnaryStmtNode *>(*si);
if ((g->tgtID == w->breakLabelID) || (g->tgtID == w->continueLabelID))
foundit = true;
}
break;
case StmtNode::For:
case StmtNode::ForIn:
{
ForStmtNode *f = checked_cast<ForStmtNode *>(*si);
if ((g->tgtID == f->breakLabelID) || (g->tgtID == f->continueLabelID))
foundit = true;
}
break;
case StmtNode::Switch:
{
SwitchStmtNode *s = checked_cast<SwitchStmtNode *>(*si);
if (g->tgtID == s->breakLabelID)
foundit = true;
}
break;
case StmtNode::block:
{
BlockStmtNode *b = checked_cast<BlockStmtNode *>(*si);
if (b->compileFrame->isFunctionFrame || b->compileFrame->localBindings.size())
blockCount++;
}
break;
}
}
ASSERT(foundit);
bCon->addShort(blockCount);
}
break;
case StmtNode::ForIn:
@ -1028,7 +1069,9 @@ namespace MetaData {
}
v->emitWriteBytecode(bCon, p->pos);
bCon->emitOp(ePop, p->pos); // clear iterator value from stack
targetList.push_back(p);
SetupStmt(env, phase, f->stmt);
targetList.pop_back();
bCon->setLabel(f->continueLabelID);
bCon->emitOp(eNext, p->pos);
bCon->emitBranch(eBranchTrue, loopTop, p->pos);
@ -1047,7 +1090,9 @@ 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);
@ -1138,6 +1183,7 @@ 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) {
@ -1148,6 +1194,7 @@ namespace MetaData {
SetupStmt(env, phase, s);
s = s->next;
}
targetList.pop_back();
bCon->setLabel(sw->breakLabelID);
delete frV;
@ -1159,7 +1206,9 @@ 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);
@ -1172,7 +1221,9 @@ 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);

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

@ -655,6 +655,7 @@ public:
typedef BindingEntry<LocalBinding> LocalBindingEntry;
// A LocalBindingMap maps names to a list of LocalBindings. Each LocalBinding in the list
// will have the same QualifiedName.name, but (potentially) different QualifiedName.namespace values
typedef HashTable<LocalBindingEntry *, const StringAtom &> LocalBindingMap;
@ -1409,10 +1410,11 @@ public:
class BlockFrame : public NonWithFrame {
public:
BlockFrame() : NonWithFrame(BlockFrameKind) { }
BlockFrame(BlockFrame *pluralFrame) : NonWithFrame(BlockFrameKind, pluralFrame) { }
BlockFrame() : NonWithFrame(BlockFrameKind), isFunctionFrame(false) { }
BlockFrame(BlockFrame *pluralFrame) : NonWithFrame(BlockFrameKind, pluralFrame), isFunctionFrame(false) { }
Plurality plurality;
bool isFunctionFrame;
virtual void instantiate(Environment *env);
virtual ~BlockFrame() { }
@ -1751,6 +1753,9 @@ inline bool operator!=(MetaData::LocalBindingEntry *s1, const StringAtom &s2) {
inline bool operator==(MetaData::InstanceBindingEntry *s1, const StringAtom &s2) { return s1->name == s2;}
inline bool operator!=(MetaData::InstanceBindingEntry *s1, const StringAtom &s2) { return s1->name != s2;}
inline HashNumber hashString(const StringAtom &s) { return s.hash; }
}; // namespace Javascript
using namespace JavaScript;

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

@ -1154,9 +1154,16 @@
pc += sizeof(short);
ASSERT(slotIndex < localFrame->frameSlots->size());
a = (*localFrame->frameSlots)[slotIndex];
float64 num = meta->toFloat64(a);
(*localFrame->frameSlots)[slotIndex] = allocNumber(num + 1.0);
pushNumber(num);
int32 i;
if (JS2VAL_IS_INT(a) && ((i = JS2VAL_TO_INT(a)) < JS2VAL_INT_MAX)) {
(*localFrame->frameSlots)[slotIndex] = INT_TO_JS2VAL(i + 1);
push(a);
}
else {
float64 num = meta->toFloat64(a);
(*localFrame->frameSlots)[slotIndex] = allocNumber(num + 1.0);
pushNumber(num);
}
}
break;
case eFrameSlotPostDec:

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

@ -644,7 +644,6 @@ namespace JavaScript {
void print(PrettyPrinter &f, bool noSemi) const;
#ifdef EPIMETHEUS
MetaData::LabelID tgtID;
uint32 blockCount;
#endif
};

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

@ -53,7 +53,9 @@ namespace JavaScript {
public:
Token::Kind tokenKind; // Token::Kind if this is a keyword; Token::identifier if not
explicit StringAtom(const String &s): String(s), tokenKind(Token::identifier) {}
HashNumber hash;
explicit StringAtom(const String &s): String(s), tokenKind(Token::identifier), hash(hashString(s)) {}
private:
StringAtom(const StringAtom &); // No copy constructor
void operator=(const StringAtom &); // No assignment operator