summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-04-03 08:40:31 -0700
committerKaz Kylheku <kaz@kylheku.com>2012-04-03 08:40:31 -0700
commit06ced4e18fd69399e7419a59dbe477e9a92c23e1 (patch)
treebf267f92a132acdd5d15df0b0ef7e2bb29c27fd6 /eval.c
parent6c4da3e5e1cb02f4d4e522626579cbded546059a (diff)
downloadtxr-06ced4e18fd69399e7419a59dbe477e9a92c23e1.tar.gz
txr-06ced4e18fd69399e7419a59dbe477e9a92c23e1.tar.bz2
txr-06ced4e18fd69399e7419a59dbe477e9a92c23e1.zip
* configure: Support a gen-gc configuration variable which
causes CONFIG_GEN_GC to be defined as 1 in config.h. * eval.c (op_defvar, dwim_loc, op_modplace, transform_op): Handle mutating assignments via set macro. (op_dohash): Inform gc about mutated variables. TODO here. * filter.c (trie_add, trie_compress): Handle mutating assignments via set macro. * gc.c (BACKPTR_VEC_SIZE, FULL_GC_INTERVAL): New preprocessor symbols. (backptr, backptr_idx, partial_gc_count, full): New static variables. (make_obj): Initialize generation to zero. (gc): Added logic for deciding between full and partial gc. (gc_set, gc_mutated): New functions. * gc.h (gc_set, gc_mutated): Declared. * hash.c (hash_mark): Changed useless use of vecref_l to vecref. (gethash_f): Use set when assigning through *found since it is a possible mutation. * lib.c (car_l, cdr_l, vecref_l): Got rid of loc macro uses. Using the value properly is going to be the caller's responsibility. (push): push may be a mutation, so use set. (intern): Uset set to mutate a hash entry. (acons_new_l, aconsq_new_l): Use set when replacing *list. * lib.h (PTR_BIT): New preprocessor symbol. (obj_common): New macro for defining common object fields. type_t is split into two bitfields, half a pointer wide, allowing for generation to be represented. (struct any, struct cons, struct string, struct sym, struct package, struct func, struct vec, struct lazy_cons, struct cobj, struct env, struct bignum, struct flonum): Use obj_common macro to defined common fields. (loc): Macro removed. (set, mut): Macros conditionally defined for real functionality. (list_collect, list_collect_nconc, list_collect_append): Replace mutating operations with set. * match.c (dest_set, v_cat, v_output, v_filter): Replace mutating operations with set. * stream.c (string_in_get_line, string_in_get_char, strlist_out_put_string, strlist_out_put_char): Replace mutating operations with set. * unwind.c (uw_register_subtype): Replace mutating operation with set.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/eval.c b/eval.c
index ff348b8d..7ff81ae4 100644
--- a/eval.c
+++ b/eval.c
@@ -701,7 +701,7 @@ static val op_defvar(val form, val env)
val existing = gethash(top_vb, sym);
if (existing)
- *cdr_l(existing) = value;
+ set(*cdr_l(existing), value);
else
sethash(top_vb, sym, cons(sym, value));
}
@@ -895,7 +895,7 @@ static val *dwim_loc(val form, val env, val op, val newform, val *retval)
loc = gethash_l(obj, first(args), &new_p);
if (new_p)
- *loc = second(args);
+ set(*loc, second(args));
return loc;
}
}
@@ -950,7 +950,7 @@ static val op_modplace(val form, val env)
}
loc = gethash_l(hash, key, &new_p);
if (new_p)
- *loc = eval(fourth(place), env, form);
+ set(*loc, eval(fourth(place), env, form));
} else if (sym == car_s) {
val cons = eval(second(place), env, form);
loc = car_l(cons);
@@ -975,13 +975,13 @@ static val op_modplace(val form, val env)
if (op == set_s) {
if (!third_arg_p)
eval_error(form, lit("~a: missing argument"), op, place, nao);
- return *loc = eval(newform, env, form);
+ return set(*loc, eval(newform, env, form));
} else if (op == inc_s) {
val inc = or2(eval(newform, env, form), one);
- return *loc = plus(*loc, inc);
+ return set(*loc, plus(*loc, inc));
} else if (op == dec_s) {
val inc = or2(eval(newform, env, form), one);
- return *loc = minus(*loc, inc);
+ return set(*loc, minus(*loc, inc));
} else if (op == push_s) {
return push(newval, loc);
} else if (op == pop_s) {
@@ -1035,6 +1035,16 @@ static val op_dohash(val form, val env)
uw_block_begin (nil, result);
+ /*
+ * Avoid issuing set() operations in the loop;
+ * just tell GC that these variables are being mutated.
+ * TODO: This is not enough since gc can take place while we execute this
+ * loop. What we need is to conditionally re-establish this.
+ * GC needs to provide a way to let us know "has GC happened since ..."
+ */
+ mut(keyvar);
+ mut(valvar);
+
while ((cell = hash_next(&iter)) != nil) {
*cdr_l(keyvar) = car(cell);
*cdr_l(valvar) = cdr(cell);
@@ -1501,7 +1511,7 @@ static val transform_op(val forms, val syms, val rg)
val newsyms = syms;
val new_p;
val *place = acons_new_l(vararg, &new_p, &newsyms);
- val sym = if3(new_p, *place = gensym(prefix), *place);
+ val sym = if3(new_p, set(*place, gensym(prefix)), *place);
cons_bind (outsyms, outforms, transform_op(re, newsyms, rg));
return cons(outsyms, rlcp(cons(sym, outforms), outforms));
} else if (eq(vararg, rest_s)) {