cleaning up the codestate classes; continue labels
git-svn-id: svn://10.0.0.236/trunk@65124 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -161,20 +161,20 @@ void ICodeGenerator::setLabel(InstructionStream *stream, int32 label)
|
||||
|
||||
/***********************************************************************************************/
|
||||
|
||||
void MultiPathICodeState::mergeStream(InstructionStream *sideStream, InstructionStream *mainStream, LabelList &labels)
|
||||
void ICodeGenerator::mergeStream(InstructionStream *sideStream)
|
||||
{
|
||||
// change InstructionStream to be a class that also remembers
|
||||
// if it contains any labels (maybe even remembers the labels
|
||||
// themselves?) in order to avoid running this loop unnecessarily.
|
||||
for (LabelList::iterator i = labels.begin(); i != labels.end(); i++) {
|
||||
if ((*i)->itsBase == sideStream) {
|
||||
(*i)->itsBase = mainStream;
|
||||
(*i)->itsOffset += mainStream->size();
|
||||
(*i)->itsBase = iCode;
|
||||
(*i)->itsOffset += iCode->size();
|
||||
}
|
||||
}
|
||||
|
||||
for (InstructionIterator ii = sideStream->begin(); ii != sideStream->end(); ii++)
|
||||
mainStream->push_back(*ii);
|
||||
iCode->push_back(*ii);
|
||||
|
||||
}
|
||||
|
||||
@@ -217,10 +217,11 @@ void ICodeGenerator::endWhileStatement()
|
||||
stitcher.pop_back();
|
||||
|
||||
// mark the start of the condition code
|
||||
// and re-attach it to the main stream
|
||||
setLabel(ics->whileCondition);
|
||||
setLabel(ics->whileCondition); // which is where continues will target
|
||||
|
||||
// and re-attach it to the main stream
|
||||
mergeStream(ics->whileExpressionStream);
|
||||
|
||||
ics->mergeStream(iCode, labels);
|
||||
if (ics->breakLabel != -1)
|
||||
setLabel(ics->breakLabel);
|
||||
|
||||
@@ -236,13 +237,12 @@ void ICodeGenerator::beginForStatement(const SourcePosition &pos)
|
||||
int32 forCondition = getLabel();
|
||||
|
||||
ForCodeState *ics = new ForCodeState(forCondition, getLabel(), this);
|
||||
ics->continueLabel = getLabel();
|
||||
|
||||
branch(forCondition);
|
||||
|
||||
stitcher.push_back(ics);
|
||||
|
||||
iCode = new InstructionStream(); // begin the stream for collecting the test expression
|
||||
iCode = new InstructionStream(); // begin the stream for collecting the condition expression
|
||||
setLabel(forCondition);
|
||||
|
||||
resetTopRegister();
|
||||
@@ -259,7 +259,10 @@ void ICodeGenerator::forCondition(Register condition)
|
||||
iCode = ics->swapStream(iCode); // switch back to main stream
|
||||
iCode = new InstructionStream(); // begin the stream for collecting the increment expression
|
||||
|
||||
setLabel(ics->continueLabel); // which is where continues will target
|
||||
ics->continueLabel = getLabel();
|
||||
setLabel(ics->continueLabel); // can't lazily insert this since we haven't seen the body yet
|
||||
// ??? could just remember the offset
|
||||
|
||||
resetTopRegister();
|
||||
}
|
||||
|
||||
@@ -279,9 +282,10 @@ void ICodeGenerator::endForStatement()
|
||||
{
|
||||
ForCodeState *ics = static_cast<ForCodeState *>(stitcher.back());
|
||||
ASSERT(ics->stateKind == For_state);
|
||||
stitcher.pop_back();
|
||||
|
||||
ics->mergeStream2(iCode, labels); // merges the increment sequence
|
||||
ics->mergeStream(iCode, labels); // merges the test sequence
|
||||
mergeStream(ics->forIncrementStream);
|
||||
mergeStream(ics->forConditionStream);
|
||||
|
||||
if (ics->breakLabel != -1)
|
||||
setLabel(ics->breakLabel);
|
||||
@@ -313,6 +317,8 @@ void ICodeGenerator::endDoStatement()
|
||||
|
||||
// mark the start of the do conditional
|
||||
setLabel(ics->doCondition);
|
||||
if (ics->continueLabel != -1)
|
||||
setLabel(ics->continueLabel);
|
||||
|
||||
resetTopRegister();
|
||||
}
|
||||
@@ -358,7 +364,7 @@ void ICodeGenerator::endCaseCondition(Register expression)
|
||||
Register r = op(COMPARE, expression, ics->controlExpression);
|
||||
branchConditional(caseLabel, r);
|
||||
|
||||
setLabel(ics->its_iCode, caseLabel); // mark the case in the Case Statement stream
|
||||
setLabel(ics->caseStatementsStream, caseLabel); // mark the case in the Case Statement stream
|
||||
resetTopRegister();
|
||||
}
|
||||
|
||||
@@ -383,7 +389,7 @@ void ICodeGenerator::beginDefaultStatement()
|
||||
ASSERT(ics->stateKind == Switch_state);
|
||||
ASSERT(ics->defaultLabel == -1);
|
||||
ics->defaultLabel = getLabel();
|
||||
setLabel(ics->its_iCode, ics->defaultLabel);
|
||||
setLabel(ics->caseStatementsStream, ics->defaultLabel);
|
||||
iCode = ics->swapStream(iCode); // switch to Case Statement stream
|
||||
}
|
||||
|
||||
@@ -413,7 +419,7 @@ void ICodeGenerator::endSwitchStatement()
|
||||
}
|
||||
|
||||
// dump all the case statements into the main stream
|
||||
ics->mergeStream(iCode, labels);
|
||||
mergeStream(ics->caseStatementsStream);
|
||||
|
||||
if (ics->breakLabel != -1)
|
||||
setLabel(ics->breakLabel);
|
||||
@@ -469,15 +475,15 @@ void ICodeGenerator::endIfStatement()
|
||||
void ICodeGenerator::breakStatement()
|
||||
{
|
||||
for (std::vector<ICodeState *>::reverse_iterator p = stitcher.rbegin(); p != stitcher.rend(); p++) {
|
||||
|
||||
// this is NOT going to stay this way
|
||||
|
||||
if ((*p)->breakLabel != -1) {
|
||||
branch((*p)->breakLabel);
|
||||
return;
|
||||
}
|
||||
if (((*p)->stateKind == While_state)
|
||||
|| ((*p)->stateKind == Do_state)
|
||||
|| ((*p)->stateKind == For_state)
|
||||
|| ((*p)->stateKind == Switch_state)) {
|
||||
if ((*p)->breakLabel == -1)
|
||||
(*p)->breakLabel = getLabel();
|
||||
(*p)->breakLabel = getLabel();
|
||||
branch((*p)->breakLabel);
|
||||
return;
|
||||
}
|
||||
@@ -485,6 +491,24 @@ void ICodeGenerator::breakStatement()
|
||||
NOT_REACHED("no break target available");
|
||||
}
|
||||
|
||||
void ICodeGenerator::continueStatement()
|
||||
{
|
||||
for (std::vector<ICodeState *>::reverse_iterator p = stitcher.rbegin(); p != stitcher.rend(); p++) {
|
||||
if ((*p)->continueLabel != -1) {
|
||||
branch((*p)->continueLabel);
|
||||
return;
|
||||
}
|
||||
if (((*p)->stateKind == While_state)
|
||||
|| ((*p)->stateKind == Do_state)
|
||||
|| ((*p)->stateKind == For_state)) {
|
||||
(*p)->continueLabel = getLabel();
|
||||
branch((*p)->continueLabel);
|
||||
return;
|
||||
}
|
||||
}
|
||||
NOT_REACHED("no continue target available");
|
||||
}
|
||||
|
||||
/***********************************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -114,44 +114,43 @@ namespace JavaScript {
|
||||
class ICodeState {
|
||||
public :
|
||||
ICodeState(StateKind kind, ICodeGenerator *icg); // inline below
|
||||
virtual ~ICodeState() { }
|
||||
|
||||
virtual int32 getBreakLabel(ICodeGenerator *icg) { ASSERT(false); }
|
||||
virtual int32 getContinueLabel(ICodeGenerator *icg) { ASSERT(false); }
|
||||
|
||||
StateKind stateKind;
|
||||
int32 registerBase;
|
||||
int32 breakLabel;
|
||||
int32 continueLabel;
|
||||
int32 registerBase;
|
||||
};
|
||||
|
||||
// an ICodeState that handles switching to a new InstructionStream
|
||||
// and then re-combining the streams later
|
||||
class MultiPathICodeState : public ICodeState {
|
||||
class WhileCodeState : public ICodeState {
|
||||
public:
|
||||
MultiPathICodeState(StateKind kind, ICodeGenerator *icg); // inline below
|
||||
virtual ~MultiPathICodeState() { delete its_iCode; }
|
||||
WhileCodeState(int32 conditionLabel, int32 bodyLabel, ICodeGenerator *icg); // inline below
|
||||
InstructionStream *swapStream(InstructionStream *iCode) { InstructionStream *t = whileExpressionStream; whileExpressionStream = iCode; return t; }
|
||||
|
||||
InstructionStream *swapStream(InstructionStream *iCode) { InstructionStream *t = its_iCode; its_iCode = iCode; return t; }
|
||||
virtual int32 getBreakLabel(ICodeGenerator *icg) { if (breakLabel == -1) breakLabel = icg->getLabel(); return breakLabel; }
|
||||
virtual int32 getContinueLabel(ICodeGenerator *icg) { return whileCondition; }
|
||||
|
||||
InstructionStream *its_iCode;
|
||||
|
||||
static void mergeStream(InstructionStream *sideStream, InstructionStream *mainStream, LabelList &labels);
|
||||
|
||||
void mergeStream(InstructionStream *mainStream, LabelList &labels) { mergeStream(its_iCode, mainStream, labels); }
|
||||
};
|
||||
|
||||
class WhileCodeState : public MultiPathICodeState {
|
||||
public:
|
||||
WhileCodeState(int32 conditionLabel, int32 bodyLabel, ICodeGenerator *icg)
|
||||
: MultiPathICodeState(While_state, icg), whileCondition(conditionLabel), whileBody(bodyLabel) { }
|
||||
int32 whileCondition;
|
||||
int32 whileBody;
|
||||
InstructionStream *whileExpressionStream;
|
||||
};
|
||||
|
||||
class ForCodeState : public MultiPathICodeState {
|
||||
class ForCodeState : public ICodeState {
|
||||
public:
|
||||
ForCodeState(int32 conditionLabel, int32 bodyLabel, ICodeGenerator *icg); // inline below
|
||||
InstructionStream *swapStream2(InstructionStream *iCode) { InstructionStream *t = its_iCode_2; its_iCode_2 = iCode; return t; }
|
||||
void mergeStream2(InstructionStream *mainStream, LabelList &labels) { mergeStream(its_iCode_2, mainStream, labels); }
|
||||
InstructionStream *swapStream(InstructionStream *iCode) { InstructionStream *t = forConditionStream; forConditionStream = iCode; return t; }
|
||||
InstructionStream *swapStream2(InstructionStream *iCode) { InstructionStream *t = forIncrementStream; forIncrementStream = iCode; return t; }
|
||||
|
||||
virtual int32 getBreakLabel(ICodeGenerator *icg) { if (breakLabel == -1) breakLabel = icg->getLabel(); return breakLabel; }
|
||||
virtual int32 getContinueLabel(ICodeGenerator *icg) { if (continueLabel == -1) continueLabel = icg->getLabel(); return whileCondition; }
|
||||
|
||||
int32 forCondition;
|
||||
int32 forBody;
|
||||
InstructionStream *its_iCode_2;
|
||||
InstructionStream *forConditionStream;
|
||||
InstructionStream *forIncrementStream;
|
||||
};
|
||||
|
||||
class IfCodeState : public ICodeState {
|
||||
@@ -166,16 +165,23 @@ namespace JavaScript {
|
||||
public:
|
||||
DoCodeState(int32 bodyLabel, int32 conditionLabel, ICodeGenerator *icg)
|
||||
: ICodeState(Do_state, icg), doBody(bodyLabel), doCondition(conditionLabel) { }
|
||||
|
||||
virtual int32 getBreakLabel(ICodeGenerator *icg) { if (breakLabel == -1) breakLabel = icg->getLabel(); return breakLabel; }
|
||||
virtual int32 getContinueLabel(ICodeGenerator *icg) { return doCondition; }
|
||||
|
||||
int32 doBody;
|
||||
int32 doCondition;
|
||||
};
|
||||
|
||||
class SwitchCodeState : public MultiPathICodeState {
|
||||
class SwitchCodeState : public ICodeState {
|
||||
public:
|
||||
SwitchCodeState(Register control, ICodeGenerator *icg)
|
||||
: MultiPathICodeState(Switch_state, icg), controlExpression(control), defaultLabel(-1) { }
|
||||
SwitchCodeState(Register control, ICodeGenerator *icg); // inline below
|
||||
InstructionStream *swapStream(InstructionStream *iCode) { InstructionStream *t = caseStatementsStream; caseStatementsStream = iCode; return t; }
|
||||
|
||||
virtual int32 getBreakLabel(ICodeGenerator *icg) { if (breakLabel == -1) breakLabel = icg->getLabel(); return breakLabel; }
|
||||
|
||||
Register controlExpression;
|
||||
InstructionStream *caseStatementsStream;
|
||||
int32 defaultLabel;
|
||||
};
|
||||
|
||||
@@ -208,6 +214,8 @@ namespace JavaScript {
|
||||
public:
|
||||
ICodeGenerator() : topRegister(0) { iCode = new InstructionStream(); }
|
||||
|
||||
void mergeStream(InstructionStream *sideStream);
|
||||
|
||||
InstructionStream *complete();
|
||||
|
||||
ostream &print(ostream &s);
|
||||
@@ -300,10 +308,15 @@ namespace JavaScript {
|
||||
inline ICodeState::ICodeState(StateKind kind, ICodeGenerator *icg)
|
||||
: stateKind(kind), breakLabel(-1), continueLabel(-1), registerBase(icg->getRegisterBase()) { }
|
||||
|
||||
inline MultiPathICodeState::MultiPathICodeState(StateKind kind, ICodeGenerator *icg)
|
||||
: ICodeState(kind, icg), its_iCode(icg->get_iCode()) {}
|
||||
inline SwitchCodeState::SwitchCodeState(Register control, ICodeGenerator *icg)
|
||||
: ICodeState(Switch_state, icg), controlExpression(control), defaultLabel(-1), caseStatementsStream(icg->get_iCode()) {}
|
||||
|
||||
inline WhileCodeState::WhileCodeState(int32 conditionLabel, int32 bodyLabel, ICodeGenerator *icg)
|
||||
: ICodeState(While_state, icg), whileCondition(conditionLabel), whileBody(bodyLabel),
|
||||
whileExpressionStream(icg->get_iCode()) { }
|
||||
|
||||
inline ForCodeState::ForCodeState(int32 conditionLabel, int32 bodyLabel, ICodeGenerator *icg)
|
||||
: MultiPathICodeState(For_state, icg), forCondition(conditionLabel), forBody(bodyLabel), its_iCode_2(icg->get_iCode()) { }
|
||||
: ICodeState(For_state, icg), forCondition(conditionLabel), forBody(bodyLabel),
|
||||
forConditionStream(icg->get_iCode()), forIncrementStream(icg->get_iCode()) { }
|
||||
}
|
||||
#endif
|
||||
@@ -161,20 +161,20 @@ void ICodeGenerator::setLabel(InstructionStream *stream, int32 label)
|
||||
|
||||
/***********************************************************************************************/
|
||||
|
||||
void MultiPathICodeState::mergeStream(InstructionStream *sideStream, InstructionStream *mainStream, LabelList &labels)
|
||||
void ICodeGenerator::mergeStream(InstructionStream *sideStream)
|
||||
{
|
||||
// change InstructionStream to be a class that also remembers
|
||||
// if it contains any labels (maybe even remembers the labels
|
||||
// themselves?) in order to avoid running this loop unnecessarily.
|
||||
for (LabelList::iterator i = labels.begin(); i != labels.end(); i++) {
|
||||
if ((*i)->itsBase == sideStream) {
|
||||
(*i)->itsBase = mainStream;
|
||||
(*i)->itsOffset += mainStream->size();
|
||||
(*i)->itsBase = iCode;
|
||||
(*i)->itsOffset += iCode->size();
|
||||
}
|
||||
}
|
||||
|
||||
for (InstructionIterator ii = sideStream->begin(); ii != sideStream->end(); ii++)
|
||||
mainStream->push_back(*ii);
|
||||
iCode->push_back(*ii);
|
||||
|
||||
}
|
||||
|
||||
@@ -217,10 +217,11 @@ void ICodeGenerator::endWhileStatement()
|
||||
stitcher.pop_back();
|
||||
|
||||
// mark the start of the condition code
|
||||
// and re-attach it to the main stream
|
||||
setLabel(ics->whileCondition);
|
||||
setLabel(ics->whileCondition); // which is where continues will target
|
||||
|
||||
// and re-attach it to the main stream
|
||||
mergeStream(ics->whileExpressionStream);
|
||||
|
||||
ics->mergeStream(iCode, labels);
|
||||
if (ics->breakLabel != -1)
|
||||
setLabel(ics->breakLabel);
|
||||
|
||||
@@ -236,13 +237,12 @@ void ICodeGenerator::beginForStatement(const SourcePosition &pos)
|
||||
int32 forCondition = getLabel();
|
||||
|
||||
ForCodeState *ics = new ForCodeState(forCondition, getLabel(), this);
|
||||
ics->continueLabel = getLabel();
|
||||
|
||||
branch(forCondition);
|
||||
|
||||
stitcher.push_back(ics);
|
||||
|
||||
iCode = new InstructionStream(); // begin the stream for collecting the test expression
|
||||
iCode = new InstructionStream(); // begin the stream for collecting the condition expression
|
||||
setLabel(forCondition);
|
||||
|
||||
resetTopRegister();
|
||||
@@ -259,7 +259,10 @@ void ICodeGenerator::forCondition(Register condition)
|
||||
iCode = ics->swapStream(iCode); // switch back to main stream
|
||||
iCode = new InstructionStream(); // begin the stream for collecting the increment expression
|
||||
|
||||
setLabel(ics->continueLabel); // which is where continues will target
|
||||
ics->continueLabel = getLabel();
|
||||
setLabel(ics->continueLabel); // can't lazily insert this since we haven't seen the body yet
|
||||
// ??? could just remember the offset
|
||||
|
||||
resetTopRegister();
|
||||
}
|
||||
|
||||
@@ -279,9 +282,10 @@ void ICodeGenerator::endForStatement()
|
||||
{
|
||||
ForCodeState *ics = static_cast<ForCodeState *>(stitcher.back());
|
||||
ASSERT(ics->stateKind == For_state);
|
||||
stitcher.pop_back();
|
||||
|
||||
ics->mergeStream2(iCode, labels); // merges the increment sequence
|
||||
ics->mergeStream(iCode, labels); // merges the test sequence
|
||||
mergeStream(ics->forIncrementStream);
|
||||
mergeStream(ics->forConditionStream);
|
||||
|
||||
if (ics->breakLabel != -1)
|
||||
setLabel(ics->breakLabel);
|
||||
@@ -313,6 +317,8 @@ void ICodeGenerator::endDoStatement()
|
||||
|
||||
// mark the start of the do conditional
|
||||
setLabel(ics->doCondition);
|
||||
if (ics->continueLabel != -1)
|
||||
setLabel(ics->continueLabel);
|
||||
|
||||
resetTopRegister();
|
||||
}
|
||||
@@ -358,7 +364,7 @@ void ICodeGenerator::endCaseCondition(Register expression)
|
||||
Register r = op(COMPARE, expression, ics->controlExpression);
|
||||
branchConditional(caseLabel, r);
|
||||
|
||||
setLabel(ics->its_iCode, caseLabel); // mark the case in the Case Statement stream
|
||||
setLabel(ics->caseStatementsStream, caseLabel); // mark the case in the Case Statement stream
|
||||
resetTopRegister();
|
||||
}
|
||||
|
||||
@@ -383,7 +389,7 @@ void ICodeGenerator::beginDefaultStatement()
|
||||
ASSERT(ics->stateKind == Switch_state);
|
||||
ASSERT(ics->defaultLabel == -1);
|
||||
ics->defaultLabel = getLabel();
|
||||
setLabel(ics->its_iCode, ics->defaultLabel);
|
||||
setLabel(ics->caseStatementsStream, ics->defaultLabel);
|
||||
iCode = ics->swapStream(iCode); // switch to Case Statement stream
|
||||
}
|
||||
|
||||
@@ -413,7 +419,7 @@ void ICodeGenerator::endSwitchStatement()
|
||||
}
|
||||
|
||||
// dump all the case statements into the main stream
|
||||
ics->mergeStream(iCode, labels);
|
||||
mergeStream(ics->caseStatementsStream);
|
||||
|
||||
if (ics->breakLabel != -1)
|
||||
setLabel(ics->breakLabel);
|
||||
@@ -469,15 +475,15 @@ void ICodeGenerator::endIfStatement()
|
||||
void ICodeGenerator::breakStatement()
|
||||
{
|
||||
for (std::vector<ICodeState *>::reverse_iterator p = stitcher.rbegin(); p != stitcher.rend(); p++) {
|
||||
|
||||
// this is NOT going to stay this way
|
||||
|
||||
if ((*p)->breakLabel != -1) {
|
||||
branch((*p)->breakLabel);
|
||||
return;
|
||||
}
|
||||
if (((*p)->stateKind == While_state)
|
||||
|| ((*p)->stateKind == Do_state)
|
||||
|| ((*p)->stateKind == For_state)
|
||||
|| ((*p)->stateKind == Switch_state)) {
|
||||
if ((*p)->breakLabel == -1)
|
||||
(*p)->breakLabel = getLabel();
|
||||
(*p)->breakLabel = getLabel();
|
||||
branch((*p)->breakLabel);
|
||||
return;
|
||||
}
|
||||
@@ -485,6 +491,24 @@ void ICodeGenerator::breakStatement()
|
||||
NOT_REACHED("no break target available");
|
||||
}
|
||||
|
||||
void ICodeGenerator::continueStatement()
|
||||
{
|
||||
for (std::vector<ICodeState *>::reverse_iterator p = stitcher.rbegin(); p != stitcher.rend(); p++) {
|
||||
if ((*p)->continueLabel != -1) {
|
||||
branch((*p)->continueLabel);
|
||||
return;
|
||||
}
|
||||
if (((*p)->stateKind == While_state)
|
||||
|| ((*p)->stateKind == Do_state)
|
||||
|| ((*p)->stateKind == For_state)) {
|
||||
(*p)->continueLabel = getLabel();
|
||||
branch((*p)->continueLabel);
|
||||
return;
|
||||
}
|
||||
}
|
||||
NOT_REACHED("no continue target available");
|
||||
}
|
||||
|
||||
/***********************************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -114,44 +114,43 @@ namespace JavaScript {
|
||||
class ICodeState {
|
||||
public :
|
||||
ICodeState(StateKind kind, ICodeGenerator *icg); // inline below
|
||||
virtual ~ICodeState() { }
|
||||
|
||||
virtual int32 getBreakLabel(ICodeGenerator *icg) { ASSERT(false); }
|
||||
virtual int32 getContinueLabel(ICodeGenerator *icg) { ASSERT(false); }
|
||||
|
||||
StateKind stateKind;
|
||||
int32 registerBase;
|
||||
int32 breakLabel;
|
||||
int32 continueLabel;
|
||||
int32 registerBase;
|
||||
};
|
||||
|
||||
// an ICodeState that handles switching to a new InstructionStream
|
||||
// and then re-combining the streams later
|
||||
class MultiPathICodeState : public ICodeState {
|
||||
class WhileCodeState : public ICodeState {
|
||||
public:
|
||||
MultiPathICodeState(StateKind kind, ICodeGenerator *icg); // inline below
|
||||
virtual ~MultiPathICodeState() { delete its_iCode; }
|
||||
WhileCodeState(int32 conditionLabel, int32 bodyLabel, ICodeGenerator *icg); // inline below
|
||||
InstructionStream *swapStream(InstructionStream *iCode) { InstructionStream *t = whileExpressionStream; whileExpressionStream = iCode; return t; }
|
||||
|
||||
InstructionStream *swapStream(InstructionStream *iCode) { InstructionStream *t = its_iCode; its_iCode = iCode; return t; }
|
||||
virtual int32 getBreakLabel(ICodeGenerator *icg) { if (breakLabel == -1) breakLabel = icg->getLabel(); return breakLabel; }
|
||||
virtual int32 getContinueLabel(ICodeGenerator *icg) { return whileCondition; }
|
||||
|
||||
InstructionStream *its_iCode;
|
||||
|
||||
static void mergeStream(InstructionStream *sideStream, InstructionStream *mainStream, LabelList &labels);
|
||||
|
||||
void mergeStream(InstructionStream *mainStream, LabelList &labels) { mergeStream(its_iCode, mainStream, labels); }
|
||||
};
|
||||
|
||||
class WhileCodeState : public MultiPathICodeState {
|
||||
public:
|
||||
WhileCodeState(int32 conditionLabel, int32 bodyLabel, ICodeGenerator *icg)
|
||||
: MultiPathICodeState(While_state, icg), whileCondition(conditionLabel), whileBody(bodyLabel) { }
|
||||
int32 whileCondition;
|
||||
int32 whileBody;
|
||||
InstructionStream *whileExpressionStream;
|
||||
};
|
||||
|
||||
class ForCodeState : public MultiPathICodeState {
|
||||
class ForCodeState : public ICodeState {
|
||||
public:
|
||||
ForCodeState(int32 conditionLabel, int32 bodyLabel, ICodeGenerator *icg); // inline below
|
||||
InstructionStream *swapStream2(InstructionStream *iCode) { InstructionStream *t = its_iCode_2; its_iCode_2 = iCode; return t; }
|
||||
void mergeStream2(InstructionStream *mainStream, LabelList &labels) { mergeStream(its_iCode_2, mainStream, labels); }
|
||||
InstructionStream *swapStream(InstructionStream *iCode) { InstructionStream *t = forConditionStream; forConditionStream = iCode; return t; }
|
||||
InstructionStream *swapStream2(InstructionStream *iCode) { InstructionStream *t = forIncrementStream; forIncrementStream = iCode; return t; }
|
||||
|
||||
virtual int32 getBreakLabel(ICodeGenerator *icg) { if (breakLabel == -1) breakLabel = icg->getLabel(); return breakLabel; }
|
||||
virtual int32 getContinueLabel(ICodeGenerator *icg) { if (continueLabel == -1) continueLabel = icg->getLabel(); return whileCondition; }
|
||||
|
||||
int32 forCondition;
|
||||
int32 forBody;
|
||||
InstructionStream *its_iCode_2;
|
||||
InstructionStream *forConditionStream;
|
||||
InstructionStream *forIncrementStream;
|
||||
};
|
||||
|
||||
class IfCodeState : public ICodeState {
|
||||
@@ -166,16 +165,23 @@ namespace JavaScript {
|
||||
public:
|
||||
DoCodeState(int32 bodyLabel, int32 conditionLabel, ICodeGenerator *icg)
|
||||
: ICodeState(Do_state, icg), doBody(bodyLabel), doCondition(conditionLabel) { }
|
||||
|
||||
virtual int32 getBreakLabel(ICodeGenerator *icg) { if (breakLabel == -1) breakLabel = icg->getLabel(); return breakLabel; }
|
||||
virtual int32 getContinueLabel(ICodeGenerator *icg) { return doCondition; }
|
||||
|
||||
int32 doBody;
|
||||
int32 doCondition;
|
||||
};
|
||||
|
||||
class SwitchCodeState : public MultiPathICodeState {
|
||||
class SwitchCodeState : public ICodeState {
|
||||
public:
|
||||
SwitchCodeState(Register control, ICodeGenerator *icg)
|
||||
: MultiPathICodeState(Switch_state, icg), controlExpression(control), defaultLabel(-1) { }
|
||||
SwitchCodeState(Register control, ICodeGenerator *icg); // inline below
|
||||
InstructionStream *swapStream(InstructionStream *iCode) { InstructionStream *t = caseStatementsStream; caseStatementsStream = iCode; return t; }
|
||||
|
||||
virtual int32 getBreakLabel(ICodeGenerator *icg) { if (breakLabel == -1) breakLabel = icg->getLabel(); return breakLabel; }
|
||||
|
||||
Register controlExpression;
|
||||
InstructionStream *caseStatementsStream;
|
||||
int32 defaultLabel;
|
||||
};
|
||||
|
||||
@@ -208,6 +214,8 @@ namespace JavaScript {
|
||||
public:
|
||||
ICodeGenerator() : topRegister(0) { iCode = new InstructionStream(); }
|
||||
|
||||
void mergeStream(InstructionStream *sideStream);
|
||||
|
||||
InstructionStream *complete();
|
||||
|
||||
ostream &print(ostream &s);
|
||||
@@ -300,10 +308,15 @@ namespace JavaScript {
|
||||
inline ICodeState::ICodeState(StateKind kind, ICodeGenerator *icg)
|
||||
: stateKind(kind), breakLabel(-1), continueLabel(-1), registerBase(icg->getRegisterBase()) { }
|
||||
|
||||
inline MultiPathICodeState::MultiPathICodeState(StateKind kind, ICodeGenerator *icg)
|
||||
: ICodeState(kind, icg), its_iCode(icg->get_iCode()) {}
|
||||
inline SwitchCodeState::SwitchCodeState(Register control, ICodeGenerator *icg)
|
||||
: ICodeState(Switch_state, icg), controlExpression(control), defaultLabel(-1), caseStatementsStream(icg->get_iCode()) {}
|
||||
|
||||
inline WhileCodeState::WhileCodeState(int32 conditionLabel, int32 bodyLabel, ICodeGenerator *icg)
|
||||
: ICodeState(While_state, icg), whileCondition(conditionLabel), whileBody(bodyLabel),
|
||||
whileExpressionStream(icg->get_iCode()) { }
|
||||
|
||||
inline ForCodeState::ForCodeState(int32 conditionLabel, int32 bodyLabel, ICodeGenerator *icg)
|
||||
: MultiPathICodeState(For_state, icg), forCondition(conditionLabel), forBody(bodyLabel), its_iCode_2(icg->get_iCode()) { }
|
||||
: ICodeState(For_state, icg), forCondition(conditionLabel), forBody(bodyLabel),
|
||||
forConditionStream(icg->get_iCode()), forIncrementStream(icg->get_iCode()) { }
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user