diff --git a/src/utils/mut.c b/src/utils/mut.c index cd825af7..24199a8e 100644 --- a/src/utils/mut.c +++ b/src/utils/mut.c @@ -99,6 +99,37 @@ B vec_join(B w, B x) { } +NOINLINE JoinFillslice fillslice_getJoin(B w, B x, usz ria) { + usz wia = IA(w); + assert(TY(w)==t_fillslice); + FillSlice* s = c(FillSlice,w); + if (!fillEqualsGetFill(s->fill, x)) goto no; + Arr* p = s->p; + + if (p->refc!=1) goto no; + if (p->type!=t_fillarr && p->type!=t_harr) goto no; + void* rp = p->type==t_fillarr? fillarr_ptr(p) : ((HArr*)p)->a; + if (rp != s->a) goto no; + if (PIA(p)!=wia) goto no; + usz wsz = mm_sizeUsable((Value*)p); + if (!(p->type==t_fillarr? fsizeof(FillArr,a,B,ria)fns->m_##N##G(m, __VA_ARGS__); #define CHK_S(REQ,X,N,...) CHK(REQ, el_or(m->fns->elType, selfElType(X)), N, __VA_ARGS__) diff --git a/src/utils/mut.h b/src/utils/mut.h index 5c77fca6..05de11c2 100644 --- a/src/utils/mut.h +++ b/src/utils/mut.h @@ -152,9 +152,13 @@ SHOULD_INLINE void bit_cpy(u64* r, usz rs, u64* x, usz xs, usz l) { +typedef struct { B w2; void* rp; } JoinFillslice; +JoinFillslice fillslice_getJoin(B w, B x, usz ria); // either returns NULL in rp, or consumes w + // if `consume==true`, consumes w,x and expects both args to be vectors // else, doesn't consume x, and decrements refcount of w iif *reusedW (won't free because the result will be w) FORCE_INLINE B arr_join_inline(B w, B x, bool consume, bool* reusedW) { + assert(isArr(w) && isArr(x)); usz wia = IA(w); usz xia = IA(x); u64 ria = wia+xia; @@ -162,7 +166,6 @@ FORCE_INLINE B arr_join_inline(B w, B x, bool consume, bool* reusedW) { u64 wsz = mm_sizeUsable(v(w)); u8 wt = TY(w); u8 we = TI(w, elType); - // TODO f64∾i32, i32∾i8, c32∾c8 etc void* rp = tyany_ptr(w); switch (wt) { case t_bitarr: if (BITARR_SZ( ria)=el_c8) goto yes; break; case t_c32arr: if (TYARR_SZ(C32,ria)=el_c8) goto yes; break; - case t_harr: if (fsizeof(HArr,a,B,ria)fill, x)) goto yes; } break; + case t_harr: if (fsizeof(HArr, a,B,ria)