Skip to content

Commit 0baf340

Browse files
gh-148: Fix SELF.
1 parent b33bb75 commit 0baf340

1 file changed

Lines changed: 15 additions & 13 deletions

File tree

src/value.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -531,16 +531,11 @@ Value* value_tns_get_ptr(Value v, const size_t* idxs, size_t nidxs) {
531531

532532
// Shallow copy semantics: increment refcount for MAP/TNS and return aliasing Value.
533533
Value value_copy(Value v) {
534-
// New semantics: value_copy produces an atomic (de-referenced) copy for
535-
// container types (TNS and MAP): the container object is duplicated so
536-
// mutations to the returned value won't affect the original. Element
537-
// values inside the container remain as aliases (not deep-copied).
538534
Value out = v;
539535
if (v.type == VAL_STR && v.as.s) {
540536
out.as.s = strdup(v.as.s);
541537
} else if (v.type == VAL_TNS && v.as.tns) {
542538
Tensor* t = v.as.tns;
543-
// allocate new tensor structure and copy shape/strides
544539
Tensor* t2 = malloc(sizeof(Tensor));
545540
if (!t2) { fprintf(stderr, "Out of memory\n"); exit(1); }
546541
t2->elem_type = t->elem_type;
@@ -551,8 +546,6 @@ Value value_copy(Value v) {
551546
t2->length = t->length;
552547
t2->data = malloc(sizeof(Value) * t2->length);
553548
for (size_t i = 0; i < t2->length; i++) {
554-
// keep element references (shallow): use value_alias to preserve
555-
// previous element-sharing semantics for nested containers
556549
extern Value value_alias(Value v);
557550
t2->data[i] = value_alias(t->data[i]);
558551
}
@@ -566,20 +559,29 @@ Value value_copy(Value v) {
566559
m2->count = m->count;
567560
m2->capacity = m->count;
568561
m2->items = malloc(sizeof(MapEntry) * (m2->capacity ? m2->capacity : 1));
562+
m2->buckets = NULL;
563+
m2->bucket_count = 0;
564+
m2->refcount = 1;
565+
mtx_init(&m2->lock, 0);
569566
for (size_t i = 0; i < m->count; i++) {
570567
extern Value value_alias(Value v);
571568
m2->items[i].key = value_alias(m->items[i].key);
572-
m2->items[i].value = value_alias(m->items[i].value);
569+
Value orig_val = m->items[i].value;
570+
if (orig_val.type == VAL_MAP && orig_val.as.map == m) {
571+
Value tmp;
572+
tmp.type = VAL_MAP;
573+
tmp.num_base = 2;
574+
tmp.num_base_nan = 0;
575+
tmp.as.map = m2;
576+
m2->items[i].value = value_alias(tmp);
577+
} else {
578+
m2->items[i].value = value_alias(m->items[i].value);
579+
}
573580
m2->items[i].next_hash = -1;
574581
}
575-
m2->buckets = NULL;
576-
m2->bucket_count = 0;
577582
if (m2->count > 0) map_rehash(m2, map_recommended_bucket_count(m2->count));
578-
m2->refcount = 1;
579-
mtx_init(&m2->lock, 0);
580583
out.as.map = m2;
581584
} else if (v.type == VAL_THR && v.as.thr) {
582-
// threads remain shared handles
583585
Thr* th = v.as.thr;
584586
mtx_lock(&th->state_lock);
585587
th->refcount++;

0 commit comments

Comments
 (0)