]> git.sesse.net Git - interpreter_trials/blobdiff - interpreter6.cpp
Add a tail-call variant with state as global variables in locked registers.
[interpreter_trials] / interpreter6.cpp
index e71cfb93916af05499b375957ec23599545d849b..590caa0ca1158e2f497828c83898e8feb1721b3b 100644 (file)
@@ -15,11 +15,7 @@ namespace interpreter6
     {
         int32_t regs[16] = {0};
         uint32_t final_cycle_count = 0;
-    };
-
-
-    struct ReturnException
-    {
+        bool exit = false;
     };
 
 
@@ -39,7 +35,8 @@ namespace interpreter6
     {
         cycle_count += 1;
         state->final_cycle_count = cycle_count;
-        throw ReturnException();
+        state->exit = true;
+        return RETURN_VAL;
     }
 
     ReturnVal op_add(PARAMS)
@@ -133,25 +130,20 @@ namespace interpreter6
         CpuState *state = &local_state;
         uint8_t *pc = program;
         state->regs[X0] = param;
+        state->exit = false;
         uint32_t cycle_count = 0;
         Flags flags = {0, 0};
-        try
+        while(!state->exit)
         {
-            while(true)
-            {
-                uint8_t opcode = *pc++;
-                ReturnVal ret = dispatch_table[opcode](ARGS);
-                pc = ret.pc;
-                flags = ret.flags;
-                cycle_count = ret.cycle_count;
-            }
-
-
-        } catch(ReturnException ex)
-        {
-            return std::make_pair(state->regs[X0], state->final_cycle_count);
+            uint8_t opcode = *pc++;
+            ReturnVal ret = dispatch_table[opcode](ARGS);
+            pc = ret.pc;
+            flags = ret.flags;
+            cycle_count = ret.cycle_count;
         }
 
+        return std::make_pair(state->regs[X0], state->final_cycle_count);
+
     }