summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2024-06-18 03:34:35 -0700
committerKaz Kylheku <kaz@kylheku.com>2024-06-18 03:34:35 -0700
commitdd839dc6ed1abf51645f5e69572ab9e106272c33 (patch)
tree1c5187356f4b8c0f728199bf55399a025d1a118a
parent213d60b7200b7c1a1085fb239becd8e2f977b6e3 (diff)
downloadtxr-dd839dc6ed1abf51645f5e69572ab9e106272c33.tar.gz
txr-dd839dc6ed1abf51645f5e69572ab9e106272c33.tar.bz2
txr-dd839dc6ed1abf51645f5e69572ab9e106272c33.zip
bugfix: several seq_iter kinds need clone operation.
Several seq_iter_t kinds of objects cannot be correctly bitwise copied, because they point to an iterator object that cannot be shared. * lib.c (seq_iter_clone_op): New static function. (si_hash_ops, si_tree_ops, si_oop_ops, si_fast_oop_ops): Use seq_iter_clone_op, which uses the copy function to duplicate it->ui.iter after doing a bitwise copy of the structure. * lib.h (seq_iter_ops_init_full): New macro.
-rw-r--r--lib.c26
-rw-r--r--lib.h2
2 files changed, 20 insertions, 8 deletions
diff --git a/lib.c b/lib.c
index 8bec2c90..ff7f0ed2 100644
--- a/lib.c
+++ b/lib.c
@@ -926,6 +926,12 @@ void seq_iter_mark_op(struct seq_iter *it)
gc_mark(it->ui.iter);
}
+static void seq_iter_clone_op(const struct seq_iter *sit, struct seq_iter *dit)
+{
+ *dit = *sit;
+ dit->ui.iter = copy(sit->ui.iter);
+}
+
struct seq_iter_ops si_null_ops = seq_iter_ops_init_nomark(seq_iter_get_nil,
seq_iter_peek_nil);
@@ -935,11 +941,13 @@ struct seq_iter_ops si_list_ops = seq_iter_ops_init(seq_iter_get_list,
struct seq_iter_ops si_vec_ops = seq_iter_ops_init_nomark(seq_iter_get_vec,
seq_iter_peek_vec);
-struct seq_iter_ops si_hash_ops = seq_iter_ops_init(seq_iter_get_hash,
- seq_iter_peek_hash);
+struct seq_iter_ops si_hash_ops = seq_iter_ops_init_clone(seq_iter_get_hash,
+ seq_iter_peek_hash,
+ seq_iter_clone_op);
-struct seq_iter_ops si_tree_ops = seq_iter_ops_init(seq_iter_get_tree,
- seq_iter_peek_tree);
+struct seq_iter_ops si_tree_ops = seq_iter_ops_init_clone(seq_iter_get_tree,
+ seq_iter_peek_tree,
+ seq_iter_clone_op);
struct seq_iter_ops si_range_cnum_ops =
seq_iter_ops_init_nomark(seq_iter_get_range_cnum,
@@ -979,14 +987,16 @@ struct seq_iter_ops si_chr_ops = seq_iter_ops_init_nomark(seq_iter_get_chr,
struct seq_iter_ops si_num_ops = seq_iter_ops_init(seq_iter_get_num,
seq_iter_peek_num);
-struct seq_iter_ops si_oop_ops = seq_iter_ops_init_mark(seq_iter_get_oop,
+struct seq_iter_ops si_oop_ops = seq_iter_ops_init_full(seq_iter_get_oop,
seq_iter_peek_oop,
- seq_iter_mark_oop);
+ seq_iter_mark_oop,
+ seq_iter_clone_op);
struct seq_iter_ops si_fast_oop_ops =
- seq_iter_ops_init_mark(seq_iter_get_fast_oop,
+ seq_iter_ops_init_full(seq_iter_get_fast_oop,
seq_iter_peek_fast_oop,
- seq_iter_mark_oop);
+ seq_iter_mark_oop,
+ seq_iter_clone_op);
struct seq_iter_ops si_cat_ops = seq_iter_ops_init_mark(seq_iter_get_cat,
seq_iter_peek_cat,
diff --git a/lib.h b/lib.h
index 18037392..0c300e8a 100644
--- a/lib.h
+++ b/lib.h
@@ -474,6 +474,8 @@ struct seq_iter_ops {
#define seq_iter_ops_init_mark(get, peek, mark) { get, peek, mark, 0 }
#define seq_iter_ops_init_clone(get, peek, clone) \
{ get, peek, seq_iter_mark_op, clone }
+#define seq_iter_ops_init_full(get, peek, mark, clone) \
+ { get, peek, mark, clone }
typedef struct seq_build {
val obj;