add 'env' property to struct pic_proc

Using attribute to make closure from c function is unsafe because closed
variables are visible from the scheme world. Use env property instead
from now.
This commit is contained in:
Yuichi Nishiwaki 2015-05-31 20:46:44 +09:00
parent ce0c737c95
commit fc957da920
3 changed files with 31 additions and 0 deletions

View File

@ -375,6 +375,9 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
} }
} else { } else {
gc_mark_object(pic, (struct pic_object *)proc->u.f.name); gc_mark_object(pic, (struct pic_object *)proc->u.f.name);
if (proc->u.f.env) {
gc_mark_object(pic, (struct pic_object *)proc->u.f.env);
}
} }
break; break;
} }

View File

@ -27,6 +27,7 @@ struct pic_proc {
struct { struct {
pic_func_t func; pic_func_t func;
pic_sym *name; pic_sym *name;
struct pic_dict *env;
} f; } f;
struct { struct {
struct pic_irep *irep; struct pic_irep *irep;
@ -48,6 +49,9 @@ struct pic_proc *pic_make_proc(pic_state *, pic_func_t, const char *);
struct pic_proc *pic_make_proc_irep(pic_state *, struct pic_irep *, struct pic_context *); struct pic_proc *pic_make_proc_irep(pic_state *, struct pic_irep *, struct pic_context *);
pic_sym *pic_proc_name(struct pic_proc *); pic_sym *pic_proc_name(struct pic_proc *);
struct pic_dict *pic_proc_env(pic_state *, struct pic_proc *);
pic_value pic_proc_env_ref(pic_state *, struct pic_proc *, const char *);
void pic_proc_env_set(pic_state *, struct pic_proc *, const char *, pic_value);
#if defined(__cplusplus) #if defined(__cplusplus)
} }

View File

@ -18,6 +18,7 @@ pic_make_proc(pic_state *pic, pic_func_t func, const char *name)
proc->tag = PIC_PROC_TAG_FUNC; proc->tag = PIC_PROC_TAG_FUNC;
proc->u.f.func = func; proc->u.f.func = func;
proc->u.f.name = sym; proc->u.f.name = sym;
proc->u.f.env = NULL;
return proc; return proc;
} }
@ -45,6 +46,29 @@ pic_proc_name(struct pic_proc *proc)
PIC_UNREACHABLE(); PIC_UNREACHABLE();
} }
struct pic_dict *
pic_proc_env(pic_state *pic, struct pic_proc *proc)
{
assert(pic_proc_func_p(proc));
if (! proc->u.f.env) {
proc->u.f.env = pic_make_dict(pic);
}
return proc->u.f.env;
}
pic_value
pic_proc_env_ref(pic_state *pic, struct pic_proc *proc, const char *key)
{
return pic_dict_ref(pic, pic_proc_env(pic, proc), pic_intern_cstr(pic, key));
}
void
pic_proc_env_set(pic_state *pic, struct pic_proc *proc, const char *key, pic_value val)
{
pic_dict_set(pic, pic_proc_env(pic, proc), pic_intern_cstr(pic, key), val);
}
static pic_value static pic_value
pic_proc_proc_p(pic_state *pic) pic_proc_proc_p(pic_state *pic)
{ {