summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-04-01 19:47:56 -0700
committerKaz Kylheku <kaz@kylheku.com>2012-04-01 19:47:56 -0700
commit87ed8a692c059f1e81f8deeea3b4f727044a45fa (patch)
treeb8f86e21ef965c2dbb0c3f8e8621760a62cf1943
parent34d0567bce45cc89fc6f476353b00b2649bcce4d (diff)
downloadtxr-87ed8a692c059f1e81f8deeea3b4f727044a45fa.tar.gz
txr-87ed8a692c059f1e81f8deeea3b4f727044a45fa.tar.bz2
txr-87ed8a692c059f1e81f8deeea3b4f727044a45fa.zip
Start of ground-work for ephemeral GC. We must add some abstraction
to places where we potentially assign a reference to a younger object inside a field located in an older object (chronological backreference) and also where we take the address of an object field, making it possible that the user of the address will do so. This patch does not take care of vectors. No, this is not an April Fool's joke. * eval.c (env_fbind, env_vbind, env_replace_vbind, lookup_var, lookup_sym_lisp1): Use set macro instead of assignment. * hash.c (hash_grow, set_hash_userdata, hash_next): Use set macro instead of assignment. * lib.c (rplaca, rplacd, string_extend, length_str, replace_str, rehome_sym, lazy_stream_func, lazy_str, lazy_str_force, lazy_str_force_upto, obj_init): Use set macro instead of assignment. (car_l, cdr_l): Use loc instead of address-of operator. * lib.h (set, loc): New macros.
-rw-r--r--ChangeLog26
-rw-r--r--eval.c10
-rw-r--r--hash.c6
-rw-r--r--lib.c44
-rw-r--r--lib.h3
5 files changed, 59 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index 8ef53851..e063d450 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+2012-04-01 Kaz Kylheku <kaz@kylheku.com>
+
+ Start of ground-work for ephemeral GC. We must add some abstraction
+ to places where we potentially assign a reference to a younger object
+ inside a field located in an older object (chronological
+ backreference) and also where we take the address of an object
+ field, making it possible that the user of the address will do so.
+
+ This patch does not take care of vectors.
+
+ No, this is not an April Fool's joke.
+
+ * eval.c (env_fbind, env_vbind, env_replace_vbind, lookup_var,
+ lookup_sym_lisp1): Use set macro instead of assignment.
+
+ * hash.c (hash_grow, set_hash_userdata, hash_next):
+ Use set macro instead of assignment.
+
+ * lib.c (rplaca, rplacd, string_extend, length_str, replace_str,
+ rehome_sym, lazy_stream_func, lazy_str, lazy_str_force,
+ lazy_str_force_upto, obj_init): Use set macro instead of assignment.
+
+ (car_l, cdr_l): Use loc instead of address-of operator.
+
+ * lib.h (set, loc): New macros.
+
2012-03-31 Kaz Kylheku <kaz@kylheku.com>
* hash.c (last_equal_key, last_equal_hash): New static variables.
diff --git a/eval.c b/eval.c
index b79b88f1..ff348b8d 100644
--- a/eval.c
+++ b/eval.c
@@ -82,21 +82,21 @@ val make_env(val vbindings, val fbindings, val up_env)
val env_fbind(val env, val sym, val fun)
{
type_check(env, ENV);
- env->e.fbindings = acons_new(sym, fun, env->e.fbindings);
+ set(env->e.fbindings, acons_new(sym, fun, env->e.fbindings));
return sym;
}
val env_vbind(val env, val sym, val obj)
{
type_check(env, ENV);
- env->e.vbindings = acons_new(sym, obj, env->e.vbindings);
+ set(env->e.vbindings, acons_new(sym, obj, env->e.vbindings));
return sym;
}
static void env_replace_vbind(val env, val bindings)
{
type_check(env, ENV);
- env->e.vbindings = bindings;
+ set(env->e.vbindings, bindings);
}
noreturn static val eval_error(val form, val fmt, ...)
@@ -120,7 +120,7 @@ val lookup_var(val env, val sym)
val bind = gethash(top_vb, sym);
if (cobjp(bind)) {
struct c_var *cv = (struct c_var *) cptr_get(bind);
- cv->bind->c.cdr = *cv->loc;
+ set(cv->bind->c.cdr, *cv->loc);
return cv->bind;
}
return bind;
@@ -183,7 +183,7 @@ static val lookup_sym_lisp1(val env, val sym)
val bind = gethash(top_vb, sym);
if (cobjp(bind)) {
struct c_var *cv = (struct c_var *) cptr_get(bind);
- cv->bind->c.cdr = *cv->loc;
+ set(cv->bind->c.cdr, *cv->loc);
return cv->bind;
}
return or2(bind, gethash(top_fb, sym));
diff --git a/hash.c b/hash.c
index 78052119..510339b8 100644
--- a/hash.c
+++ b/hash.c
@@ -346,7 +346,7 @@ static void hash_grow(struct hash *h)
}
h->modulus = new_modulus;
- h->table = new_table;
+ set(h->table, new_table);
}
val make_hash(val weak_keys, val weak_vals, val equal_based)
@@ -451,7 +451,7 @@ val set_hash_userdata(val hash, val data)
{
struct hash *h = (struct hash *) cobj_handle(hash, hash_s);
val olddata = h->userdata;
- h->userdata = data;
+ set(h->userdata, data);
return olddata;
}
@@ -502,7 +502,7 @@ val hash_next(val *iter)
*iter = nil;
return nil;
}
- hi->cons = vecref(h->table, num(hi->chain));
+ set(hi->cons, vecref(h->table, num(hi->chain)));
}
return car(hi->cons);
}
diff --git a/lib.c b/lib.c
index 186a4a8c..6703c024 100644
--- a/lib.c
+++ b/lib.c
@@ -224,9 +224,9 @@ val rplaca(val cons, val new_car)
{
switch (type(cons)) {
case CONS:
- return cons->c.car = new_car;
+ return set(cons->c.car, new_car);
case LCONS:
- return cons->lc.car = new_car;
+ return set(cons->lc.car, new_car);
default:
type_mismatch(lit("~s is not a cons"), cons, nao);
}
@@ -237,9 +237,9 @@ val rplacd(val cons, val new_cdr)
{
switch (type(cons)) {
case CONS:
- return cons->c.cdr = new_cdr;
+ return set(cons->c.cdr, new_cdr);
case LCONS:
- return cons->lc.cdr = new_cdr;
+ return set(cons->lc.cdr, new_cdr);
default:
type_mismatch(lit("~s is not a cons"), cons, nao);
}
@@ -249,13 +249,13 @@ val *car_l(val cons)
{
switch (type(cons)) {
case CONS:
- return &cons->c.car;
+ return loc(cons->c.car);
case LCONS:
if (cons->lc.func) {
funcall1(cons->lc.func, cons);
cons->lc.func = nil;
}
- return &cons->lc.car;
+ return loc(cons->lc.car);
default:
type_mismatch(lit("~s is not a cons"), cons, nao);
}
@@ -265,13 +265,13 @@ val *cdr_l(val cons)
{
switch (type(cons)) {
case CONS:
- return &cons->c.cdr;
+ return loc(cons->c.cdr);
case LCONS:
if (cons->lc.func) {
funcall1(cons->lc.func, cons);
cons->lc.func = nil;
}
- return &cons->lc.cdr;
+ return loc(cons->lc.cdr);
default:
type_mismatch(lit("~s is not a cons"), cons, nao);
}
@@ -1431,8 +1431,8 @@ val string_extend(val str, val tail)
str->st.str = (wchar_t *) chk_realloc((mem_t *) str->st.str,
alloc * sizeof *str->st.str);
- str->st.alloc = num(alloc);
- str->st.len = plus(str->st.len, needed);
+ set(str->st.alloc, num(alloc));
+ set(str->st.len, plus(str->st.len, needed));
if (stringp(tail)) {
wmemcpy(str->st.str + len, c_str(tail), c_num(needed) + 1);
@@ -1475,8 +1475,8 @@ val length_str(val str)
}
if (!str->st.len) {
- str->st.len = num(wcslen(str->st.str));
- str->st.alloc = plus(str->st.len, one);
+ set(str->st.len, num(wcslen(str->st.str)));
+ set(str->st.alloc, plus(str->st.len, one));
}
return str->st.len;
}
@@ -1741,7 +1741,7 @@ val replace_str(val str_in, val items, val from, val to)
wmemmove(str_in->st.str + t - c_num(len_diff),
str_in->st.str + t, (l - t) + 1);
- str_in->st.len = minus(len, len_diff);
+ set(str_in->st.len, minus(len, len_diff));
to = plus(from, len_it);
} else if (lt(len_rep, len_it)) {
val len_diff = minus(len_it, len_rep);
@@ -2262,7 +2262,7 @@ static val rehome_sym(val sym, val package)
if (sym->s.package)
remhash(sym->s.package->pk.symhash, symbol_name(sym));
- sym->s.package = package;
+ set(sym->s.package, package);
sethash(package->pk.symhash, symbol_name(sym), sym);
return sym;
}
@@ -3316,8 +3316,8 @@ static val lazy_stream_func(val env, val lcons)
val next = cdr(env) ? pop(cdr_l(env)) : get_line(stream);
val ahead = get_line(stream);
- lcons->lc.car = next;
- lcons->lc.cdr = if2(ahead, make_lazy_cons(lcons->lc.func));
+ set(lcons->lc.car, next);
+ set(lcons->lc.cdr, if2(ahead, make_lazy_cons(lcons->lc.func)));
lcons->lc.func = nil;
if (!next || !ahead)
@@ -3357,12 +3357,12 @@ val lazy_str(val lst, val term, val limit)
obj->ls.prefix = null_string;
obj->ls.list = nil;
} else {
- obj->ls.prefix = cat_str(list(first(lst), term, nao), nil);
- obj->ls.list = rest(lst);
+ set(obj->ls.prefix, cat_str(list(first(lst), term, nao), nil));
+ set(obj->ls.list, rest(lst));
limit = if2(limit, minus(limit, one));
}
- obj->ls.opts = cons(term, limit);
+ set(obj->ls.opts, cons(term, limit));
return obj;
}
@@ -3376,7 +3376,7 @@ val lazy_str_force(val lstr)
while ((!lim || gt(lim, zero)) && lstr->ls.list) {
val next = pop(&lstr->ls.list);
val term = car(lstr->ls.opts);
- lstr->ls.prefix = cat_str(list(lstr->ls.prefix, next, term, nao), nil);
+ set(lstr->ls.prefix, cat_str(list(lstr->ls.prefix, next, term, nao), nil));
if (lim)
lim = minus(lim, one);
}
@@ -3399,7 +3399,7 @@ val lazy_str_force_upto(val lstr, val index)
{
val next = pop(&lstr->ls.list);
val term = car(lstr->ls.opts);
- lstr->ls.prefix = cat_str(list(lstr->ls.prefix, next, term, nao), nil);
+ set(lstr->ls.prefix, cat_str(list(lstr->ls.prefix, next, term, nao), nil));
if (lim)
lim = minus(lim, one);
}
@@ -4048,7 +4048,7 @@ static void obj_init(void)
/* t can't be interned, because gethash_l needs t in order to do its job. */
t = *gethash_l(user_package->pk.symhash, lit("t"), 0) = make_sym(lit("t"));
- t->s.package = user_package;
+ set(t->s.package, user_package);
null = intern(lit("null"), user_package);
cons_s = intern(lit("cons"), user_package);
diff --git a/lib.h b/lib.h
index 8f4fae65..3e2db2a4 100644
--- a/lib.h
+++ b/lib.h
@@ -217,6 +217,9 @@ union obj {
struct flonum fl;
};
+#define set(place, val) ((place) = (val))
+#define loc(place) (&(place))
+
INLINE cnum tag(val obj) { return ((cnum) obj) & TAG_MASK; }
INLINE int is_ptr(val obj) { return obj && tag(obj) == TAG_PTR; }
INLINE int is_num(val obj) { return tag(obj) == TAG_NUM; }