diff --git a/src/builtins/sfns.c b/src/builtins/sfns.c index 9ebf3258..76e0470b 100644 --- a/src/builtins/sfns.c +++ b/src/builtins/sfns.c @@ -923,27 +923,26 @@ B join_c2(B t, B w, B x) { } if (c-wr > 1 || c-xr > 1) thrF("∾: Argument ranks must differ by 1 or less (%i≡=𝕨, %i≡=𝕩)", wr, xr); - bool reusedW; - B r = arr_join_inline(w, x, false, &reusedW); + bool usedW; + usz wia0 = IA(w); + B r = arr_join_inline(w, x, false, &usedW); if (c==1) { if (RNK(r)==0) SRNK(r,1); } else { assert(c>1); ur rnk0 = RNK(r); ShArr* sh0 = shObj(r); - usz wia; usz* wsh; - if (wr==1 && reusedW) { - wia = IA(w)-IA(x); - wsh = &wia; + if (wr==1 && usedW) { + wsh = &wia0; } else { wsh = SH(w); // when wr>1, shape object won't be disturbed by arr_join_inline } usz* xsh = SH(x); - SRNK(r, 0); // otherwise shape allocation failing may break things + SRNK(r, 0); // otherwise shape allocation failing may break things; leaves shape owned only here usz* rsh = arr_shAlloc(a(r), c); #if PRINT_JOIN_REUSE - printf(reusedW? "reuse:1;" : "reuse:0;"); + printf(usedW? "reuse:1;" : "reuse:0;"); #endif for (i32 i = 1; i < c; i++) { usz s = xsh[i+xr-c]; @@ -961,7 +960,7 @@ B join_c2(B t, B w, B x) { } decG(x); - if (!reusedW) decG(w); + if (!usedW) decG(w); return qWithFill(r, f); } diff --git a/src/utils/mut.h b/src/utils/mut.h index edd15527..4db3d3b5 100644 --- a/src/utils/mut.h +++ b/src/utils/mut.h @@ -156,9 +156,11 @@ typedef struct { B w2; void* rp; } JoinFillslice; JoinFillslice fillslice_getJoin(B w, usz ria); // either returns NULL in rp, or consumes w // consume==true: consumes w,x and expects both args to be vectors -// consume==false: doesn't consume x, and decrements refcount of w iif *reusedW (won't free because the result will be w); result has arbitrary but valid shape +// consume==false: doesn't consume x, and +// *usedW==true: consumes w, returns w or its backing array; if RNK(w)>1, result has the same shape as w, i.e. not updated +// *usedW==false: doesn't consume w; result has vector shape // returns possibly incorrect fills if arguments aren't equal class typed arrays -FORCE_INLINE B arr_join_inline(B w, B x, bool consume, bool* reusedW) { +FORCE_INLINE B arr_join_inline(B w, B x, bool consume, bool* usedW) { assert(isArr(w) && isArr(x)); usz wia = IA(w); usz xia = IA(x); @@ -193,13 +195,13 @@ FORCE_INLINE B arr_join_inline(B w, B x, bool consume, bool* reusedW) { mut_copyG(r, 0, w, 0, wia); mut_copyG(r, wia, x, 0, xia); if (consume) { decG(x); decG(w); } - *reusedW = false; + *usedW = false; return mut_fv(r); yes: COPY_TO(rp, we, wia, x, 0, xia); if (consume) decG(x); - *reusedW = true; + *usedW = true; a(w)->ia = ria; return FL_KEEP(w,fl_squoze); // keeping fl_squoze as appending items can't make the largest item smaller } diff --git a/test/cases/prims.bqn b/test/cases/prims.bqn index aadbf5f3..5d4fc729 100644 --- a/test/cases/prims.bqn +++ b/test/cases/prims.bqn @@ -181,6 +181,7 @@ w←1‿1⥊1 ⋄ x←2⥊1 ⋄ w‿x <¨↩ ⋄ {! (∾⟨•Repr𝕩,": Expe # ≍𝕩 !"≍: Result rank too large (255≡=𝕩)" % ≍⍟256 1 +%USE tvar ⋄ 1‿2‿3‿4‿5‿64 {c𝕊e: {!∘≡¨⟜⊏ ⥊ ∾_tvar´ 𝕩}¨ ⟨4‿c, c⟩ ⋈⌜○({𝕩⥊