don't use zero length arrray field for struct proc

This commit is contained in:
Yuichi Nishiwaki 2017-04-09 19:42:03 +09:00
parent 960029841e
commit 69cdedc79f
4 changed files with 40 additions and 37 deletions

View File

@ -342,17 +342,16 @@ gc_mark_object(pic_state *pic, struct object *obj)
break; break;
} }
case PIC_TYPE_PROC_FUNC: { case PIC_TYPE_PROC_FUNC: {
int i; if (obj->u.proc.fp) {
for (i = 0; i < obj->u.proc.u.f.localc; ++i) { LOOP(obj->u.proc.fp);
gc_mark(pic, obj->u.proc.locals[i]);
} }
break; break;
} }
case PIC_TYPE_PROC_IREP: { case PIC_TYPE_PROC_IREP: {
if (obj->u.proc.u.i.fp) { if (obj->u.proc.fp) {
gc_mark_object(pic, (struct object *)obj->u.proc.u.i.fp); gc_mark_object(pic, (struct object *)obj->u.proc.fp);
} }
LOOP(obj->u.proc.u.i.irep); LOOP(obj->u.proc.u.irep);
break; break;
} }
case PIC_TYPE_IREP: { case PIC_TYPE_IREP: {

View File

@ -107,16 +107,10 @@ struct frame {
struct proc { struct proc {
OBJECT_HEADER OBJECT_HEADER
union { union {
struct { pic_func_t func;
pic_func_t func; struct irep *irep;
int localc;
} f;
struct {
struct irep *irep;
struct frame *fp;
} i;
} u; } u;
pic_value locals[1]; struct frame *fp;
}; };
enum { enum {

View File

@ -35,14 +35,22 @@ pic_value
pic_make_proc_func(pic_state *pic, pic_func_t func, int n, pic_value *env) pic_make_proc_func(pic_state *pic, pic_func_t func, int n, pic_value *env)
{ {
struct proc *proc; struct proc *proc;
int i; struct frame *fp = NULL;
proc = (struct proc *)pic_obj_alloc(pic, offsetof(struct proc, locals) + sizeof(pic_value) * n, PIC_TYPE_PROC_FUNC); if (n > 0) {
proc->u.f.func = func; int i;
proc->u.f.localc = n; fp = (struct frame *)pic_obj_alloc(pic, offsetof(struct frame, storage) + sizeof(pic_value) * n, PIC_TYPE_FRAME);
for (i = 0; i < n; ++i) { fp->regc = n;
proc->locals[i] = env[i]; fp->regs = fp->storage;
fp->up = NULL;
for (i = 0; i < n; ++i) {
fp->regs[i] = env[i];
}
} }
proc = (struct proc *)pic_obj_alloc(pic, sizeof(struct proc), PIC_TYPE_PROC_FUNC);
proc->u.func = func;
proc->fp = fp;
return obj_value(pic, proc); return obj_value(pic, proc);
} }
@ -51,9 +59,9 @@ pic_make_proc_irep(pic_state *pic, struct irep *irep, struct frame *fp)
{ {
struct proc *proc; struct proc *proc;
proc = (struct proc *)pic_obj_alloc(pic, offsetof(struct proc, locals), PIC_TYPE_PROC_IREP); proc = (struct proc *)pic_obj_alloc(pic, sizeof(struct proc), PIC_TYPE_PROC_IREP);
proc->u.i.irep = irep; proc->u.irep = irep;
proc->u.i.fp = fp; proc->fp = fp;
return obj_value(pic, proc); return obj_value(pic, proc);
} }
@ -292,23 +300,25 @@ pic_get_args(pic_state *pic, const char *format, ...)
pic_value pic_value
pic_closure_ref(pic_state *pic, int n) pic_closure_ref(pic_state *pic, int n)
{ {
pic_value self = GET_PROC(pic); struct proc *proc = proc_ptr(pic, GET_PROC(pic));
if (n < 0 || proc_ptr(pic, self)->u.f.localc <= n) { assert(n >= 0);
if (proc->fp == NULL || proc->fp->regc <= n) {
pic_error(pic, "pic_closure_ref: index out of range", 1, pic_int_value(pic, n)); pic_error(pic, "pic_closure_ref: index out of range", 1, pic_int_value(pic, n));
} }
return proc_ptr(pic, self)->locals[n]; return proc->fp->regs[n];
} }
void void
pic_closure_set(pic_state *pic, int n, pic_value v) pic_closure_set(pic_state *pic, int n, pic_value v)
{ {
pic_value self = GET_PROC(pic); struct proc *proc = proc_ptr(pic, GET_PROC(pic));
if (n < 0 || proc_ptr(pic, self)->u.f.localc <= n) { assert(n >= 0);
if (proc->fp == NULL || proc->fp->regc <= n) {
pic_error(pic, "pic_closure_ref: index out of range", 1, pic_int_value(pic, n)); pic_error(pic, "pic_closure_ref: index out of range", 1, pic_int_value(pic, n));
} }
proc_ptr(pic, self)->locals[n] = v; proc->fp->regs[n] = v;
} }
pic_value pic_value
@ -591,7 +601,7 @@ pic_apply(pic_state *pic, pic_value proc, int argc, pic_value *argv)
if (proc->tt == PIC_TYPE_PROC_FUNC) { if (proc->tt == PIC_TYPE_PROC_FUNC) {
/* invoke! */ /* invoke! */
v = proc->u.f.func(pic); v = proc->u.func(pic);
pic->sp[0] = v; pic->sp[0] = v;
pic->sp += pic->ci->retc; pic->sp += pic->ci->retc;
@ -599,7 +609,7 @@ pic_apply(pic_state *pic, pic_value proc, int argc, pic_value *argv)
goto L_RET; goto L_RET;
} }
else { else {
struct irep *irep = proc->u.i.irep; struct irep *irep = proc->u.irep;
int i; int i;
pic_value rest; pic_value rest;
@ -630,7 +640,7 @@ pic_apply(pic_state *pic, pic_value proc, int argc, pic_value *argv)
} }
/* prepare cxt */ /* prepare cxt */
ci->up = proc->u.i.fp; ci->up = proc->fp;
ci->regc = irep->capturec; ci->regc = irep->capturec;
ci->regs = ci->fp + irep->argc + irep->localc; ci->regs = ci->fp + irep->argc + irep->localc;

View File

@ -50,7 +50,7 @@ pic_make_weak(pic_state *pic)
pic_value pic_value
pic_weak_ref(pic_state *pic, pic_value weak, pic_value key) pic_weak_ref(pic_state *pic, pic_value weak, pic_value key)
{ {
khash_t(weak) *h = &weak_ptr(pic, proc_ptr(pic, weak)->locals[0])->hash; khash_t(weak) *h = &weak_ptr(pic, proc_ptr(pic, weak)->fp->regs[0])->hash;
int it; int it;
it = kh_get(weak, h, obj_ptr(pic, key)); it = kh_get(weak, h, obj_ptr(pic, key));
@ -63,7 +63,7 @@ pic_weak_ref(pic_state *pic, pic_value weak, pic_value key)
void void
pic_weak_set(pic_state *pic, pic_value weak, pic_value key, pic_value val) pic_weak_set(pic_state *pic, pic_value weak, pic_value key, pic_value val)
{ {
khash_t(weak) *h = &weak_ptr(pic, proc_ptr(pic, weak)->locals[0])->hash; khash_t(weak) *h = &weak_ptr(pic, proc_ptr(pic, weak)->fp->regs[0])->hash;
int ret; int ret;
int it; int it;
@ -74,7 +74,7 @@ pic_weak_set(pic_state *pic, pic_value weak, pic_value key, pic_value val)
bool bool
pic_weak_has(pic_state *pic, pic_value weak, pic_value key) pic_weak_has(pic_state *pic, pic_value weak, pic_value key)
{ {
khash_t(weak) *h = &weak_ptr(pic, proc_ptr(pic, weak)->locals[0])->hash; khash_t(weak) *h = &weak_ptr(pic, proc_ptr(pic, weak)->fp->regs[0])->hash;
return kh_get(weak, h, obj_ptr(pic, key)) != kh_end(h); return kh_get(weak, h, obj_ptr(pic, key)) != kh_end(h);
} }
@ -82,7 +82,7 @@ pic_weak_has(pic_state *pic, pic_value weak, pic_value key)
void void
pic_weak_del(pic_state *pic, pic_value weak, pic_value key) pic_weak_del(pic_state *pic, pic_value weak, pic_value key)
{ {
khash_t(weak) *h = &weak_ptr(pic, proc_ptr(pic, weak)->locals[0])->hash; khash_t(weak) *h = &weak_ptr(pic, proc_ptr(pic, weak)->fp->regs[0])->hash;
int it; int it;
it = kh_get(weak, h, obj_ptr(pic, key)); it = kh_get(weak, h, obj_ptr(pic, key));