зеркало из https://github.com/mozilla/gecko-dev.git
Changed compare/branch handling to determine last compare opcode.
Made returnStatement a member in ICG.
This commit is contained in:
Родитель
6c7e2e4df4
Коммит
7741726bd9
|
@ -58,14 +58,6 @@ namespace JavaScript {
|
|||
return iCode;
|
||||
}
|
||||
|
||||
InstructionStream *ICodeGenerator::complete(Register result)
|
||||
{
|
||||
Return *instr = new Return(RETURN, result);
|
||||
iCode->push_back(instr);
|
||||
return complete();
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************/
|
||||
|
||||
Register ICodeGenerator::loadVariable(uint32 frameIndex)
|
||||
|
@ -128,8 +120,13 @@ namespace JavaScript {
|
|||
iCode->push_back(instr);
|
||||
}
|
||||
|
||||
void ICodeGenerator::branchConditional(int32 label, Register condition, ICodeOp branchOp)
|
||||
void ICodeGenerator::branchConditional(int32 label, Register condition)
|
||||
{
|
||||
ICodeOp branchOp = getBranchOp();
|
||||
if (branchOp == NOP) {
|
||||
// XXXX emit convert to boolean / Test / ...
|
||||
branchOp = BRANCH_NE;
|
||||
}
|
||||
BranchCond *instr = new BranchCond(branchOp, label, condition);
|
||||
iCode->push_back(instr);
|
||||
}
|
||||
|
@ -188,8 +185,9 @@ namespace JavaScript {
|
|||
}
|
||||
}
|
||||
|
||||
for (InstructionIterator ii = sideStream->begin(); ii != sideStream->end(); ii++)
|
||||
for (InstructionIterator ii = sideStream->begin(); ii != sideStream->end(); ii++) {
|
||||
iCode->push_back(*ii);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -211,12 +209,12 @@ namespace JavaScript {
|
|||
iCode = new InstructionStream();
|
||||
}
|
||||
|
||||
void ICodeGenerator::endWhileExpression(Register condition, ICodeOp branchOp)
|
||||
void ICodeGenerator::endWhileExpression(Register condition)
|
||||
{
|
||||
WhileCodeState *ics = static_cast<WhileCodeState *>(stitcher.back());
|
||||
ASSERT(ics->stateKind == While_state);
|
||||
|
||||
branchConditional(ics->whileBody, condition, branchOp);
|
||||
branchConditional(ics->whileBody, condition);
|
||||
resetTopRegister();
|
||||
// stash away the condition expression and switch
|
||||
// back to the main stream
|
||||
|
@ -376,7 +374,7 @@ namespace JavaScript {
|
|||
ASSERT(ics->stateKind == Switch_state);
|
||||
|
||||
int32 caseLabel = getLabel();
|
||||
Register r = op(COMPARE, expression, ics->controlExpression);
|
||||
Register r = op(COMPARE_EQ, expression, ics->controlExpression);
|
||||
branchConditional(caseLabel, r);
|
||||
|
||||
setLabel(ics->caseStatementsStream, caseLabel); // mark the case in the Case Statement stream
|
||||
|
@ -524,10 +522,17 @@ namespace JavaScript {
|
|||
NOT_REACHED("no continue target available");
|
||||
}
|
||||
|
||||
void ICodeGenerator::returnStatement(Register result)
|
||||
{
|
||||
Return *instr = new Return(RETURN, result);
|
||||
iCode->push_back(instr);
|
||||
}
|
||||
|
||||
/***********************************************************************************************/
|
||||
|
||||
|
||||
char *opcodeName[] = {
|
||||
"nop",
|
||||
"move_to",
|
||||
"load_var",
|
||||
"save_var",
|
||||
|
@ -541,6 +546,11 @@ namespace JavaScript {
|
|||
"multiply",
|
||||
"divide",
|
||||
"compare",
|
||||
"compare",
|
||||
"compare",
|
||||
"compare",
|
||||
"compare",
|
||||
"compare",
|
||||
"not",
|
||||
"branch",
|
||||
"branch_lt",
|
||||
|
@ -563,13 +573,16 @@ namespace JavaScript {
|
|||
{
|
||||
s << "ICG! " << iCode->size() << "\n";
|
||||
for (InstructionIterator i = iCode->begin(); i != iCode->end(); i++) {
|
||||
|
||||
for (LabelList::iterator k = labels.begin(); k != labels.end(); k++)
|
||||
if ((*k)->itsOffset == (i - iCode->begin())) {
|
||||
s << "label #" << (k - labels.begin()) << ":\n";
|
||||
//s << "label #" << (k - labels.begin()) << ":\n";
|
||||
s << "#" << (i - iCode->begin());
|
||||
break;
|
||||
}
|
||||
|
||||
Instruction *instr = *i;
|
||||
s << "\t"<< std::setiosflags( std::ostream::left ) << std::setw(16) << opcodeName[instr->itsOp];
|
||||
s << "\t" << std::setiosflags( std::ostream::left ) << std::setw(16) << opcodeName[instr->itsOp];
|
||||
switch (instr->itsOp) {
|
||||
case LOAD_NAME :
|
||||
{
|
||||
|
@ -593,7 +606,7 @@ namespace JavaScript {
|
|||
case BRANCH :
|
||||
{
|
||||
Branch *t = static_cast<Branch * >(instr);
|
||||
s << "target #" << t->itsOperand1;
|
||||
s << "instr #" << t->itsOperand1;
|
||||
}
|
||||
break;
|
||||
case BRANCH_LT :
|
||||
|
@ -604,14 +617,19 @@ namespace JavaScript {
|
|||
case BRANCH_GT :
|
||||
{
|
||||
BranchCond *t = static_cast<BranchCond * >(instr);
|
||||
s << "target #" << t->itsOperand1 << ", R" << t->itsOperand2;
|
||||
s << "instr #" << t->itsOperand1 << ", R" << t->itsOperand2;
|
||||
}
|
||||
break;
|
||||
case ADD :
|
||||
case SUBTRACT :
|
||||
case MULTIPLY :
|
||||
case DIVIDE :
|
||||
case COMPARE :
|
||||
case COMPARE_LT :
|
||||
case COMPARE_LE :
|
||||
case COMPARE_EQ :
|
||||
case COMPARE_NE :
|
||||
case COMPARE_GT :
|
||||
case COMPARE_GE :
|
||||
{
|
||||
Arithmetic *t = static_cast<Arithmetic * >(instr);
|
||||
s << "R" << t->itsOperand1 << ", R" << t->itsOperand2 << ", R" << t->itsOperand3;
|
||||
|
@ -635,7 +653,8 @@ namespace JavaScript {
|
|||
}
|
||||
for (LabelList::iterator k = labels.begin(); k != labels.end(); k++)
|
||||
if ((*k)->itsOffset == (iCode->end() - iCode->begin())) {
|
||||
s << "label #" << (k - labels.begin()) << ":\n";
|
||||
// s << "label #" << (k - labels.begin()) << ":\n";
|
||||
s << "#" << (i - iCode->begin());
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ namespace JavaScript {
|
|||
|
||||
enum ICodeOp {
|
||||
// Operand1 Operand2 Operand3
|
||||
NOP,
|
||||
|
||||
MOVE_TO, // Source Register Destination Register
|
||||
|
||||
|
@ -52,7 +53,14 @@ namespace JavaScript {
|
|||
MULTIPLY,
|
||||
DIVIDE,
|
||||
|
||||
COMPARE, // Source Register 1 Source Register 2 Destination Register
|
||||
// maintain contiguity
|
||||
COMPARE_LT, // Source Register 1 Source Register 2 Destination Register
|
||||
COMPARE_LE,
|
||||
COMPARE_EQ,
|
||||
COMPARE_NE,
|
||||
COMPARE_GE,
|
||||
COMPARE_GT,
|
||||
|
||||
NOT, // Source Register Destination Register
|
||||
|
||||
BRANCH, // Target label
|
||||
|
@ -72,7 +80,8 @@ namespace JavaScript {
|
|||
Instruction(ICodeOp op) : itsOp(op) { }
|
||||
ICodeOp itsOp;
|
||||
|
||||
ICodeOp opcode() { return itsOp; }
|
||||
ICodeOp getBranchOp() { return ((itsOp >= COMPARE_LT) && (itsOp <= COMPARE_GT)) ? (ICodeOp)(BRANCH_LT + (itsOp - COMPARE_LT)) : NOP; }
|
||||
ICodeOp opcode() { return itsOp; }
|
||||
};
|
||||
|
||||
template <typename Operand1>
|
||||
|
@ -119,6 +128,7 @@ namespace JavaScript {
|
|||
typedef Instruction_1<int32> Branch;
|
||||
typedef Instruction_2<int32, Register> BranchCond;
|
||||
typedef Instruction_3<Register, Register, Register> Arithmetic;
|
||||
typedef Instruction_3<Register, Register, Register> Compare;
|
||||
typedef Instruction_2<Register, Register> Move;
|
||||
typedef Instruction_1<Register> Return;
|
||||
|
||||
|
@ -167,9 +177,8 @@ namespace JavaScript {
|
|||
|
||||
class ICodeGenerator {
|
||||
private:
|
||||
|
||||
InstructionStream *iCode;
|
||||
|
||||
|
||||
LabelList labels;
|
||||
|
||||
std::vector<ICodeState *> stitcher;
|
||||
|
@ -178,6 +187,8 @@ namespace JavaScript {
|
|||
Register getRegister() { return topRegister++; }
|
||||
void resetTopRegister() { topRegister = stitcher.empty() ? 0 : stitcher.back()->registerBase; }
|
||||
|
||||
ICodeOp getBranchOp() { ASSERT(!iCode->empty()); return iCode->back()->getBranchOp(); }
|
||||
|
||||
public:
|
||||
int32 getLabel();
|
||||
private:
|
||||
|
@ -185,7 +196,7 @@ namespace JavaScript {
|
|||
void setLabel(InstructionStream *stream, int32 label);
|
||||
|
||||
void branch(int32 label);
|
||||
void branchConditional(int32 label, Register condition, ICodeOp branchOp = BRANCH_NE);
|
||||
void branchConditional(int32 label, Register condition);
|
||||
|
||||
public:
|
||||
ICodeGenerator() : topRegister(0) { iCode = new InstructionStream(); }
|
||||
|
@ -193,13 +204,14 @@ namespace JavaScript {
|
|||
void mergeStream(InstructionStream *sideStream);
|
||||
|
||||
InstructionStream *complete();
|
||||
InstructionStream *complete(Register result);
|
||||
|
||||
ostream &print(ostream &s);
|
||||
|
||||
Register op(ICodeOp op, Register source);
|
||||
Register op(ICodeOp op, Register source1, Register source2);
|
||||
|
||||
Register compare(ICodeOp op, Register source1, Register source2);
|
||||
|
||||
Register loadVariable(uint32 frameIndex);
|
||||
Register loadImmediate(double value);
|
||||
|
||||
|
@ -222,9 +234,10 @@ namespace JavaScript {
|
|||
// expression statements
|
||||
void beginStatement(uint32 /*pos*/) { resetTopRegister(); }
|
||||
|
||||
|
||||
void returnStatement(Register result);
|
||||
|
||||
void beginWhileStatement(uint32 pos);
|
||||
void endWhileExpression(Register condition, ICodeOp branchOp = BRANCH_NE);
|
||||
void endWhileExpression(Register condition);
|
||||
void endWhileStatement();
|
||||
|
||||
|
||||
|
@ -270,10 +283,6 @@ namespace JavaScript {
|
|||
|
||||
void throwStatement(Register expression);
|
||||
|
||||
|
||||
void returnStatement(Register expression); // optional <operand>
|
||||
|
||||
|
||||
void beginCatchStatement();
|
||||
void endCatchExpression(Register expression);
|
||||
void endCatchStatement();
|
||||
|
|
|
@ -45,7 +45,7 @@ JSValue interpret(InstructionStream& iCode, const JSValues& args)
|
|||
registers[op2(i)] = registers[op1(i)];
|
||||
}
|
||||
break;
|
||||
case LOAD_NAME:
|
||||
case LOAD_NAME:
|
||||
{
|
||||
LoadName* i = static_cast<LoadName*>(instruction);
|
||||
registers[op2(i)] = globals[*op1(i)];
|
||||
|
@ -164,7 +164,12 @@ JSValue interpret(InstructionStream& iCode, const JSValues& args)
|
|||
registers[op3(i)] = JSValue(registers[op1(i)].f64 / registers[op2(i)].f64);
|
||||
}
|
||||
break;
|
||||
case COMPARE:
|
||||
case COMPARE_LT:
|
||||
case COMPARE_LE:
|
||||
case COMPARE_EQ:
|
||||
case COMPARE_NE:
|
||||
case COMPARE_GT:
|
||||
case COMPARE_GE:
|
||||
{
|
||||
Arithmetic* i = static_cast<Arithmetic*>(instruction);
|
||||
float64 diff = (registers[op1(i)].f64 - registers[op2(i)].f64);
|
||||
|
|
|
@ -438,8 +438,8 @@ static void testInterpreter(float64 n)
|
|||
icg.beginWhileStatement(position);
|
||||
Register r0 = icg.loadVariable(0);
|
||||
Register r1 = icg.loadImmediate(1.0);
|
||||
Register r2 = icg.op(COMPARE, r0, r1);
|
||||
icg.endWhileExpression(r2, BRANCH_GT);
|
||||
Register r2 = icg.op(COMPARE_GT, r0, r1);
|
||||
icg.endWhileExpression(r2);
|
||||
r0 = icg.loadVariable(0);
|
||||
r1 = icg.loadVariable(1);
|
||||
r2 = icg.op(MULTIPLY, r1, r0);
|
||||
|
@ -453,8 +453,8 @@ static void testInterpreter(float64 n)
|
|||
}
|
||||
|
||||
// return result;
|
||||
icg.beginStatement(position);
|
||||
InstructionStream *iCode = icg.complete(icg.loadVariable(1));
|
||||
icg.returnStatement(icg.loadVariable(1));
|
||||
InstructionStream *iCode = icg.complete();
|
||||
// std::cout << icg;
|
||||
|
||||
// test the iCode interpreter.
|
||||
|
|
|
@ -58,14 +58,6 @@ namespace JavaScript {
|
|||
return iCode;
|
||||
}
|
||||
|
||||
InstructionStream *ICodeGenerator::complete(Register result)
|
||||
{
|
||||
Return *instr = new Return(RETURN, result);
|
||||
iCode->push_back(instr);
|
||||
return complete();
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************/
|
||||
|
||||
Register ICodeGenerator::loadVariable(uint32 frameIndex)
|
||||
|
@ -128,8 +120,13 @@ namespace JavaScript {
|
|||
iCode->push_back(instr);
|
||||
}
|
||||
|
||||
void ICodeGenerator::branchConditional(int32 label, Register condition, ICodeOp branchOp)
|
||||
void ICodeGenerator::branchConditional(int32 label, Register condition)
|
||||
{
|
||||
ICodeOp branchOp = getBranchOp();
|
||||
if (branchOp == NOP) {
|
||||
// XXXX emit convert to boolean / Test / ...
|
||||
branchOp = BRANCH_NE;
|
||||
}
|
||||
BranchCond *instr = new BranchCond(branchOp, label, condition);
|
||||
iCode->push_back(instr);
|
||||
}
|
||||
|
@ -188,8 +185,9 @@ namespace JavaScript {
|
|||
}
|
||||
}
|
||||
|
||||
for (InstructionIterator ii = sideStream->begin(); ii != sideStream->end(); ii++)
|
||||
for (InstructionIterator ii = sideStream->begin(); ii != sideStream->end(); ii++) {
|
||||
iCode->push_back(*ii);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -211,12 +209,12 @@ namespace JavaScript {
|
|||
iCode = new InstructionStream();
|
||||
}
|
||||
|
||||
void ICodeGenerator::endWhileExpression(Register condition, ICodeOp branchOp)
|
||||
void ICodeGenerator::endWhileExpression(Register condition)
|
||||
{
|
||||
WhileCodeState *ics = static_cast<WhileCodeState *>(stitcher.back());
|
||||
ASSERT(ics->stateKind == While_state);
|
||||
|
||||
branchConditional(ics->whileBody, condition, branchOp);
|
||||
branchConditional(ics->whileBody, condition);
|
||||
resetTopRegister();
|
||||
// stash away the condition expression and switch
|
||||
// back to the main stream
|
||||
|
@ -376,7 +374,7 @@ namespace JavaScript {
|
|||
ASSERT(ics->stateKind == Switch_state);
|
||||
|
||||
int32 caseLabel = getLabel();
|
||||
Register r = op(COMPARE, expression, ics->controlExpression);
|
||||
Register r = op(COMPARE_EQ, expression, ics->controlExpression);
|
||||
branchConditional(caseLabel, r);
|
||||
|
||||
setLabel(ics->caseStatementsStream, caseLabel); // mark the case in the Case Statement stream
|
||||
|
@ -524,10 +522,17 @@ namespace JavaScript {
|
|||
NOT_REACHED("no continue target available");
|
||||
}
|
||||
|
||||
void ICodeGenerator::returnStatement(Register result)
|
||||
{
|
||||
Return *instr = new Return(RETURN, result);
|
||||
iCode->push_back(instr);
|
||||
}
|
||||
|
||||
/***********************************************************************************************/
|
||||
|
||||
|
||||
char *opcodeName[] = {
|
||||
"nop",
|
||||
"move_to",
|
||||
"load_var",
|
||||
"save_var",
|
||||
|
@ -541,6 +546,11 @@ namespace JavaScript {
|
|||
"multiply",
|
||||
"divide",
|
||||
"compare",
|
||||
"compare",
|
||||
"compare",
|
||||
"compare",
|
||||
"compare",
|
||||
"compare",
|
||||
"not",
|
||||
"branch",
|
||||
"branch_lt",
|
||||
|
@ -563,13 +573,16 @@ namespace JavaScript {
|
|||
{
|
||||
s << "ICG! " << iCode->size() << "\n";
|
||||
for (InstructionIterator i = iCode->begin(); i != iCode->end(); i++) {
|
||||
|
||||
for (LabelList::iterator k = labels.begin(); k != labels.end(); k++)
|
||||
if ((*k)->itsOffset == (i - iCode->begin())) {
|
||||
s << "label #" << (k - labels.begin()) << ":\n";
|
||||
//s << "label #" << (k - labels.begin()) << ":\n";
|
||||
s << "#" << (i - iCode->begin());
|
||||
break;
|
||||
}
|
||||
|
||||
Instruction *instr = *i;
|
||||
s << "\t"<< std::setiosflags( std::ostream::left ) << std::setw(16) << opcodeName[instr->itsOp];
|
||||
s << "\t" << std::setiosflags( std::ostream::left ) << std::setw(16) << opcodeName[instr->itsOp];
|
||||
switch (instr->itsOp) {
|
||||
case LOAD_NAME :
|
||||
{
|
||||
|
@ -593,7 +606,7 @@ namespace JavaScript {
|
|||
case BRANCH :
|
||||
{
|
||||
Branch *t = static_cast<Branch * >(instr);
|
||||
s << "target #" << t->itsOperand1;
|
||||
s << "instr #" << t->itsOperand1;
|
||||
}
|
||||
break;
|
||||
case BRANCH_LT :
|
||||
|
@ -604,14 +617,19 @@ namespace JavaScript {
|
|||
case BRANCH_GT :
|
||||
{
|
||||
BranchCond *t = static_cast<BranchCond * >(instr);
|
||||
s << "target #" << t->itsOperand1 << ", R" << t->itsOperand2;
|
||||
s << "instr #" << t->itsOperand1 << ", R" << t->itsOperand2;
|
||||
}
|
||||
break;
|
||||
case ADD :
|
||||
case SUBTRACT :
|
||||
case MULTIPLY :
|
||||
case DIVIDE :
|
||||
case COMPARE :
|
||||
case COMPARE_LT :
|
||||
case COMPARE_LE :
|
||||
case COMPARE_EQ :
|
||||
case COMPARE_NE :
|
||||
case COMPARE_GT :
|
||||
case COMPARE_GE :
|
||||
{
|
||||
Arithmetic *t = static_cast<Arithmetic * >(instr);
|
||||
s << "R" << t->itsOperand1 << ", R" << t->itsOperand2 << ", R" << t->itsOperand3;
|
||||
|
@ -635,7 +653,8 @@ namespace JavaScript {
|
|||
}
|
||||
for (LabelList::iterator k = labels.begin(); k != labels.end(); k++)
|
||||
if ((*k)->itsOffset == (iCode->end() - iCode->begin())) {
|
||||
s << "label #" << (k - labels.begin()) << ":\n";
|
||||
// s << "label #" << (k - labels.begin()) << ":\n";
|
||||
s << "#" << (i - iCode->begin());
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ namespace JavaScript {
|
|||
|
||||
enum ICodeOp {
|
||||
// Operand1 Operand2 Operand3
|
||||
NOP,
|
||||
|
||||
MOVE_TO, // Source Register Destination Register
|
||||
|
||||
|
@ -52,7 +53,14 @@ namespace JavaScript {
|
|||
MULTIPLY,
|
||||
DIVIDE,
|
||||
|
||||
COMPARE, // Source Register 1 Source Register 2 Destination Register
|
||||
// maintain contiguity
|
||||
COMPARE_LT, // Source Register 1 Source Register 2 Destination Register
|
||||
COMPARE_LE,
|
||||
COMPARE_EQ,
|
||||
COMPARE_NE,
|
||||
COMPARE_GE,
|
||||
COMPARE_GT,
|
||||
|
||||
NOT, // Source Register Destination Register
|
||||
|
||||
BRANCH, // Target label
|
||||
|
@ -72,7 +80,8 @@ namespace JavaScript {
|
|||
Instruction(ICodeOp op) : itsOp(op) { }
|
||||
ICodeOp itsOp;
|
||||
|
||||
ICodeOp opcode() { return itsOp; }
|
||||
ICodeOp getBranchOp() { return ((itsOp >= COMPARE_LT) && (itsOp <= COMPARE_GT)) ? (ICodeOp)(BRANCH_LT + (itsOp - COMPARE_LT)) : NOP; }
|
||||
ICodeOp opcode() { return itsOp; }
|
||||
};
|
||||
|
||||
template <typename Operand1>
|
||||
|
@ -119,6 +128,7 @@ namespace JavaScript {
|
|||
typedef Instruction_1<int32> Branch;
|
||||
typedef Instruction_2<int32, Register> BranchCond;
|
||||
typedef Instruction_3<Register, Register, Register> Arithmetic;
|
||||
typedef Instruction_3<Register, Register, Register> Compare;
|
||||
typedef Instruction_2<Register, Register> Move;
|
||||
typedef Instruction_1<Register> Return;
|
||||
|
||||
|
@ -167,9 +177,8 @@ namespace JavaScript {
|
|||
|
||||
class ICodeGenerator {
|
||||
private:
|
||||
|
||||
InstructionStream *iCode;
|
||||
|
||||
|
||||
LabelList labels;
|
||||
|
||||
std::vector<ICodeState *> stitcher;
|
||||
|
@ -178,6 +187,8 @@ namespace JavaScript {
|
|||
Register getRegister() { return topRegister++; }
|
||||
void resetTopRegister() { topRegister = stitcher.empty() ? 0 : stitcher.back()->registerBase; }
|
||||
|
||||
ICodeOp getBranchOp() { ASSERT(!iCode->empty()); return iCode->back()->getBranchOp(); }
|
||||
|
||||
public:
|
||||
int32 getLabel();
|
||||
private:
|
||||
|
@ -185,7 +196,7 @@ namespace JavaScript {
|
|||
void setLabel(InstructionStream *stream, int32 label);
|
||||
|
||||
void branch(int32 label);
|
||||
void branchConditional(int32 label, Register condition, ICodeOp branchOp = BRANCH_NE);
|
||||
void branchConditional(int32 label, Register condition);
|
||||
|
||||
public:
|
||||
ICodeGenerator() : topRegister(0) { iCode = new InstructionStream(); }
|
||||
|
@ -193,13 +204,14 @@ namespace JavaScript {
|
|||
void mergeStream(InstructionStream *sideStream);
|
||||
|
||||
InstructionStream *complete();
|
||||
InstructionStream *complete(Register result);
|
||||
|
||||
ostream &print(ostream &s);
|
||||
|
||||
Register op(ICodeOp op, Register source);
|
||||
Register op(ICodeOp op, Register source1, Register source2);
|
||||
|
||||
Register compare(ICodeOp op, Register source1, Register source2);
|
||||
|
||||
Register loadVariable(uint32 frameIndex);
|
||||
Register loadImmediate(double value);
|
||||
|
||||
|
@ -222,9 +234,10 @@ namespace JavaScript {
|
|||
// expression statements
|
||||
void beginStatement(uint32 /*pos*/) { resetTopRegister(); }
|
||||
|
||||
|
||||
void returnStatement(Register result);
|
||||
|
||||
void beginWhileStatement(uint32 pos);
|
||||
void endWhileExpression(Register condition, ICodeOp branchOp = BRANCH_NE);
|
||||
void endWhileExpression(Register condition);
|
||||
void endWhileStatement();
|
||||
|
||||
|
||||
|
@ -270,10 +283,6 @@ namespace JavaScript {
|
|||
|
||||
void throwStatement(Register expression);
|
||||
|
||||
|
||||
void returnStatement(Register expression); // optional <operand>
|
||||
|
||||
|
||||
void beginCatchStatement();
|
||||
void endCatchExpression(Register expression);
|
||||
void endCatchStatement();
|
||||
|
|
|
@ -45,7 +45,7 @@ JSValue interpret(InstructionStream& iCode, const JSValues& args)
|
|||
registers[op2(i)] = registers[op1(i)];
|
||||
}
|
||||
break;
|
||||
case LOAD_NAME:
|
||||
case LOAD_NAME:
|
||||
{
|
||||
LoadName* i = static_cast<LoadName*>(instruction);
|
||||
registers[op2(i)] = globals[*op1(i)];
|
||||
|
@ -164,7 +164,12 @@ JSValue interpret(InstructionStream& iCode, const JSValues& args)
|
|||
registers[op3(i)] = JSValue(registers[op1(i)].f64 / registers[op2(i)].f64);
|
||||
}
|
||||
break;
|
||||
case COMPARE:
|
||||
case COMPARE_LT:
|
||||
case COMPARE_LE:
|
||||
case COMPARE_EQ:
|
||||
case COMPARE_NE:
|
||||
case COMPARE_GT:
|
||||
case COMPARE_GE:
|
||||
{
|
||||
Arithmetic* i = static_cast<Arithmetic*>(instruction);
|
||||
float64 diff = (registers[op1(i)].f64 - registers[op2(i)].f64);
|
||||
|
|
|
@ -438,8 +438,8 @@ static void testInterpreter(float64 n)
|
|||
icg.beginWhileStatement(position);
|
||||
Register r0 = icg.loadVariable(0);
|
||||
Register r1 = icg.loadImmediate(1.0);
|
||||
Register r2 = icg.op(COMPARE, r0, r1);
|
||||
icg.endWhileExpression(r2, BRANCH_GT);
|
||||
Register r2 = icg.op(COMPARE_GT, r0, r1);
|
||||
icg.endWhileExpression(r2);
|
||||
r0 = icg.loadVariable(0);
|
||||
r1 = icg.loadVariable(1);
|
||||
r2 = icg.op(MULTIPLY, r1, r0);
|
||||
|
@ -453,8 +453,8 @@ static void testInterpreter(float64 n)
|
|||
}
|
||||
|
||||
// return result;
|
||||
icg.beginStatement(position);
|
||||
InstructionStream *iCode = icg.complete(icg.loadVariable(1));
|
||||
icg.returnStatement(icg.loadVariable(1));
|
||||
InstructionStream *iCode = icg.complete();
|
||||
// std::cout << icg;
|
||||
|
||||
// test the iCode interpreter.
|
||||
|
|
Загрузка…
Ссылка в новой задаче