more arithmetic, conditional branches, return instruction.

This commit is contained in:
beard%netscape.com 2000-04-06 02:58:22 +00:00
Родитель a57994c317
Коммит 602bdc5282
2 изменённых файлов: 184 добавлений и 24 удалений

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

@ -35,9 +35,16 @@ JSValue interpret(InstructionStream& iCode, const JSValues& args)
JSValues registers(32); JSValues registers(32);
static std::map<String, JSValue> globals; static std::map<String, JSValue> globals;
for (InstructionIterator pc = iCode.begin(); pc != iCode.end(); ++pc) { InstructionIterator pc = iCode.begin();
while (pc != iCode.end()) {
Instruction* instruction = *pc; Instruction* instruction = *pc;
switch (instruction->opcode()) { switch (instruction->opcode()) {
case MOVE_TO:
{
Move* i = static_cast<Move*>(instruction);
registers[op2(i)] = registers[op1(i)];
}
break;
case LOAD_NAME: case LOAD_NAME:
{ {
LoadName* i = static_cast<LoadName*>(instruction); LoadName* i = static_cast<LoadName*>(instruction);
@ -72,14 +79,61 @@ JSValue interpret(InstructionStream& iCode, const JSValues& args)
{ {
Branch* i = static_cast<Branch*>(instruction); Branch* i = static_cast<Branch*>(instruction);
pc = iCode.begin() + op1(i); pc = iCode.begin() + op1(i);
continue;
} }
break; break;
case BRANCH_COND: case BRANCH_LT:
{ {
BranchCond* i = static_cast<BranchCond*>(instruction); BranchCond* i = static_cast<BranchCond*>(instruction);
// s << "target #" << t->itsOperand1 << ", R" << t->itsOperand2; if (registers[op2(i)].i32 < 0) {
if (registers[op2(i)].i32)
pc = iCode.begin() + op1(i); pc = iCode.begin() + op1(i);
continue;
}
}
break;
case BRANCH_LE:
{
BranchCond* i = static_cast<BranchCond*>(instruction);
if (registers[op2(i)].i32 <= 0) {
pc = iCode.begin() + op1(i);
continue;
}
}
break;
case BRANCH_EQ:
{
BranchCond* i = static_cast<BranchCond*>(instruction);
if (registers[op2(i)].i32 == 0) {
pc = iCode.begin() + op1(i);
continue;
}
}
break;
case BRANCH_NE:
{
BranchCond* i = static_cast<BranchCond*>(instruction);
if (registers[op2(i)].i32 != 0) {
pc = iCode.begin() + op1(i);
continue;
}
}
break;
case BRANCH_GE:
{
BranchCond* i = static_cast<BranchCond*>(instruction);
if (registers[op2(i)].i32 >= 0) {
pc = iCode.begin() + op1(i);
continue;
}
}
break;
case BRANCH_GT:
{
BranchCond* i = static_cast<BranchCond*>(instruction);
if (registers[op2(i)].i32 > 0) {
pc = iCode.begin() + op1(i);
continue;
}
} }
break; break;
case ADD: case ADD:
@ -89,16 +143,32 @@ JSValue interpret(InstructionStream& iCode, const JSValues& args)
registers[op3(i)] = JSValue(registers[op1(i)].f64 + registers[op2(i)].f64); registers[op3(i)] = JSValue(registers[op1(i)].f64 + registers[op2(i)].f64);
} }
break; break;
case SUBTRACT:
{
// could get clever here with Functional forms.
Arithmetic* i = static_cast<Arithmetic*>(instruction);
registers[op3(i)] = JSValue(registers[op1(i)].f64 - registers[op2(i)].f64);
}
break;
case MULTIPLY:
{
// could get clever here with Functional forms.
Arithmetic* i = static_cast<Arithmetic*>(instruction);
registers[op3(i)] = JSValue(registers[op1(i)].f64 * registers[op2(i)].f64);
}
break;
case DIVIDE:
{
// could get clever here with Functional forms.
Arithmetic* i = static_cast<Arithmetic*>(instruction);
registers[op3(i)] = JSValue(registers[op1(i)].f64 / registers[op2(i)].f64);
}
break;
case COMPARE: case COMPARE:
{ {
Arithmetic* i = static_cast<Arithmetic*>(instruction); Arithmetic* i = static_cast<Arithmetic*>(instruction);
registers[op3(i)].i32 = registers[op1(i)].f64 == registers[op2(i)].f64; float64 diff = (registers[op1(i)].f64 - registers[op2(i)].f64);
} registers[op3(i)].i32 = (diff == 0.0 ? 0 : (diff > 0.0 ? 1 : -1));
break;
case MOVE_TO:
{
Move* i = static_cast<Move*>(instruction);
registers[op2(i)] = registers[op1(i)];
} }
break; break;
case NOT: case NOT:
@ -107,9 +177,19 @@ JSValue interpret(InstructionStream& iCode, const JSValues& args)
registers[op2(i)].i32 = !registers[op1(i)].i32; registers[op2(i)].i32 = !registers[op1(i)].i32;
} }
break; break;
case RETURN:
{
Return* i = static_cast<Return*>(instruction);
result = registers[op1(i)];
pc = iCode.end();
continue;
}
default: default:
break; break;
} }
// increment the program counter.
++pc;
} }
return result; return result;

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

@ -35,9 +35,16 @@ JSValue interpret(InstructionStream& iCode, const JSValues& args)
JSValues registers(32); JSValues registers(32);
static std::map<String, JSValue> globals; static std::map<String, JSValue> globals;
for (InstructionIterator pc = iCode.begin(); pc != iCode.end(); ++pc) { InstructionIterator pc = iCode.begin();
while (pc != iCode.end()) {
Instruction* instruction = *pc; Instruction* instruction = *pc;
switch (instruction->opcode()) { switch (instruction->opcode()) {
case MOVE_TO:
{
Move* i = static_cast<Move*>(instruction);
registers[op2(i)] = registers[op1(i)];
}
break;
case LOAD_NAME: case LOAD_NAME:
{ {
LoadName* i = static_cast<LoadName*>(instruction); LoadName* i = static_cast<LoadName*>(instruction);
@ -72,14 +79,61 @@ JSValue interpret(InstructionStream& iCode, const JSValues& args)
{ {
Branch* i = static_cast<Branch*>(instruction); Branch* i = static_cast<Branch*>(instruction);
pc = iCode.begin() + op1(i); pc = iCode.begin() + op1(i);
continue;
} }
break; break;
case BRANCH_COND: case BRANCH_LT:
{ {
BranchCond* i = static_cast<BranchCond*>(instruction); BranchCond* i = static_cast<BranchCond*>(instruction);
// s << "target #" << t->itsOperand1 << ", R" << t->itsOperand2; if (registers[op2(i)].i32 < 0) {
if (registers[op2(i)].i32)
pc = iCode.begin() + op1(i); pc = iCode.begin() + op1(i);
continue;
}
}
break;
case BRANCH_LE:
{
BranchCond* i = static_cast<BranchCond*>(instruction);
if (registers[op2(i)].i32 <= 0) {
pc = iCode.begin() + op1(i);
continue;
}
}
break;
case BRANCH_EQ:
{
BranchCond* i = static_cast<BranchCond*>(instruction);
if (registers[op2(i)].i32 == 0) {
pc = iCode.begin() + op1(i);
continue;
}
}
break;
case BRANCH_NE:
{
BranchCond* i = static_cast<BranchCond*>(instruction);
if (registers[op2(i)].i32 != 0) {
pc = iCode.begin() + op1(i);
continue;
}
}
break;
case BRANCH_GE:
{
BranchCond* i = static_cast<BranchCond*>(instruction);
if (registers[op2(i)].i32 >= 0) {
pc = iCode.begin() + op1(i);
continue;
}
}
break;
case BRANCH_GT:
{
BranchCond* i = static_cast<BranchCond*>(instruction);
if (registers[op2(i)].i32 > 0) {
pc = iCode.begin() + op1(i);
continue;
}
} }
break; break;
case ADD: case ADD:
@ -89,16 +143,32 @@ JSValue interpret(InstructionStream& iCode, const JSValues& args)
registers[op3(i)] = JSValue(registers[op1(i)].f64 + registers[op2(i)].f64); registers[op3(i)] = JSValue(registers[op1(i)].f64 + registers[op2(i)].f64);
} }
break; break;
case SUBTRACT:
{
// could get clever here with Functional forms.
Arithmetic* i = static_cast<Arithmetic*>(instruction);
registers[op3(i)] = JSValue(registers[op1(i)].f64 - registers[op2(i)].f64);
}
break;
case MULTIPLY:
{
// could get clever here with Functional forms.
Arithmetic* i = static_cast<Arithmetic*>(instruction);
registers[op3(i)] = JSValue(registers[op1(i)].f64 * registers[op2(i)].f64);
}
break;
case DIVIDE:
{
// could get clever here with Functional forms.
Arithmetic* i = static_cast<Arithmetic*>(instruction);
registers[op3(i)] = JSValue(registers[op1(i)].f64 / registers[op2(i)].f64);
}
break;
case COMPARE: case COMPARE:
{ {
Arithmetic* i = static_cast<Arithmetic*>(instruction); Arithmetic* i = static_cast<Arithmetic*>(instruction);
registers[op3(i)].i32 = registers[op1(i)].f64 == registers[op2(i)].f64; float64 diff = (registers[op1(i)].f64 - registers[op2(i)].f64);
} registers[op3(i)].i32 = (diff == 0.0 ? 0 : (diff > 0.0 ? 1 : -1));
break;
case MOVE_TO:
{
Move* i = static_cast<Move*>(instruction);
registers[op2(i)] = registers[op1(i)];
} }
break; break;
case NOT: case NOT:
@ -107,9 +177,19 @@ JSValue interpret(InstructionStream& iCode, const JSValues& args)
registers[op2(i)].i32 = !registers[op1(i)].i32; registers[op2(i)].i32 = !registers[op1(i)].i32;
} }
break; break;
case RETURN:
{
Return* i = static_cast<Return*>(instruction);
result = registers[op1(i)];
pc = iCode.end();
continue;
}
default: default:
break; break;
} }
// increment the program counter.
++pc;
} }
return result; return result;