-
-\section{Interpreter}
-The client contains an interpreter to execute a \gls{Task}'s bytecode.
-
-First some preparatory work is done. The stack will be initialized and the
-program counter and stack pointer are set to zero and the bottom respectively.
-Then the interpreter executes one step at the time while the program counter is
-smaller than the program length. The code for this is listed in
-Listing~\ref{lst:interpr}. One execution step is basically a big switch
-statement going over all possible bytecode instructions. Some instructions are
-detailed upon in the listing. The \CI{BCPush} instruction is a little more
-complicated in real life because some decoding will take place as not all
-\CI{BCValue}'s are of the same length.
-
-\begin{lstlisting}[language=C,label={lst:interpr},%
- caption={Rough code outline for interpretation}]
-#define f16(p) program[pc]*265+program[pc+1]
-
-void run_task(struct task *t){
- uint8_t *program = t->bc;
- int plen = t->tasklength;
- int pc = 0;
- int sp = 0;
- while(pc < plen){
- switch(program[pc++]){
- case BCNOP:
- break;
- case BCPUSH:
- stack[sp++] = pc++ //Simplified
- break;
- case BCPOP:
- sp--;
- break;
- case BCSDSSTORE:
- sds_store(f16(pc), stack[--sp]);
- pc+=2;
- break;
- // ...
- case BCADD: trace("add");
- stack[sp-2] = stack[sp-2] + stack[sp-1];
- sp -= 1;
- break;
- // ...
- case BCJMPT: trace("jmpt to %d", program[pc]);
- pc = stack[--sp] ? program[pc]-1 : pc+1;
- break;
-}
-\end{lstlisting}