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