Created
December 15, 2014 13:55
-
-
Save jaz303/f2dc513f5c20353a2888 to your computer and use it in GitHub Desktop.
Interruptible VM with signal handlers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <signal.h> | |
typedef enum opcode { | |
OP_HALT = 0, | |
OP_NOP, | |
OP_JMP, | |
OP_MAX | |
} opcode_t; | |
typedef struct ins { | |
char i; | |
char o; | |
} ins_t; | |
void **jump_table_hack; | |
void exec(ins_t*, void***); | |
static void catch_signal(int signo) { | |
puts("abort requested!\n"); | |
// caught a SIGINT - rewrite the opcode handlers so that | |
// every instruction is handled as OP_HALT - this forces | |
// the VM to exit with clobbering the input program | |
for (int i = 1; i < OP_MAX; ++i) { | |
jump_table_hack[i] = jump_table_hack[0]; | |
} | |
} | |
int main(int argc, char *argv[]) { | |
// steal the jump table so the signal handler | |
// can rewrite it to force program abort | |
exec(NULL, &jump_table_hack); | |
// program that loops forever | |
ins_t myprog[] = { | |
{ OP_NOP, 0 }, | |
{ OP_JMP, 0 } | |
}; | |
// install signal handler | |
if (signal(SIGINT, catch_signal) == SIG_ERR) { | |
fputs("boom\n", stderr); | |
return EXIT_FAILURE; | |
} | |
// run the program | |
exec(myprog, NULL); | |
return 0; | |
} | |
void exec(ins_t *program, void ***jump_table_out) { | |
static void *jump_table[] = { | |
&&L_HALT, | |
&&L_NOP, | |
&&L_JMP | |
}; | |
if (jump_table_out) { | |
*jump_table_out = (void**)&jump_table; | |
return; | |
} | |
int ip = 0; | |
goto *(jump_table[program[ip].i]); | |
L_HALT: | |
puts("interpreter exited gracefully!\n"); | |
return; | |
L_NOP: | |
printf("NOP!\n"); | |
goto *jump_table[program[++ip].i]; | |
L_JMP: | |
ip = program[ip].o; | |
goto *jump_table[program[ip].i]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment