summaryrefslogtreecommitdiffstats
path: root/vm.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-03-22 20:49:34 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-03-22 20:49:34 -0700
commit07bc53f2f5736ee0ecc5f152432446e7b4a200f8 (patch)
tree503d5d39ec4d84a690fa1aa9e8ea7ac7ed4b6c2f /vm.c
parent7b6473d3895c94397206913937e93b1aad48952e (diff)
downloadtxr-07bc53f2f5736ee0ecc5f152432446e7b4a200f8.tar.gz
txr-07bc53f2f5736ee0ecc5f152432446e7b4a200f8.tar.bz2
txr-07bc53f2f5736ee0ecc5f152432446e7b4a200f8.zip
vm: bugfix: cannot access vec during gc.
Let's have a field in struct vm_desc that keeps track of the ftab size. The problem is when we do length_vec(vd->funvec) in vm_desc_mark, we are in the middle of garbage collection. The object's tag has a reachable bit which blows up the type check. * vm.c (struct vm_desc): New member, ftsz. (vm_make_desc): Store the length of the function table into ftsz. (vm_desc_mark): Use the stored length as the loop bound; do not access vd->funvec.
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/vm.c b/vm.c
index b8eb2fed..913fb60c 100644
--- a/vm.c
+++ b/vm.c
@@ -65,6 +65,7 @@ struct vm_desc {
int nlvl;
int nreg;
int frsz;
+ cnum ftsz;
val bytecode;
val datavec;
val funvec;
@@ -128,12 +129,12 @@ val vm_make_desc(val nlevels, val nregs, val bytecode,
{
mem_t *code = buf_get(bytecode, self);
val dvl = length_vec(datavec);
- cnum fvl = c_num(length_vec(funvec));
+ cnum ftsz = c_num(length_vec(funvec));
loc data_loc = if3(dvl != zero, vecref_l(datavec, zero), nulloc);
struct vm_desc *vd = coerce(struct vm_desc *, chk_malloc(sizeof *vd));
- struct vm_ftent *ftab = if3(fvl != 0,
+ struct vm_ftent *ftab = if3(ftsz != 0,
coerce(struct vm_ftent *,
- chk_calloc(fvl, sizeof *ftab)), 0);
+ chk_calloc(ftsz, sizeof *ftab)), 0);
cnum i;
val desc;
@@ -142,6 +143,7 @@ val vm_make_desc(val nlevels, val nregs, val bytecode,
vd->code = coerce(vm_word_t *, code);
vd->data = valptr(data_loc);
vd->ftab = ftab;
+ vd->ftsz = ftsz;
vd->bytecode = nil;
vd->datavec = nil;
@@ -157,7 +159,7 @@ val vm_make_desc(val nlevels, val nregs, val bytecode,
vd->funvec = funvec;
vd->self = desc;
- for (i = 0; i < fvl; i++) {
+ for (i = 0; i < ftsz; i++) {
struct vm_ftent *fe = &ftab[i];
fe->fb = lookup_fun(nil, vecref(funvec, num_fast(i)));
fe->fbloc = if3(fe->fb, cdr_l(fe->fb), nulloc);
@@ -195,13 +197,13 @@ static void vm_desc_destroy(val obj)
static void vm_desc_mark(val obj)
{
struct vm_desc *vd = coerce(struct vm_desc *, obj->co.handle);
- cnum i, fvl = c_num(length_vec(vd->funvec));
+ cnum i, ftsz = vd->ftsz;
gc_mark(vd->bytecode);
gc_mark(vd->datavec);
gc_mark(vd->funvec);
- for (i = 0; i < fvl; i++)
+ for (i = 0; i < ftsz; i++)
gc_mark(vd->ftab[i].fb);
}