From 69cdedc79f5bf7544acfc2512047b06e0d2d31f6 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Sun, 9 Apr 2017 19:42:03 +0900 Subject: [PATCH] don't use zero length arrray field for struct proc --- lib/gc.c | 11 +++++------ lib/object.h | 12 +++--------- lib/proc.c | 46 ++++++++++++++++++++++++++++------------------ lib/weak.c | 8 ++++---- 4 files changed, 40 insertions(+), 37 deletions(-) diff --git a/lib/gc.c b/lib/gc.c index d7023750..742fdc13 100644 --- a/lib/gc.c +++ b/lib/gc.c @@ -342,17 +342,16 @@ gc_mark_object(pic_state *pic, struct object *obj) break; } case PIC_TYPE_PROC_FUNC: { - int i; - for (i = 0; i < obj->u.proc.u.f.localc; ++i) { - gc_mark(pic, obj->u.proc.locals[i]); + if (obj->u.proc.fp) { + LOOP(obj->u.proc.fp); } break; } case PIC_TYPE_PROC_IREP: { - if (obj->u.proc.u.i.fp) { - gc_mark_object(pic, (struct object *)obj->u.proc.u.i.fp); + if (obj->u.proc.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; } case PIC_TYPE_IREP: { diff --git a/lib/object.h b/lib/object.h index 52832797..da8f7f4e 100644 --- a/lib/object.h +++ b/lib/object.h @@ -107,16 +107,10 @@ struct frame { struct proc { OBJECT_HEADER union { - struct { - pic_func_t func; - int localc; - } f; - struct { - struct irep *irep; - struct frame *fp; - } i; + pic_func_t func; + struct irep *irep; } u; - pic_value locals[1]; + struct frame *fp; }; enum { diff --git a/lib/proc.c b/lib/proc.c index 25127a0a..5d4e2467 100644 --- a/lib/proc.c +++ b/lib/proc.c @@ -35,14 +35,22 @@ pic_value pic_make_proc_func(pic_state *pic, pic_func_t func, int n, pic_value *env) { 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); - proc->u.f.func = func; - proc->u.f.localc = n; - for (i = 0; i < n; ++i) { - proc->locals[i] = env[i]; + if (n > 0) { + int i; + fp = (struct frame *)pic_obj_alloc(pic, offsetof(struct frame, storage) + sizeof(pic_value) * n, PIC_TYPE_FRAME); + fp->regc = n; + 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); } @@ -51,9 +59,9 @@ pic_make_proc_irep(pic_state *pic, struct irep *irep, struct frame *fp) { struct proc *proc; - proc = (struct proc *)pic_obj_alloc(pic, offsetof(struct proc, locals), PIC_TYPE_PROC_IREP); - proc->u.i.irep = irep; - proc->u.i.fp = fp; + proc = (struct proc *)pic_obj_alloc(pic, sizeof(struct proc), PIC_TYPE_PROC_IREP); + proc->u.irep = irep; + proc->fp = fp; return obj_value(pic, proc); } @@ -292,23 +300,25 @@ pic_get_args(pic_state *pic, const char *format, ...) pic_value 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)); } - return proc_ptr(pic, self)->locals[n]; + return proc->fp->regs[n]; } void 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)); } - proc_ptr(pic, self)->locals[n] = v; + proc->fp->regs[n] = v; } 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) { /* invoke! */ - v = proc->u.f.func(pic); + v = proc->u.func(pic); pic->sp[0] = v; 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; } else { - struct irep *irep = proc->u.i.irep; + struct irep *irep = proc->u.irep; int i; pic_value rest; @@ -630,7 +640,7 @@ pic_apply(pic_state *pic, pic_value proc, int argc, pic_value *argv) } /* prepare cxt */ - ci->up = proc->u.i.fp; + ci->up = proc->fp; ci->regc = irep->capturec; ci->regs = ci->fp + irep->argc + irep->localc; diff --git a/lib/weak.c b/lib/weak.c index f8a7a893..a1a4a606 100644 --- a/lib/weak.c +++ b/lib/weak.c @@ -50,7 +50,7 @@ pic_make_weak(pic_state *pic) pic_value 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; 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 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 it; @@ -74,7 +74,7 @@ pic_weak_set(pic_state *pic, pic_value weak, pic_value key, pic_value val) bool 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); } @@ -82,7 +82,7 @@ pic_weak_has(pic_state *pic, pic_value weak, pic_value key) void 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; it = kh_get(weak, h, obj_ptr(pic, key));