gnu_labels_as_values_threaded.c (863B)
1 /* GNU labels-as-values: a direct-threaded (computed-goto) bytecode 2 * interpreter driven by a function-local static dispatch table built from 3 * label addresses. Runs `push 3; push 4; add; push 5; mul; halt`, i.e. 4 * (3 + 4) * 5 = 35. */ 5 enum { OP_PUSH, OP_ADD, OP_MUL, OP_HALT }; 6 7 int test_main(void) { 8 static const unsigned char prog[] = { 9 OP_PUSH, 3, OP_PUSH, 4, OP_ADD, OP_PUSH, 5, OP_MUL, OP_HALT, 10 }; 11 static void* const tab[] = { 12 &&do_push, 13 &&do_add, 14 &&do_mul, 15 &&do_halt, 16 }; 17 int stack[16]; 18 int sp = 0; 19 const unsigned char* pc = prog; 20 21 goto* tab[*pc++]; 22 23 do_push: 24 stack[sp++] = *pc++; 25 goto* tab[*pc++]; 26 do_add: 27 stack[sp - 2] = stack[sp - 2] + stack[sp - 1]; 28 sp--; 29 goto* tab[*pc++]; 30 do_mul: 31 stack[sp - 2] = stack[sp - 2] * stack[sp - 1]; 32 sp--; 33 goto* tab[*pc++]; 34 do_halt: 35 return stack[sp - 1]; 36 }