diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2012-04-05 09:18:14 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2012-04-05 09:18:14 -0700 |
commit | c162f73f9cfd0bb48675dc11bd56ac359451510b (patch) | |
tree | 5fda9e1835758135d39090ddc8ca79ec1070c5d9 /eval.c | |
parent | 1e5d313bafa78885490b3fa0759ba76436917d9b (diff) | |
download | txr-c162f73f9cfd0bb48675dc11bd56ac359451510b.tar.gz txr-c162f73f9cfd0bb48675dc11bd56ac359451510b.tar.bz2 txr-c162f73f9cfd0bb48675dc11bd56ac359451510b.zip |
The mut macro should only be used for vectors or vector-like objects
which hold direct references to other objects and must be used
each time a mutation takes place.
* eval.c (op_dohash): invocations of mut macro removed.
Comment rewritten.
* lib.c (sort_list): Use set macro for mutating assignment.
Do not invoke mut on sorted list; it won't work anyway, because
it doesn't mean what the code wants it to mean: that the list will be
fully traversed during gc marking.
Diffstat (limited to 'eval.c')
-rw-r--r-- | eval.c | 16 |
1 files changed, 6 insertions, 10 deletions
@@ -1035,17 +1035,13 @@ 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) { + /* These assignments are gc-safe, because keyvar and valvar + are newer objects than existing entries in the hash, + unless the body mutates hash by inserting newer objects, + and also deleting them such that these variables end up + with the only reference. But in that case, those objects + will be noted in the GC's check list. */ *cdr_l(keyvar) = car(cell); *cdr_l(valvar) = cdr(cell); eval_progn(body, new_env, form); |