allocate global variable entry area by malloc and save it into pic_state
This commit is contained in:
parent
c92a672e01
commit
e7a5784fd7
|
@ -12,6 +12,7 @@
|
||||||
#define PIC_HEAP_SIZE 8192
|
#define PIC_HEAP_SIZE 8192
|
||||||
#define PIC_STACK_SIZE 1024
|
#define PIC_STACK_SIZE 1024
|
||||||
#define PIC_IREP_SIZE 256
|
#define PIC_IREP_SIZE 256
|
||||||
|
#define PIC_GLOBALS_SIZE 1024
|
||||||
|
|
||||||
/* enable all debug flags */
|
/* enable all debug flags */
|
||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
|
|
|
@ -27,6 +27,8 @@ typedef struct {
|
||||||
pic_value sADD, sSUB, sMUL, sDIV;
|
pic_value sADD, sSUB, sMUL, sDIV;
|
||||||
struct pic_env *global_env;
|
struct pic_env *global_env;
|
||||||
|
|
||||||
|
pic_value *globals;
|
||||||
|
size_t glen, gcapa;
|
||||||
struct pic_irep **irep;
|
struct pic_irep **irep;
|
||||||
size_t ilen, icapa;
|
size_t ilen, icapa;
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@ struct pic_code {
|
||||||
union {
|
union {
|
||||||
double f;
|
double f;
|
||||||
int i;
|
int i;
|
||||||
struct pic_pair *gvar;
|
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
1
src/gc.c
1
src/gc.c
|
@ -169,7 +169,6 @@ static void
|
||||||
gc_mark_phase(pic_state *pic)
|
gc_mark_phase(pic_state *pic)
|
||||||
{
|
{
|
||||||
pic_value *stack;
|
pic_value *stack;
|
||||||
pic_callinfo *ci;
|
|
||||||
struct pic_env *env;
|
struct pic_env *env;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,11 @@ pic_open()
|
||||||
pic->ilen = 0;
|
pic->ilen = 0;
|
||||||
pic->icapa = PIC_IREP_SIZE;
|
pic->icapa = PIC_IREP_SIZE;
|
||||||
|
|
||||||
|
/* globals */
|
||||||
|
pic->globals = (struct pic_value *)malloc(sizeof(pic_value) * PIC_GLOBALS_SIZE);
|
||||||
|
pic->glen = 0;
|
||||||
|
pic->gcapa = PIC_GLOBALS_SIZE;
|
||||||
|
|
||||||
/* GC arena */
|
/* GC arena */
|
||||||
pic->arena_idx = 0;
|
pic->arena_idx = 0;
|
||||||
|
|
||||||
|
|
114
src/vm.c
114
src/vm.c
|
@ -24,65 +24,55 @@ pic_assq(pic_state *pic, pic_value key, pic_value assoc)
|
||||||
goto enter;
|
goto enter;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum scope_type {
|
static bool
|
||||||
SCOPE_GLOBAL,
|
env_lookup(pic_state *pic, pic_value sym, struct pic_env *env, int *depth, int *idx)
|
||||||
SCOPE_NONLOCAL,
|
|
||||||
SCOPE_LOCAL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static enum scope_type
|
|
||||||
env_lookup(pic_state *pic, pic_value sym, struct pic_env *env, struct pic_pair **p)
|
|
||||||
{
|
{
|
||||||
pic_value v;
|
pic_value v;
|
||||||
bool f = true;
|
int d = 0;
|
||||||
|
|
||||||
enter:
|
enter:
|
||||||
|
|
||||||
v = pic_assq(pic, sym, env->assoc);
|
v = pic_assq(pic, sym, env->assoc);
|
||||||
if (! pic_nil_p(v)) {
|
if (! pic_nil_p(v)) {
|
||||||
*p = pic_pair_ptr(v);
|
if (env->parent == NULL) { /* global */
|
||||||
goto leave;
|
*depth = -1;
|
||||||
|
}
|
||||||
|
else { /* non-global */
|
||||||
|
*depth = d;
|
||||||
|
}
|
||||||
|
*idx = (int)pic_float(pic_pair_ptr(v)->cdr);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
f = false;
|
|
||||||
if (env->parent) {
|
if (env->parent) {
|
||||||
env = env->parent;
|
env = env->parent;
|
||||||
|
++d;
|
||||||
goto enter;
|
goto enter;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
*p = NULL;
|
|
||||||
|
|
||||||
leave:
|
|
||||||
|
|
||||||
if (env->parent) {
|
|
||||||
if (f) {
|
|
||||||
return SCOPE_LOCAL;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return SCOPE_NONLOCAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return SCOPE_GLOBAL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pic_pair *
|
static int
|
||||||
env_define(pic_state *pic, pic_value sym, struct pic_env *env)
|
env_global_define(pic_state *pic, pic_value sym)
|
||||||
{
|
{
|
||||||
pic_value cell;
|
pic_value cell;
|
||||||
|
int d, idx;
|
||||||
|
|
||||||
cell = pic_cons(pic, sym, pic_undef_value());
|
if (env_lookup(pic, sym, pic->global_env, &d, &idx)) {
|
||||||
env->assoc = pic_cons(pic, cell, env->assoc);
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
return pic_pair_ptr(cell);
|
idx = pic->glen++;
|
||||||
|
cell = pic_cons(pic, sym, pic_float_value(idx));
|
||||||
|
pic->global_env->assoc = pic_cons(pic, cell, pic->global_env->assoc);
|
||||||
|
|
||||||
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pic_env *
|
static struct pic_env *
|
||||||
env_new(pic_state *pic, pic_value args, struct pic_env *env)
|
env_new(pic_state *pic, pic_value args, struct pic_env *env)
|
||||||
{
|
{
|
||||||
struct pic_env *inner_env;
|
struct pic_env *inner_env;
|
||||||
pic_value v;
|
pic_value v, cell;
|
||||||
struct pic_pair *cell;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
inner_env = (struct pic_env *)pic_alloc(pic, sizeof(struct pic_env));
|
inner_env = (struct pic_env *)pic_alloc(pic, sizeof(struct pic_env));
|
||||||
|
@ -91,8 +81,10 @@ env_new(pic_state *pic, pic_value args, struct pic_env *env)
|
||||||
|
|
||||||
i = -1;
|
i = -1;
|
||||||
for (v = args; ! pic_nil_p(v); v = pic_cdr(pic, v)) {
|
for (v = args; ! pic_nil_p(v); v = pic_cdr(pic, v)) {
|
||||||
cell = env_define(pic, pic_car(pic, v), inner_env);
|
pic_value sym = pic_car(pic, v);
|
||||||
cell->cdr = pic_float_value(i--);
|
|
||||||
|
cell = pic_cons(pic, sym, pic_float_value(i--));
|
||||||
|
inner_env->assoc = pic_cons(pic, cell, inner_env->assoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return inner_env;
|
return inner_env;
|
||||||
|
@ -102,13 +94,13 @@ void
|
||||||
pic_defun(pic_state *pic, const char *name, pic_func_t cfunc)
|
pic_defun(pic_state *pic, const char *name, pic_func_t cfunc)
|
||||||
{
|
{
|
||||||
struct pic_proc *proc;
|
struct pic_proc *proc;
|
||||||
struct pic_pair *cell;
|
int idx;
|
||||||
|
|
||||||
proc = (struct pic_proc *)pic_obj_alloc(pic, sizeof(struct pic_proc), PIC_TT_PROC);
|
proc = (struct pic_proc *)pic_obj_alloc(pic, sizeof(struct pic_proc), PIC_TT_PROC);
|
||||||
proc->cfunc_p = true;
|
proc->cfunc_p = true;
|
||||||
proc->u.cfunc = cfunc;
|
proc->u.cfunc = cfunc;
|
||||||
cell = env_define(pic, pic_intern_cstr(pic, name), pic->global_env);
|
idx = env_global_define(pic, pic_intern_cstr(pic, name));
|
||||||
cell->cdr = pic_obj_value(proc);
|
pic->globals[idx] = pic_obj_value(proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -164,10 +156,10 @@ print_irep(pic_state *pic, struct pic_irep *irep)
|
||||||
printf("OP_PUSHNUM\t%g\n", irep->code[i].u.f);
|
printf("OP_PUSHNUM\t%g\n", irep->code[i].u.f);
|
||||||
break;
|
break;
|
||||||
case OP_GREF:
|
case OP_GREF:
|
||||||
printf("OP_GREF\t%p\n", irep->code[i].u.gvar);
|
printf("OP_GREF\t%i\n", irep->code[i].u.i);
|
||||||
break;
|
break;
|
||||||
case OP_GSET:
|
case OP_GSET:
|
||||||
printf("OP_GSET\t%p\n", irep->code[i].u.gvar);
|
printf("OP_GSET\t%i\n", irep->code[i].u.i);
|
||||||
break;
|
break;
|
||||||
case OP_LREF:
|
case OP_LREF:
|
||||||
printf("OP_LREF\t%d\n", irep->code[i].u.i);
|
printf("OP_LREF\t%d\n", irep->code[i].u.i);
|
||||||
|
@ -241,25 +233,25 @@ pic_gen(pic_state *pic, struct pic_irep *irep, pic_value obj, struct pic_env *en
|
||||||
|
|
||||||
switch (pic_type(obj)) {
|
switch (pic_type(obj)) {
|
||||||
case PIC_TT_SYMBOL: {
|
case PIC_TT_SYMBOL: {
|
||||||
enum scope_type s;
|
bool b;
|
||||||
struct pic_pair *gvar;
|
int depth, idx;
|
||||||
|
|
||||||
s = env_lookup(pic, obj, env, &gvar);
|
b = env_lookup(pic, obj, env, &depth, &idx);
|
||||||
if (! gvar) {
|
if (! b) {
|
||||||
pic_raise(pic, "unbound variable");
|
pic_raise(pic, "unbound variable");
|
||||||
}
|
}
|
||||||
switch (s) {
|
|
||||||
case SCOPE_LOCAL:
|
if (depth == -1) { /* global */
|
||||||
irep->code[irep->clen].insn = OP_LREF;
|
|
||||||
irep->code[irep->clen].u.i = (int)pic_float(gvar->cdr);
|
|
||||||
irep->clen++;
|
|
||||||
break;
|
|
||||||
case SCOPE_GLOBAL:
|
|
||||||
irep->code[irep->clen].insn = OP_GREF;
|
irep->code[irep->clen].insn = OP_GREF;
|
||||||
irep->code[irep->clen].u.gvar = gvar;
|
irep->code[irep->clen].u.i = idx;
|
||||||
irep->clen++;
|
irep->clen++;
|
||||||
break;
|
}
|
||||||
case SCOPE_NONLOCAL:
|
else if (depth == 0) { /* local */
|
||||||
|
irep->code[irep->clen].insn = OP_LREF;
|
||||||
|
irep->code[irep->clen].u.i = idx;
|
||||||
|
irep->clen++;
|
||||||
|
}
|
||||||
|
else { /* nonlocal */
|
||||||
pic_raise(pic, "reference to closed variable not supported");
|
pic_raise(pic, "reference to closed variable not supported");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -269,14 +261,14 @@ pic_gen(pic_state *pic, struct pic_irep *irep, pic_value obj, struct pic_env *en
|
||||||
|
|
||||||
proc = pic_car(pic, obj);
|
proc = pic_car(pic, obj);
|
||||||
if (pic_eq_p(pic, proc, sDEFINE)) {
|
if (pic_eq_p(pic, proc, sDEFINE)) {
|
||||||
struct pic_pair *gvar;
|
int idx;
|
||||||
|
|
||||||
gvar = env_define(pic, pic_car(pic, pic_cdr(pic, obj)), env);
|
idx = env_global_define(pic, pic_car(pic, pic_cdr(pic, obj)));
|
||||||
|
|
||||||
pic_gen(pic, irep, pic_car(pic, pic_cdr(pic, pic_cdr(pic, obj))), env);
|
pic_gen(pic, irep, pic_car(pic, pic_cdr(pic, pic_cdr(pic, obj))), env);
|
||||||
|
|
||||||
irep->code[irep->clen].insn = OP_GSET;
|
irep->code[irep->clen].insn = OP_GSET;
|
||||||
irep->code[irep->clen].u.gvar = gvar;
|
irep->code[irep->clen].u.i = idx;
|
||||||
irep->clen++;
|
irep->clen++;
|
||||||
irep->code[irep->clen].insn = OP_PUSHFALSE;
|
irep->code[irep->clen].insn = OP_PUSHFALSE;
|
||||||
irep->clen++;
|
irep->clen++;
|
||||||
|
@ -524,11 +516,11 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args)
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_GREF) {
|
CASE(OP_GREF) {
|
||||||
PUSH(pc->u.gvar->cdr);
|
PUSH(pic->globals[pc->u.i]);
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_GSET) {
|
CASE(OP_GSET) {
|
||||||
pc->u.gvar->cdr = POP();
|
pic->globals[pc->u.i] = POP();
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_LREF) {
|
CASE(OP_LREF) {
|
||||||
|
|
Loading…
Reference in New Issue