Simplified script VM:

- removed I_RET instruction, return is now implicit at end of script
 - I_POP is not a binary instruction.

git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@963 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
twanvl
2008-06-03 14:08:11 +00:00
parent 03cfd6bb79
commit 6912dfda09
9 changed files with 99 additions and 107 deletions
+18 -25
View File
@@ -39,12 +39,10 @@ ScriptValueP Context::eval(const Script& script, bool useScope) {
try {
// Instruction pointer
const Instruction* instr = &script.instructions[0];
const Instruction* end = &*script.instructions.end();
// Loop until we are done
while (true) {
assert(instr < &*script.instructions.end());
// debug
// cout << script.dumpInstr(instr - &script.instructions[0], *instr) << endl;
while (instr < end) {
// Evaluate the current instruction
Instruction i = *instr++;
switch (i.instr) {
@@ -54,11 +52,6 @@ ScriptValueP Context::eval(const Script& script, bool useScope) {
stack.push_back(script.constants[i.data]);
break;
}
// Pop top value
case I_POP: {
stack.pop_back();
break;
}
// Jump
case I_JUMP: {
instr = &script.instructions[i.data];
@@ -144,21 +137,10 @@ ScriptValueP Context::eval(const Script& script, bool useScope) {
closeScope(scope);
break;
}
// Function return
case I_RET: {
// restore shadowed variables
if (useScope) closeScope(scope);
// return top of stack
ScriptValueP result = stack.back();
stack.pop_back();
assert(stack.size() == stack_size); // we end up with the same stack
return result;
}
// Simple instruction: unary
case I_UNARY: {
instrUnary(i.instr1, stack.back());
// cout << "\t\t-> " << (String)*stack.back() << endl;
break;
}
// Simple instruction: binary
@@ -166,7 +148,6 @@ ScriptValueP Context::eval(const Script& script, bool useScope) {
ScriptValueP b = stack.back(); stack.pop_back();
ScriptValueP& a = stack.back();
instrBinary(i.instr2, a, b);
// cout << "\t\t-> " << (String)*stack.back() << endl;
break;
}
// Simple instruction: ternary
@@ -175,7 +156,6 @@ ScriptValueP Context::eval(const Script& script, bool useScope) {
ScriptValueP b = stack.back(); stack.pop_back();
ScriptValueP& a = stack.back();
instrTernary(i.instr3, a, b, c);
// cout << "\t\t-> " << (String)*stack.back() << endl;
break;
}
// Simple instruction: quaternary
@@ -185,12 +165,20 @@ ScriptValueP Context::eval(const Script& script, bool useScope) {
ScriptValueP b = stack.back(); stack.pop_back();
ScriptValueP& a = stack.back();
instrQuaternary(i.instr4, a, b, c, d);
// cout << "\t\t-> " << (String)*stack.back() << endl;
break;
}
}
}
// Function return
// restore shadowed variables
if (useScope) closeScope(scope);
// return top of stack
ScriptValueP result = stack.back();
stack.pop_back();
assert(stack.size() == stack_size); // we end up with the same stack
return result;
} catch (...) {
// cleanup after an exception
if (useScope) closeScope(scope); // restore scope
@@ -322,14 +310,19 @@ class ScriptCompose : public ScriptValue {
};
void instrBinary (BinaryInstructionType i, ScriptValueP& a, const ScriptValueP& b) {
ScriptType at = a->type(), bt = b->type();
switch (i) {
case I_POP:
// a = a;
break;
case I_MEMBER:
a = a->getMember(*b);
break;
case I_ITERATOR_R:
a = rangeIterator(*a, *b);
break;
default:
ScriptType at = a->type(), bt = b->type();
switch(i) {
case I_ADD: // add is quite overloaded
if (at == SCRIPT_NIL) {
a = b;
@@ -370,7 +363,7 @@ void instrBinary (BinaryInstructionType i, ScriptValueP& a, const ScriptValueP&
case I_OR_ELSE:
if (at == SCRIPT_ERROR) a = b;
break;
}
}}
}
// ----------------------------------------------------------------------------- : Simple instructions : ternary