Merge branch 'global-table'
This commit is contained in:
commit
dbad3690af
|
@ -88,10 +88,7 @@ typedef struct {
|
||||||
int sym_cnt;
|
int sym_cnt;
|
||||||
int uniq_sym_cnt;
|
int uniq_sym_cnt;
|
||||||
|
|
||||||
xhash global_tbl;
|
xhash globals;
|
||||||
pic_value *globals;
|
|
||||||
size_t glen, gcapa;
|
|
||||||
|
|
||||||
xhash macros;
|
xhash macros;
|
||||||
|
|
||||||
pic_value lib_tbl;
|
pic_value lib_tbl;
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
|
|
||||||
/* #define PIC_RESCUE_SIZE 30 */
|
/* #define PIC_RESCUE_SIZE 30 */
|
||||||
|
|
||||||
/* #define PIC_GLOBALS_SIZE 1024 */
|
|
||||||
|
|
||||||
/* #define PIC_SYM_POOL_SIZE 128 */
|
/* #define PIC_SYM_POOL_SIZE 128 */
|
||||||
|
|
||||||
/* #define PIC_IREP_SIZE 8 */
|
/* #define PIC_IREP_SIZE 8 */
|
||||||
|
@ -93,10 +91,6 @@
|
||||||
# define PIC_RESCUE_SIZE 30
|
# define PIC_RESCUE_SIZE 30
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PIC_GLOBALS_SIZE
|
|
||||||
# define PIC_GLOBALS_SIZE 1024
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PIC_SYM_POOL_SIZE
|
#ifndef PIC_SYM_POOL_SIZE
|
||||||
# define PIC_SYM_POOL_SIZE 128
|
# define PIC_SYM_POOL_SIZE 128
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -100,7 +100,7 @@ new_analyze_state(pic_state *pic)
|
||||||
/* push initial scope */
|
/* push initial scope */
|
||||||
push_scope(state, pic_nil_value());
|
push_scope(state, pic_nil_value());
|
||||||
|
|
||||||
xh_begin(&it, &pic->global_tbl);
|
xh_begin(&it, &pic->globals);
|
||||||
while (xh_next(&it)) {
|
while (xh_next(&it)) {
|
||||||
pic_sym sym = xh_key(it.e, pic_sym);
|
pic_sym sym = xh_key(it.e, pic_sym);
|
||||||
xv_push(&state->scope->locals, &sym);
|
xv_push(&state->scope->locals, &sym);
|
||||||
|
@ -291,20 +291,8 @@ static pic_value
|
||||||
analyze_global_var(analyze_state *state, pic_sym sym)
|
analyze_global_var(analyze_state *state, pic_sym sym)
|
||||||
{
|
{
|
||||||
pic_state *pic = state->pic;
|
pic_state *pic = state->pic;
|
||||||
xh_entry *e;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if ((e = xh_get_int(&pic->global_tbl, sym))) {
|
return pic_list2(pic, pic_symbol_value(state->sGREF), pic_sym_value(sym));
|
||||||
i = xh_val(e, size_t);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
i = pic->glen++;
|
|
||||||
if (i >= pic->gcapa) {
|
|
||||||
pic_error(pic, "global table overflow");
|
|
||||||
}
|
|
||||||
xh_put_int(&pic->global_tbl, sym, &i);
|
|
||||||
}
|
|
||||||
return pic_list2(pic, pic_symbol_value(state->sGREF), pic_int_value(i));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
|
@ -1096,7 +1084,7 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
sym = pic_sym(pic_car(pic, obj));
|
sym = pic_sym(pic_car(pic, obj));
|
||||||
if (sym == state->sGREF) {
|
if (sym == state->sGREF) {
|
||||||
cxt->code[cxt->clen].insn = OP_GREF;
|
cxt->code[cxt->clen].insn = OP_GREF;
|
||||||
cxt->code[cxt->clen].u.i = pic_int(pic_list_ref(pic, obj, 1));
|
cxt->code[cxt->clen].u.i = pic_sym(pic_list_ref(pic, obj, 1));
|
||||||
cxt->clen++;
|
cxt->clen++;
|
||||||
return;
|
return;
|
||||||
} else if (sym == state->sCREF) {
|
} else if (sym == state->sCREF) {
|
||||||
|
|
5
src/gc.c
5
src/gc.c
|
@ -575,8 +575,9 @@ gc_mark_phase(pic_state *pic)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* global variables */
|
/* global variables */
|
||||||
for (i = 0; i < pic->glen; ++i) {
|
xh_begin(&it, &pic->globals);
|
||||||
gc_mark(pic, pic->globals[i]);
|
while (xh_next(&it)) {
|
||||||
|
gc_mark(pic, xh_val(it.e, pic_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* macro objects */
|
/* macro objects */
|
||||||
|
|
|
@ -49,10 +49,7 @@ pic_open(int argc, char *argv[], char **envp)
|
||||||
pic->uniq_sym_cnt = 0;
|
pic->uniq_sym_cnt = 0;
|
||||||
|
|
||||||
/* global variables */
|
/* global variables */
|
||||||
xh_init_int(&pic->global_tbl, sizeof(size_t));
|
xh_init_int(&pic->globals, sizeof(pic_value));
|
||||||
pic->globals = (pic_value *)calloc(PIC_GLOBALS_SIZE, sizeof(pic_value));
|
|
||||||
pic->glen = 0;
|
|
||||||
pic->gcapa = PIC_GLOBALS_SIZE;
|
|
||||||
|
|
||||||
/* macros */
|
/* macros */
|
||||||
xh_init_int(&pic->macros, sizeof(struct pic_macro *));
|
xh_init_int(&pic->macros, sizeof(struct pic_macro *));
|
||||||
|
@ -164,7 +161,6 @@ pic_close(pic_state *pic)
|
||||||
pic->ci = pic->cibase;
|
pic->ci = pic->cibase;
|
||||||
pic->arena_idx = 0;
|
pic->arena_idx = 0;
|
||||||
pic->err = NULL;
|
pic->err = NULL;
|
||||||
pic->glen = 0;
|
|
||||||
xh_clear(&pic->macros);
|
xh_clear(&pic->macros);
|
||||||
pic->lib_tbl = pic_nil_value();
|
pic->lib_tbl = pic_nil_value();
|
||||||
|
|
||||||
|
@ -179,10 +175,9 @@ pic_close(pic_state *pic)
|
||||||
free(pic->cibase);
|
free(pic->cibase);
|
||||||
|
|
||||||
/* free global stacks */
|
/* free global stacks */
|
||||||
free(pic->globals);
|
|
||||||
free(pic->try_jmps);
|
free(pic->try_jmps);
|
||||||
xh_destroy(&pic->syms);
|
xh_destroy(&pic->syms);
|
||||||
xh_destroy(&pic->global_tbl);
|
xh_destroy(&pic->globals);
|
||||||
xh_destroy(&pic->macros);
|
xh_destroy(&pic->macros);
|
||||||
xh_destroy(&pic->rlabels);
|
xh_destroy(&pic->rlabels);
|
||||||
|
|
||||||
|
|
87
src/vm.c
87
src/vm.c
|
@ -387,79 +387,38 @@ pic_get_args(pic_state *pic, const char *format, ...)
|
||||||
return i - 1;
|
return i - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
|
||||||
global_ref(pic_state *pic, const char *name)
|
|
||||||
{
|
|
||||||
xh_entry *e;
|
|
||||||
pic_sym sym, rename;
|
|
||||||
|
|
||||||
sym = pic_intern_cstr(pic, name);
|
|
||||||
if (! pic_find_rename(pic, pic->lib->env, sym, &rename)) {
|
|
||||||
return SIZE_MAX;
|
|
||||||
}
|
|
||||||
if (! (e = xh_get_int(&pic->global_tbl, rename))) {
|
|
||||||
return SIZE_MAX;
|
|
||||||
}
|
|
||||||
return xh_val(e, size_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t
|
|
||||||
global_def(pic_state *pic, const char *name)
|
|
||||||
{
|
|
||||||
pic_sym sym, rename;
|
|
||||||
size_t gidx;
|
|
||||||
|
|
||||||
sym = pic_intern_cstr(pic, name);
|
|
||||||
if ((gidx = global_ref(pic, name)) != SIZE_MAX) {
|
|
||||||
pic_warn(pic, "redefining global");
|
|
||||||
return gidx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* register to the senv */
|
|
||||||
rename = pic_add_rename(pic, pic->lib->env, sym);
|
|
||||||
|
|
||||||
/* register to the global table */
|
|
||||||
gidx = pic->glen++;
|
|
||||||
if (pic->glen >= pic->gcapa) {
|
|
||||||
pic_error(pic, "global table overflow");
|
|
||||||
}
|
|
||||||
xh_put_int(&pic->global_tbl, rename, &gidx);
|
|
||||||
|
|
||||||
return gidx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
pic_define(pic_state *pic, const char *name, pic_value val)
|
pic_define(pic_state *pic, const char *name, pic_value val)
|
||||||
{
|
{
|
||||||
|
pic_sym sym, rename;
|
||||||
|
|
||||||
|
sym = pic_intern_cstr(pic, name);
|
||||||
|
|
||||||
|
if (! pic_find_rename(pic, pic->lib->env, sym, &rename)) {
|
||||||
|
rename = pic_add_rename(pic, pic->lib->env, sym);
|
||||||
|
} else {
|
||||||
|
pic_warn(pic, "redefining global");
|
||||||
|
}
|
||||||
|
|
||||||
/* push to the global arena */
|
/* push to the global arena */
|
||||||
pic->globals[global_def(pic, name)] = val;
|
xh_put_int(&pic->globals, rename, &val);
|
||||||
|
|
||||||
/* export! */
|
/* export! */
|
||||||
pic_export(pic, pic_intern_cstr(pic, name));
|
pic_export(pic, sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
pic_value
|
pic_value
|
||||||
pic_ref(pic_state *pic, const char *name)
|
pic_ref(pic_state *pic, const char *name)
|
||||||
{
|
{
|
||||||
size_t gid;
|
pic_sym sym, rename;
|
||||||
|
|
||||||
gid = global_ref(pic, name);
|
sym = pic_intern_cstr(pic, name);
|
||||||
if (gid == SIZE_MAX) {
|
|
||||||
|
if (! pic_find_rename(pic, pic->lib->env, sym, &rename)) {
|
||||||
pic_errorf(pic, "symbol \"%s\" not defined", name);
|
pic_errorf(pic, "symbol \"%s\" not defined", name);
|
||||||
}
|
}
|
||||||
return pic->globals[gid];
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
return xh_val(xh_get_int(&pic->globals, rename), pic_value);
|
||||||
pic_set(pic_state *pic, const char *name, pic_value value)
|
|
||||||
{
|
|
||||||
size_t gid;
|
|
||||||
|
|
||||||
gid = global_ref(pic, name);
|
|
||||||
if (gid == SIZE_MAX) {
|
|
||||||
pic_error(pic, "symbol not defined");
|
|
||||||
}
|
|
||||||
pic->globals[gid] = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pic_value
|
pic_value
|
||||||
|
@ -675,11 +634,19 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value argv)
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_GREF) {
|
CASE(OP_GREF) {
|
||||||
PUSH(pic->globals[c.u.i]);
|
xh_entry *e;
|
||||||
|
|
||||||
|
if ((e = xh_get_int(&pic->globals, c.u.i)) == NULL) {
|
||||||
|
pic_errorf(pic, "logic flaw; reference to uninitialized global variable: ~s", pic_symbol_name(pic, c.u.i));
|
||||||
|
}
|
||||||
|
PUSH(xh_val(e, pic_value));
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_GSET) {
|
CASE(OP_GSET) {
|
||||||
pic->globals[c.u.i] = POP();
|
pic_value val;
|
||||||
|
|
||||||
|
val = POP();
|
||||||
|
xh_put_int(&pic->globals, c.u.i, &val);
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_LREF) {
|
CASE(OP_LREF) {
|
||||||
|
|
Loading…
Reference in New Issue