123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- #include <assert.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "qcodes.h"
- #include "objects.h"
- #include "information.h"
- #include "symboltable.h"
- #include "glovars.h"
- #include "allocator.h"
- #include "vm.h"
- void vm_exec(scm *code) {
- static void* lbl[] = {
- [CODE_HALT] = &&lbl_halt,
-
- [CODE_DATUM_FALSE] = &&lbl_datum_false,
- [CODE_DATUM_TRUE] = &&lbl_datum_true,
- [CODE_DATUM_NULL] = &&lbl_datum_null,
- [CODE_DATUM_SYMBOL] = &&lbl_datum_symbol,
- [CODE_DATUM_CHAR] = &&lbl_datum_char,
- [CODE_DATUM_NUMBER] = &&lbl_datum_number,
- [CODE_DATUM_STRING] = &&lbl_datum_string,
-
- [CODE_ALLOCATE_CLOSURE] = &&lbl_allocate_closure,
- [CODE_CLOSURE_SET] = &&lbl_closure_set,
-
- [CODE_VAR_GLO] = &&lbl_var_glo,
- [CODE_SET_GLO] = &&lbl_set_glo,
- [CODE_VAR_LOC] = &&lbl_var_loc,
- [CODE_SET_LOC] = &&lbl_set_loc,
- [CODE_VAR_ENV] = &&lbl_var_env,
- [CODE_SET_ENV] = &&lbl_set_env,
- [CODE_CLO_SET_ACC] = &&lbl_clo_set_acc,
- [CODE_CLO_SET_LOC] = &&lbl_clo_set_loc,
- [CODE_SET_CLO_REG] = &&lbl_set_clo_reg,
-
- [CODE_JUMP] = &&lbl_jump,
- [CODE_BRANCH] = &&lbl_branch,
- [CODE_PUSH] = &&lbl_push,
- [CODE_STACK_GROW] = &&lbl_stack_grow,
- [CODE_STACKFRAME] = &&lbl_stackframe,
- [CODE_CALL] = &&lbl_call,
- [CODE_RET] = &&lbl_ret,
- [CODE_SHIFTBACK] = &&lbl_shiftback,
-
- [CODE_INFORMATION] = &&lbl_information,
- };
-
- struct global *glo;
- scm idx;
- scm num;
-
- #define CODEWORD (*(code++))
- #define NEXT goto *lbl[CODEWORD]
- //#define NEXT printf("[%ld]\n", *code); goto *lbl[CODEWORD]
-
- #define DBG(x) (void)0
- //#define DBG(x) x
-
- NEXT;
-
- lbl_halt:
- return;
-
- lbl_datum_false:
- reg_acc = ATOM_FLS;
- NEXT;
- lbl_datum_true:
- reg_acc = ATOM_TRU;
- NEXT;
- lbl_datum_null:
- reg_acc = ATOM_NUL;
- NEXT;
- lbl_datum_symbol:
- reg_acc = CODEWORD;
- NEXT;
- lbl_datum_char:
- reg_acc = CODEWORD;
- NEXT;
- lbl_datum_number:
- reg_acc = mk_numb(CODEWORD);
- NEXT;
- lbl_datum_string:
- reg_acc = CODEWORD;
- NEXT;
-
- lbl_allocate_closure:
- idx = CODEWORD;
- num = CODEWORD;
- reg_clo = allocate_clos(code + num, idx);
- NEXT;
- lbl_closure_set:
- idx = CODEWORD;
- scm_getptr(reg_clo)[2 + idx] = reg_acc;
- NEXT;
-
- lbl_var_glo:
- glo = (void*)CODEWORD;
- DBG(printf("[G:%p:%s]\n", glo, lookup(get_sym(glo->name))));
- reg_acc = glo->val;
- NEXT;
- lbl_set_glo:
- glo = (void*)CODEWORD;
- glo->val = reg_acc;
- NEXT;
- lbl_var_loc:
- idx = CODEWORD;
- reg_acc = stack[reg_rbp + 1 + idx];
- NEXT;
- lbl_set_loc:
- idx = CODEWORD;
- stack[reg_rbp + 1 + idx] = reg_acc;
- NEXT;
- lbl_var_env:
- idx = CODEWORD;
- reg_acc = reg_env[idx];
- NEXT;
- lbl_set_env:
- idx = CODEWORD;
- reg_env[idx] = reg_acc;
- NEXT;
- lbl_clo_set_acc:
- reg_acc = reg_clo;
- NEXT;
- lbl_clo_set_loc:
- idx = CODEWORD;
- stack[reg_rbp + 1 + idx] = reg_clo;
- NEXT;
- lbl_set_clo_reg:
- reg_clo = reg_acc;
- NEXT;
- lbl_jump:
- idx = CODEWORD;
- code += idx;
- NEXT;
- lbl_branch:
- idx = CODEWORD;
- if (reg_acc == ATOM_FLS)
- code += idx;
- NEXT;
- lbl_push:
- stack[++reg_rsp] = reg_acc;
- NEXT;
- lbl_stack_grow:
- reg_rsp += CODEWORD;
- NEXT;
- lbl_stackframe:
- idx = CODEWORD;
- stack[++reg_rsp] = 0xC0FFEEEEEEEEEEEE;
- stack[++reg_rsp] = (scm)(code + idx);
- stack[++reg_rsp] = (scm)reg_env;
- stack[++reg_rsp] = reg_rbp;
- stack[++reg_rsp] = 0xDEADBEEFDEADBEEF;
- reg_rbp_tmp = reg_rsp;
- NEXT;
- lbl_call:
- reg_rbp = reg_rbp_tmp;
- switch(scm_gettag(reg_acc)) {
- case TAG_BLTN:
- reg_acc = (get_bltn(reg_acc))();
- goto lbl_ret;
- break;
- case TAG_CLOS:
- code = PTR_SCM(get_clos(reg_acc)[1]);
- reg_env = get_clos(reg_acc)+2;
- break;
- default:
- stack_trace();
- fprintf(stderr, "call: not a closure 0x%lx %ld\n", reg_acc, scm_gettag(reg_acc));
- exit(1);
- }
- NEXT;
- lbl_ret:
- reg_rsp = reg_rbp;
- assert(stack[reg_rsp--] == 0xDEADBEEFDEADBEEF);
- reg_rbp = stack[reg_rsp--];
- reg_env = PTR_SCM(stack[reg_rsp--]);
- code = PTR_SCM(stack[reg_rsp--]);
- assert(stack[reg_rsp--] == 0xC0FFEEEEEEEEEEEE);
- NEXT;
- lbl_shiftback:
- num = CODEWORD;
- for(idx = 0; idx < num; idx++)
- stack[reg_rbp + 1 + idx] = stack[reg_rsp - num + 1 + idx];
- reg_rsp = reg_rbp + num + 1;
- reg_rbp_tmp = reg_rbp;
- NEXT;
-
- lbl_information:
- (void)CODEWORD;
- (void)CODEWORD;
- NEXT;
- }
|