mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-09 00:11:44 +00:00
Modifying 'break' to skip block frames...
This commit is contained in:
parent
4df458af4c
commit
efccdcf4f5
@ -430,7 +430,7 @@ namespace MetaData {
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
enum { BRANCH_OFFSET = 1, STR_PTR, TYPE_PTR, NAME_INDEX, FRAME_INDEX, BRANCH_PAIR, U16, FLOAT64 };
|
||||
enum { BRANCH_OFFSET = 1, STR_PTR, TYPE_PTR, NAME_INDEX, FRAME_INDEX, BRANCH_PAIR, U16, FLOAT64, BREAK_OFFSET_AND_COUNT };
|
||||
struct {
|
||||
JS2Op op;
|
||||
char *name;
|
||||
@ -520,6 +520,7 @@ namespace MetaData {
|
||||
{ eBranchFalse, "BranchFalse", BRANCH_OFFSET }, // <branch displacement:s32> XXX save space with short and long versions instead ?
|
||||
{ eBranchTrue, "BranchTrue", BRANCH_OFFSET }, // <branch displacement:s32>
|
||||
{ eBranch, "Branch", BRANCH_OFFSET }, // <branch displacement:s32>
|
||||
{ eBreak, "Break", BREAK_OFFSET_AND_COUNT }, // <branch displacement:s32> <blockCount:u16>
|
||||
{ eNew, "New", U16 }, // <argCount:u16>
|
||||
{ eCall, "Call", U16 }, // <argCount:u16>
|
||||
{ eTypeof, "Typeof", 0 },
|
||||
@ -573,6 +574,15 @@ namespace MetaData {
|
||||
pc += sizeof(int32);
|
||||
}
|
||||
break;
|
||||
case BREAK_OFFSET_AND_COUNT:
|
||||
{
|
||||
int32 offset = BytecodeContainer::getOffset(pc);
|
||||
stdOut << " " << offset << " --> " << (pc - start) + offset;
|
||||
pc += sizeof(int32);
|
||||
printFormat(stdOut, " (%d)", BytecodeContainer::getShort(pc));
|
||||
pc += sizeof(short);
|
||||
}
|
||||
break;
|
||||
case TYPE_PTR:
|
||||
{
|
||||
JS2Class *c = BytecodeContainer::getType(pc);
|
||||
@ -744,6 +754,7 @@ namespace MetaData {
|
||||
|
||||
case eReturnVoid:
|
||||
case eBranch:
|
||||
case eBreak:
|
||||
return 0;
|
||||
|
||||
case eVoid: // remove top item, push undefined
|
||||
|
@ -129,6 +129,7 @@ enum JS2Op {
|
||||
eBranchFalse, // <branch displacement:s32> XXX save space with short and long versions instead ?
|
||||
eBranchTrue, // <branch displacement:s32>
|
||||
eBranch, // <branch displacement:s32>
|
||||
eBreak, // <branch displacement:s32> <blockCount:u16>
|
||||
eNew, // <argCount:u16>
|
||||
eCall, // <argCount:u16>
|
||||
eTypeof,
|
||||
|
@ -161,8 +161,10 @@ namespace MetaData {
|
||||
b->compileFrame = new BlockFrame();
|
||||
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);
|
||||
ValidateStmtList(cxt, env, pl, b->statements);
|
||||
env->removeTopFrame();
|
||||
targetList.pop_back();
|
||||
}
|
||||
break;
|
||||
case StmtNode::label:
|
||||
@ -171,8 +173,8 @@ namespace MetaData {
|
||||
l->labelID = bCon->getLabel();
|
||||
/*
|
||||
A labelled statement catches contained, named, 'breaks' but simply adds itself as a label for
|
||||
contained iteration statements. (i.e. you can 'break' out of a labelled statement, but not 'continue'
|
||||
one, however the statement label becomes a 'continuable' label for all contained iteration statements.
|
||||
contained iteration statements. (i.e. one can 'break' out of a labelled statement, but not 'continue'
|
||||
one, however the statement label becomes a 'continuable' label for all contained iteration statements.)
|
||||
*/
|
||||
// Make sure there is no existing break target with the same name
|
||||
for (TargetListIterator si = targetList.begin(), end = targetList.end(); (si != end); si++) {
|
||||
@ -259,8 +261,9 @@ namespace MetaData {
|
||||
case StmtNode::Break:
|
||||
{
|
||||
GoStmtNode *g = checked_cast<GoStmtNode *>(p);
|
||||
bool found = false;
|
||||
for (TargetListReverseIterator si = targetList.rbegin(), end = targetList.rend(); (si != end); si++) {
|
||||
g->blockCount = 0;
|
||||
g->tgtID = -1;
|
||||
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)
|
||||
@ -268,7 +271,6 @@ namespace MetaData {
|
||||
LabelStmtNode *l = checked_cast<LabelStmtNode *>(*si);
|
||||
if (l->name == *g->name) {
|
||||
g->tgtID = l->labelID;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -276,6 +278,9 @@ namespace MetaData {
|
||||
else {
|
||||
// anything at all will do
|
||||
switch ((*si)->getKind()) {
|
||||
case StmtNode::block:
|
||||
g->blockCount++;
|
||||
break;
|
||||
case StmtNode::label:
|
||||
{
|
||||
LabelStmtNode *l = checked_cast<LabelStmtNode *>(*si);
|
||||
@ -303,26 +308,25 @@ namespace MetaData {
|
||||
}
|
||||
break;
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
if (g->tgtID == -1)
|
||||
reportError(Exception::syntaxError, "No such break target available", p->pos);
|
||||
}
|
||||
break;
|
||||
case StmtNode::Continue:
|
||||
{
|
||||
GoStmtNode *g = checked_cast<GoStmtNode *>(p);
|
||||
bool found = false;
|
||||
for (TargetListIterator si = targetList.begin(), end = targetList.end(); (si != end); si++) {
|
||||
g->blockCount = 0;
|
||||
g->tgtID = -1;
|
||||
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) {
|
||||
LabelStmtNode *l = checked_cast<LabelStmtNode *>(*si);
|
||||
if (l->name == *g->name) {
|
||||
g->tgtID = l->labelID;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -330,6 +334,9 @@ namespace MetaData {
|
||||
else {
|
||||
// only some non-label statements will do
|
||||
switch ((*si)->getKind()) {
|
||||
case StmtNode::block:
|
||||
g->blockCount++;
|
||||
break;
|
||||
case StmtNode::While:
|
||||
case StmtNode::DoWhile:
|
||||
{
|
||||
@ -344,11 +351,10 @@ namespace MetaData {
|
||||
g->tgtID = f->continueLabelID;
|
||||
}
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
if (g->tgtID == -1)
|
||||
reportError(Exception::syntaxError, "No such break target available", p->pos);
|
||||
}
|
||||
break;
|
||||
@ -742,7 +748,8 @@ namespace MetaData {
|
||||
case StmtNode::Continue:
|
||||
{
|
||||
GoStmtNode *g = checked_cast<GoStmtNode *>(p);
|
||||
bCon->emitBranch(eBranch, g->tgtID, p->pos);
|
||||
bCon->emitBranch(eBreak, g->tgtID, p->pos);
|
||||
// bCon->
|
||||
}
|
||||
break;
|
||||
case StmtNode::ForIn:
|
||||
|
@ -64,6 +64,17 @@
|
||||
}
|
||||
break;
|
||||
|
||||
case eBreak:
|
||||
{
|
||||
int32 offset = BytecodeContainer::getOffset(pc);
|
||||
pc += sizeof(int32);
|
||||
uint32 blockCount = BytecodeContainer::getShort(pc);
|
||||
pc += sizeof(short);
|
||||
//
|
||||
pc += offset;
|
||||
}
|
||||
break;
|
||||
|
||||
case ePop:
|
||||
{
|
||||
pop();
|
||||
|
@ -647,6 +647,7 @@ namespace JavaScript {
|
||||
void print(PrettyPrinter &f, bool noSemi) const;
|
||||
#ifdef EPIMETHEUS
|
||||
MetaData::LabelID tgtID;
|
||||
uint32 blockCount;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user