diff --git a/src/builtins/fns.c b/src/builtins/fns.c index ebc416b7..78230342 100644 --- a/src/builtins/fns.c +++ b/src/builtins/fns.c @@ -217,14 +217,15 @@ B find_c2(B t, B w, B x) { if (wr == 0) return C2(eq, w, x); usz wl = IA(w); usz xl = IA(x); - if (wl > xl) { decG(w); decG(x); return emptyIVec(); } - if (wl == 0) { decG(w); decG(x); return taga(arr_shVec(allOnes(xl+1))); } + B r; + if (wl > xl) { r = emptyIVec(); goto dec_ret; } + if (wl == 0) { r = taga(arr_shVec(allOnes(xl+1))); goto dec_ret; } // Compare elements of w to slices of x - SGetU(w) usz rl = xl - wl + 1; // Result length u8* xp = tyany_ptr(x); - u64* rp; B r = m_bitarrv(&rp, rl); + u64* rp; r = m_bitarrv(&rp, rl); CmpASFn eq = CMP_AS_FN(eq, xe); + SGetU(w) CMP_AS_CALL(eq, rp, xp, GetU(w,0), rl); if (wl == 1) goto dec_ret; usz xw = elWidth(xe); @@ -237,16 +238,14 @@ B find_c2(B t, B w, B x) { if (s == 0) break; // Switch to verifying matches individually if (s < rl/16 && rl <= I32_MAX && we != el_bit) { - B ind = C1(slash, incG(r)); - if (TI(ind,elType)!=el_i32) ind = taga(cpyI32Arr(ind)); + B ind = toI32Any(C1(slash, incG(r))); usz ni = IA(ind); i32* ip = i32any_ptr(ind); u8* wp = (u8*)tyany_ptr(w) + i*elWidth(we); - usz eq_idx = EQFN_INDEX(we, xe); - EqFn equalp = eqFns[eq_idx]; u8 ed = eqFnData[eq_idx]; + EqFnObj eqfn = EQFN_GET(we, xe); for (usz ii = 0; ii < ni; ii++) { usz j = ip[ii]; - if (!equalp(wp, xp + (i+j)*xw, wl-i, ed)) bitp_set(rp, j, 0); + if (!EQFN_CALL(eqfn, wp, xp + (i+j)*xw, wl-i)) bitp_set(rp, j, 0); } decG(ind); break; diff --git a/src/builtins/group.c b/src/builtins/group.c index fe0aced4..78e20c01 100644 --- a/src/builtins/group.c +++ b/src/builtins/group.c @@ -134,9 +134,9 @@ static B group_simple(B w, B x, ur xr, usz wia, usz xn, usz* xsh, u8 we) { bitp_set(mp, 0, -1!=o2fG(IGetU(w,0))); B ind = C1(slash, m); - w = C2(select, inc(ind), w); - if (TI(ind,elType)!=el_i32) ind = taga(cpyI32Arr(ind)); - if (TI(w ,elType)!=el_i32) w = taga(cpyI32Arr(w )); + w = C2(select, incG(ind), w); + ind = toI32Any(ind); + w = toI32Any(w); wia = IA(ind); i32* ip = i32any_ptr(ind); @@ -179,7 +179,7 @@ static B group_simple(B w, B x, ur xr, usz wia, usz xn, usz* xsh, u8 we) { x = C2(slash, m, x); xn = *SH(x); neg = 0; } - if (TI(w,elType)!=el_i32) w = taga(cpyI32Arr(w)); + w = toI32Any(w); i32* wp = i32any_ptr(w); for (usz i = 0; i < ria; i++) len[i] = pos[i] = 0; for (usz i = 0; i < xn; i++) len[wp[i]]++; // overallocation makes this safe after n<-1 check diff --git a/src/builtins/md1.c b/src/builtins/md1.c index fdfd4d22..bf43fd5f 100644 --- a/src/builtins/md1.c +++ b/src/builtins/md1.c @@ -305,10 +305,9 @@ static NOINLINE B match_cells(bool ne, B w, B x, ur wr, ur xr, usz len) { CMP_AA_CALL(cmp, rp, wp, xp, len); } else { if (we==el_bit || xe==el_bit) return bi_N; - usz eq_idx = EQFN_INDEX(we, xe); - EqFn equalp = eqFns[eq_idx]; u8 ed = eqFnData[eq_idx]; + EqFnObj eqfn = EQFN_GET(we, xe); for (usz i = 0; i < len; i++) { - bitp_set(rp, i, ne^equalp(wp, xp, csz, ed)); + bitp_set(rp, i, ne^EQFN_CALL(eqfn, wp, xp, csz)); wp += ww; xp += xw; } } diff --git a/src/utils/calls.h b/src/utils/calls.h index 360a9c9c..2caf5320 100644 --- a/src/utils/calls.h +++ b/src/utils/calls.h @@ -40,5 +40,8 @@ typedef bool (*EqFn)(void* a, void* b, u64 l, u64 data); extern EqFn eqFns[]; extern u8 eqFnData[]; #define EQFN_INDEX(W_ELT, X_ELT) ((W_ELT)*8 + (X_ELT)) +typedef struct { EqFn fn; u8 data; } EqFnObj; +#define EQFN_GET(W_ELT, X_ELT) ({ u8 eqfn_i_ = EQFN_INDEX(W_ELT, X_ELT); (EqFnObj){.fn=eqFns[eqfn_i_], .data=eqFnData[eqfn_i_]}; }) +#define EQFN_CALL(FN, W, X, L) (FN).fn(W, X, L, (FN).data) void bit_negatePtr(u64* rp, u64* xp, usz count); // count is number of u64-s