123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "vm.h"
- #include "gc.h"
- #include "builtins.h"
- //#define DEBUG_COUNT_BUILTINS
- #ifdef DEBUG_COUNT_BUILTINS
- int count_builtin[50] = { 0 };
- #endif
- //#define DEBUG
- void vm_put_place(unsigned char place_sort, scm place_index, scm obj) {
- switch(place_sort) {
- case 'r':
- vm_reg_ret = obj;
- break;
-
- case 'g':
- vm_set_global(place_index, obj);
- break;
- case 't':
- vm_set_stack_top(place_index, obj);
- break;
-
- case 'l':
- vm_set_stack_base(place_index, obj);
- break;
-
- case 'e':
- clos_set_env(vm_reg_env, place_index, obj);
- break;
-
- default:
- fprintf(stderr, "Unknown place sort %c\n", place_sort);
- exit(-1);
- }
- }
- void execute(void) {
- unsigned char c;
- while(1) {
- #ifdef DEBUG
- char tmp_buf[512];
- strncpy(tmp_buf, (char*)(bytecode+place), 32);
- printf("<<<%s>>>\n", tmp_buf);
- #endif
-
- c = bytecode[place++];
- switch(c) {
- case 'H':
- vm_halt();
- break;
-
- case 'Q':
- vm_quit();
- break;
-
- case 'B':
- vm_builtin();
- break;
-
- case 'A':
- vm_alloc();
- break;
-
- case 'c':
- vm_make_closure();
- break;
-
- case 'E':
- vm_set_closure();
- break;
-
- case 'C':
- vm_call();
- break;
-
- case 'T':
- vm_tail_call();
- break;
-
- case 'M':
- vm_move();
- break;
-
- case 'R':
- vm_return();
- break;
-
- case 'b':
- vm_branch();
- break;
-
- case 'J':
- vm_jump();
- break;
-
- default:
- fprintf(stderr, "Unknown VM instruction [%c] at %ld\n", c, place);
- //strncpy(tmp_buf, (char*)(bytecode), 32);
- //printf("<<<%s>>>\n", tmp_buf);
- //printf("%c %d\n", i1, blt_tsh);
-
- exit(-1);
- }
- }
- }
- void vm_halt() {
- #ifdef DEBUG
- fprintf(stderr, "VM [%s]\n", "HALT");
- #endif
-
- while(bytecode[place++] != '\n') {}
- }
- void vm_quit() {
- #ifdef DEBUG
- fprintf(stderr, "VM [%s]\n", "QUIT");
- #endif
- #ifdef DEBUG_COUNT_BUILTINS
- for(int i = 0; i < 50; i++) {
- printf("BLTN[%2d] used %4d times\n", i, count_builtin[i]);
- }
- #endif
- exit(0);
- }
- void vm_builtin() {
- #ifdef DEBUG
- fprintf(stderr, "VM [%s]\n", "BUILTIN");
- #endif
-
- unsigned char place_sort;
- scm place_index;
- scm n;
-
- bytecode_read_place(&place_sort, &place_index);
- n = bytecode_read_n(2);
- bytecode_read_args();
-
- #ifdef DEBUG
- fprintf(stderr, "VM [%s %ld]\n", "BUILTIN", n);
- for(int i = 0; i < bytecode_args_num; i++) {
- void builtin_display(scm);
- printf("ARG %d %ld\n", i, scm_get_tag(bytecode_args[i]));
- scm_display(bytecode_args[i]);
- puts("");
- }
- puts(".");
- #endif
-
- builtin_handler h;
- scm res;
-
- h = handler[n];
- if(!h) {
- fprintf(stderr, "unimplemented or missing builtin %ld\n", n);
- exit(-1);
- }
- #ifdef DEBUG_COUNT_BUILTINS
- count_builtin[n]++;
- #endif
- res = h();
- vm_put_place(place_sort, place_index, res);
- }
- void vm_alloc() {
- #ifdef DEBUG
- fprintf(stderr, "VM [%s]\n", "ALLOC");
- #endif
- scm n;
- n = bytecode_read_n(2);
-
- stack_grow(n);
- }
- void vm_make_closure() {
- #ifdef DEBUG
- fprintf(stderr, "VM [%s]\n", "MAKE-CLOSURE");
- #endif
- unsigned char place_sort;
- scm place_index;
- scm lbl;
- scm n;
- bytecode_read_place(&place_sort, &place_index);
- lbl = bytecode_read_n(6);
- n = bytecode_read_n(2);
- scm clo;
- scm *ptr;
- int i;
- clo = heap_alloc_closure(n, lbl);
- ptr = get_clos(clo);
- for(i = 0; i < n; i++) {
- ptr[2 + i] = 0;
- }
-
- vm_put_place(place_sort, place_index, clo);
- }
- void vm_set_closure() {
- #ifdef DEBUG
- fprintf(stderr, "VM [%s]\n", "SET-CLOSURE!");
- #endif
- scm clo;
- scm n;
- scm val;
- clo = bytecode_read_val();
- n = bytecode_read_n(2);
- val = bytecode_read_val();
-
- clos_set_env(clo, n, val);
- }
- void vm_call() {
- #ifdef DEBUG
- fprintf(stderr, "VM [%s]\n", "CALL");
- #endif
- scm clo;
- int i;
- clo = bytecode_read_val();
- bytecode_read_args();
- stack_push(0xC0DEDBADC0DEDBAD);
- stack_push(vm_stack_base_ptr);
- stack_push(vm_reg_env);
- stack_push(place);
- stack_push(0xC0FFEEEEEEEEEEEE);
- vm_stack_base_ptr = vm_stack_ptr;
- for(i = 0; i < bytecode_args_num; i++) {
- stack_push(bytecode_args[i]);
- }
-
- vm_reg_env = clo;
- place = clos_lbl(clo);
- }
- void vm_tail_call() {
- #ifdef DEBUG
- fprintf(stderr, "VM [%s]\n", "TAIL-CALL");
- #endif
-
- scm clo;
- int i;
-
- clo = bytecode_read_val();
- bytecode_read_args();
-
- vm_stack_ptr = vm_stack_base_ptr;
- for(i = 0; i < bytecode_args_num; i++) {
- stack_push(bytecode_args[i]);
- }
-
- vm_reg_env = clo;
- place = clos_lbl(clo);
- }
- void vm_move() {
- #ifdef DEBUG
- fprintf(stderr, "VM [%s]\n", "MOVE");
- #endif
-
- unsigned char place_sort;
- scm place_index;
- scm val;
- bytecode_read_place(&place_sort, &place_index);
- val = bytecode_read_val();
-
- vm_put_place(place_sort, place_index, val);
- }
- void vm_return() {
- #ifdef DEBUG
- fprintf(stderr, "VM [%s]\n", "RETURN");
- #endif
- scm tmp;
-
- vm_stack_ptr = vm_stack_base_ptr;
-
- tmp = stack_pop();
- assert(tmp == 0xC0FFEEEEEEEEEEEE);
- place = stack_pop();
- vm_reg_env = stack_pop();
- vm_stack_base_ptr = stack_pop();
- tmp = stack_pop();
- assert(tmp == 0xC0DEDBADC0DEDBAD);
- }
- void vm_branch() {
- #ifdef DEBUG
- fprintf(stderr, "VM [%s]\n", "BRANCH");
- #endif
- scm ip;
- ip = bytecode_read_n(6);
- if(vm_reg_ret != atom_tag_fals)
- place = ip;
- }
- void vm_jump() {
- #ifdef DEBUG
- fprintf(stderr, "VM [%s]\n", "JUMP");
- #endif
- scm ip;
- ip = bytecode_read_n(6);
- place = ip;
- }
|