diff --git a/src/builtins/cells.c b/src/builtins/cells.c index 190d7ee5..c61e8759 100644 --- a/src/builtins/cells.c +++ b/src/builtins/cells.c @@ -33,7 +33,7 @@ B takedrop_highrank(bool take, B w, B x); // from sfns.c incByG(X, (i64)X##_sn + ((i64)DX-1)); #define S_SLICES(X, SLN) usz* X##_sh = SH(X); S_KSLICES(X, X##_sh, 1, SLN, 0) -#define SLICE(X, S) taga(arr_shSetU(X##_slc(X, S, X##_csz), X##_cr, X##_csh)) +#define SLICE(X, S) taga(arr_shSetUO(X##_slc(X, S, X##_csz), X##_cr, X##_csh)) #define SLICEI(X) ({ B r = SLICE(X, X##p); X##p+= X##_csz; r; }) diff --git a/src/builtins/fns.c b/src/builtins/fns.c index 353a7aeb..477c9d87 100644 --- a/src/builtins/fns.c +++ b/src/builtins/fns.c @@ -136,13 +136,13 @@ B ud_c2(B t, B w, B x) { for (usz i=wr; if; rsh->a[0] = xsh[0] * xsh[1]; } Arr* r = TI(x,slice)(x, 0, IA(x)); - if (xr>2) arr_shSetU(r, xr-1, rsh); + if (xr>2) arr_shSetUG(r, xr-1, rsh); else arr_shVec(r); return taga(r); } diff --git a/src/builtins/md1.c b/src/builtins/md1.c index c35b2d4d..23862e3a 100644 --- a/src/builtins/md1.c +++ b/src/builtins/md1.c @@ -76,17 +76,14 @@ B tbl_c2(Md1D* d, B w, B x) { B f = d->f; if (TI(x,arrD1) && wia>130 && xia<2560>>arrTypeBitsLog(TY(x))) { Arr* wd = arr_shVec(TI(w,slice)(incG(w), 0, wia)); r = fc2(f, C2(slash, m_i32(xia), taga(wd)), C2(shape, m_f64(ria), incG(x))); + arr_shErase(a(r), 1); } else if (xia>7) { SGet(w) M_APD_TOT(rm, ria) incByG(x, wia); for (usz wi = 0; wi < wia; wi++) APDD(rm, fc2(f, Get(w,wi), x)); - r = taga(APD_TOT_GET(rm)); + r = taga(arr_shVec(APD_TOT_GET(rm))); } else goto generic; - if (RNK(r)>1) { - SRNK(r, 0); // otherwise the following arr_shAlloc failing will result in r->sh dangling - ptr_dec(shObj(r)); - } rsh = arr_shAlloc(a(r), rr); } else { generic:; diff --git a/src/builtins/md2.c b/src/builtins/md2.c index e6693ab8..475ec3f4 100644 --- a/src/builtins/md2.c +++ b/src/builtins/md2.c @@ -43,7 +43,7 @@ typedef struct ReObj { void re_visit(Value* v) { mm_visit(((ReObj*)v)->msg); } void re_freeO(Value* v) { dec(lastErrMsg); lastErrMsg = ((ReObj*)v)->msg; } void pushRe(void) { - ReObj* o = customObj(sizeof(ReObj), re_visit, re_freeO); + ReObj* o = m_customObj(sizeof(ReObj), re_visit, re_freeO); o->msg = lastErrMsg; gsAdd(tag(o,OBJ_TAG)); diff --git a/src/builtins/scan.c b/src/builtins/scan.c index 8f72ce12..248b855f 100644 --- a/src/builtins/scan.c +++ b/src/builtins/scan.c @@ -286,10 +286,10 @@ B scan_c2(Md1D* d, B w, B x) { B f = d->f; FC2 fc2 = c2fn(f); if (isArr(w)) { - ur wr = RNK(w); usz* wsh = SH(w); SGet(w) - if (wr+1!=xr || !eqShPart(wsh, xsh+1, wr)) thrF("`: Shape of 𝕨 must match the cell of 𝕩 (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", w, x); + if (!ptr_eqShape(SH(w), RNK(w), xsh+1, xr-1)) thrF("`: Shape of 𝕨 must match the cell of 𝕩 (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", w, x); if (ia!=0) { usz csz = arr_csz(x); + SGet(w) for (; i < csz; i++) r.a[i] = fc2(f, Get(w,i), xget(xa,i)); for (; i < ia; i++) r.a[i] = fc2(f, inc(r.a[i-csz]), xget(xa,i)); } diff --git a/src/builtins/search.c b/src/builtins/search.c index 6965c8e2..4361e696 100644 --- a/src/builtins/search.c +++ b/src/builtins/search.c @@ -79,7 +79,7 @@ static NOINLINE B toIntCell(B x, ux csz0, ur co) { TySlice* r = m_arr(sizeof(TySlice), t, ria); r->p = a(r0); r->a = tyany_ptr(r0); - if (co>=1) arr_shSetU((Arr*)r, co, rsh); + if (co>=1) arr_shSetUO((Arr*)r, co, rsh); else arr_shVec((Arr*)r); return taga(r); } diff --git a/src/builtins/select.c b/src/builtins/select.c index 4e508ef2..b7079f7d 100644 --- a/src/builtins/select.c +++ b/src/builtins/select.c @@ -351,7 +351,7 @@ B select_c2(B t, B w, B x) { ShArr* sh = m_shArr(rr); shcpy(sh->a, SH(w), wr); shcpy(sh->a+wr, SH(x)+1, xr-1); - arr_shSetU(r, rr, sh); + arr_shSetUG(r, rr, sh); } else { arr_shVec(r); } diff --git a/src/builtins/sfns.c b/src/builtins/sfns.c index 3e4091d1..a67bde40 100644 --- a/src/builtins/sfns.c +++ b/src/builtins/sfns.c @@ -132,11 +132,11 @@ B shape_c1(B t, B x) { } return taga(arr_shVec(TI(x,slice)(x, 0, ia))); } -static B truncReshape(B x, usz xia, usz nia, ur nr, ShArr* sh) { // consumes all +static B truncReshape(B x, usz xia, usz nia, ur nr, ShArr* sh) { // consumes x, and sh if nr>1 B r; Arr* ra; if (reusable(x) && xia==nia) { r = x; decSh(v(x)); ra = (Arr*)v(r); } else { ra = TI(x,slice)(x, 0, nia); r = taga(ra); } - arr_shSetU(ra, nr, sh); + arr_shSetUO(ra, nr, sh); return r; } static void fill_words(void* rp, u64 v, u64 bytes) { @@ -280,7 +280,7 @@ B shape_c2(B t, B w, B x) { for (i64 i = 0; i < div; i++) mut_copyG(m, i*xia, x, 0, xia); mut_copyG(m, div*xia, x, 0, mod); decG(x); - return withFill(taga(arr_shSetU(mut_fp(m), nr, sh)), xf); + return withFill(taga(arr_shSetUO(mut_fp(m), nr, sh)), xf); } u8 xk = xl - 3; rp = m_tyarrp(&r, 1<a[i] = 1; - x = VALIDATE(taga(arr_shSetU(ra, rr, rsh))); + x = VALIDATE(taga(arr_shSetUG(ra, rr, rsh))); } if (cellStart==-1) { // printf("equal shape\n"); r = x; @@ -530,7 +530,7 @@ NOINLINE B takedrop_highrank(bool take, B w, B x) { goto basicTake; } } else if (ria==0) { // printf("empty result\n"); - r = taga(arr_shSetU(emptyArr(x, rr), rr, rsh)); + r = taga(arr_shSetUG(emptyArr(x, rr), rr, rsh)); } else { // printf("generic\n"); B xf = getFillR(x); if (anyFill && noFill(xf)) { @@ -609,7 +609,7 @@ NOINLINE B takedrop_highrank(bool take, B w, B x) { } // end of actual generic copying code - r = withFill(taga(arr_shSetU(mut_fp(rm), rr, rsh)), xf); + r = withFill(taga(arr_shSetUG(mut_fp(rm), rr, rsh)), xf); } decG(x); decW_tfree: TFREE(tmp); @@ -1346,13 +1346,14 @@ static B shape_uc1_t(B r, usz ia) { return r; } B shape_uc1(B t, B o, B x) { - if (!isArr(x) || RNK(x)==0) { + ur xr; + if (!isArr(x) || (xr=RNK(x))==0) { usz xia = isArr(x)? IA(x) : 1; return C2(shape, emptyIVec(), shape_uc1_t(c1(o, shape_c1(t, x)), xia)); } usz xia = IA(x); - if (RNK(x)==1) return shape_uc1_t(c1(o, x), xia); - ur xr = RNK(x); + if (xr==1) return shape_uc1_t(c1(o, x), xia); + assert(xr>1); ShArr* sh = ptr_inc(shObj(x)); return truncReshape(shape_uc1_t(c1(o, shape_c1(t, x)), xia), xia, xia, xr, sh); } diff --git a/src/builtins/slash.c b/src/builtins/slash.c index 53bcd9a1..286e702b 100644 --- a/src/builtins/slash.c +++ b/src/builtins/slash.c @@ -360,7 +360,7 @@ B grade_bool(B x, usz xia, bool up) { #if SINGELI_AVX2 && FAST_PDEP if (xia < 16) { BRANCHLESS_GRADE(i8) } else if (xia <= 1<<15) { - B notx = bit_negate(inc(x)); + B notx = bit_negate(incG(x)); u64* xp0 = bitarr_ptr(notx); u64* xp1 = xp; if (!up) { u64* t=xp1; xp1=xp0; xp0=t; } diff --git a/src/builtins/transpose.c b/src/builtins/transpose.c index 7d718a17..d5845b6f 100644 --- a/src/builtins/transpose.c +++ b/src/builtins/transpose.c @@ -156,7 +156,7 @@ B select_c2(B,B,B); static void shSet(Arr* ra, ur rr, ShArr* sh) { if (RARE(rr <= 1)) arr_shVec(ra); - else arr_shSetU(ra, rr, sh); + else arr_shSetUO(ra, rr, sh); } B transp_c2(B t, B w, B x) { @@ -335,7 +335,7 @@ B transp_c2(B t, B w, B x) { zsh->a[0] = IA(x)/csz; zsh->a[1] = csz; Arr* z = TI(x,slice)(x, 0, IA(x)); - arr_shSetU(z, 2, zsh); + arr_shSetUG(z, 2, zsh); x = taga(z); // (+⌜´st×⟜↕¨rsh)⊏⥊𝕩 B ind = bi_N; diff --git a/src/core/stuff.h b/src/core/stuff.h index c4912940..f6d9141e 100644 --- a/src/core/stuff.h +++ b/src/core/stuff.h @@ -1,21 +1,17 @@ // memory defs - -NORETURN void bqn_exit(i32 code); -u64 mm_heapUsed(void); -void print_allocStats(void); -void vm_pstLive(void); - - #ifndef MAP_NORESERVE #define MAP_NORESERVE 0 // apparently needed for freebsd or something #endif +void print_allocStats(void); +void vm_pstLive(void); + typedef struct CustomObj { struct Value; V2v visit; V2v freeO; } CustomObj; -void* customObj(u64 size, V2v visit, V2v freeO); +void* m_customObj(u64 size, V2v visit, V2v freeO); // shape mess @@ -81,13 +77,13 @@ static Arr* arr_shSetI(Arr* x, ur r, ShArr* sh) { // set rank and assign and inc else x->sh = &x->ia; return x; } -static Arr* arr_shSetU(Arr* x, ur r, ShArr* sh) { // set rank and assign shape +static Arr* arr_shSetUO(Arr* x, ur r, ShArr* sh) { // set rank, and consume & assign shape if r>1 SPRNK(x,r); if (r>1) x->sh = sh->a; else x->sh = &x->ia; return x; } -static Arr* arr_shSetUG(Arr* x, ur r, ShArr* sh) { // arr_shSetU but guaranteed r>1 +static Arr* arr_shSetUG(Arr* x, ur r, ShArr* sh) { // arr_shSetUO but guaranteed r>1, i.e. always consumes sh assert(r>1); SPRNK(x,r); x->sh = sh->a; @@ -124,12 +120,10 @@ static Arr* arr_shReplace(Arr* x, ur r, ShArr* sh) { // replace x's shape with a return x; } static Arr* arr_shCopy(Arr* n, B o) { // copy shape & rank from o to n - assert(isArr(o)); - assert(IA(o)==n->ia); + assert(isArr(o) && IA(o)==n->ia); return arr_shCopyUnchecked(n, o); } static void shcpy(usz* dst, usz* src, ux len) { - // memcpy(dst, src, len*sizeof(usz)); PLAINLOOP for (ux i = 0; i < len; i++) dst[i] = src[i]; } @@ -144,18 +138,14 @@ static usz arr_csz(B x) { return shProd(SH(x), 1, xr); } static bool eqShPart(usz* w, usz* x, usz len) { - // return memcmp(w, x, len*sizeof(usz))==0; PLAINLOOP for (i32 i = 0; i < len; i++) if (w[i]!=x[i]) return false; return true; } -static bool ptr_eqShape(Arr* w, Arr* x) { - ur wr = PRNK(w); usz* wsh = PSH(w); - ur xr = PRNK(x); usz* xsh = PSH(x); - if (wr!=xr) return false; - if (wsh==xsh) return true; +static bool ptr_eqShape(usz* wsh, ur wr, usz* xsh, ur xr) { + if (wr != xr) return false; return eqShPart(wsh, xsh, wr); } -static bool eqShape(B w, B x) { assert(isArr(w) && isArr(x)); return ptr_eqShape(a(w), a(x)); } +static bool eqShape(B w, B x) { assert(isArr(w) && isArr(x)); return ptr_eqShape(SH(w), RNK(w), SH(x), RNK(x)); } B bit_sel(B b, B e0, B e1); // consumes b; b must be bitarr; b⊏e0‿e1 Arr* allZeroes(usz ia); @@ -168,10 +158,6 @@ B narrowWidenedBitArr(B x, ur axis, ur cr, usz* csh); // consumes x.val; undoes Arr* cpyWithShape(B x); // consumes; returns array with refcount 1 with the same shape as x; to allocate a new shape in its place, the previous one needs to be freed, rank set to 1, and then shape & rank set to the new ones Arr* emptyArr(B x, ur xr); // doesn't consume; returns an empty array with the fill of x; if xr>1, shape is unset -static B m_hVec1(B a ); // consumes all -static B m_hVec2(B a, B b ); // consumes all -static B m_hVec3(B a, B b, B c ); // consumes all -static B m_hVec4(B a, B b, B c, B d); // consumes all B m_vec1(B a); // complete fills B m_vec2(B a, B b); // incomplete fills @@ -241,8 +227,8 @@ B chr_squeeze(B x); // consumes; see note below static inline B num_squeezeChk(B x) { return FL_HAS(x,fl_squoze)? x : num_squeeze(x); } static inline B chr_squeezeChk(B x) { return FL_HAS(x,fl_squoze)? x : chr_squeeze(x); } -B def_fn_uc1(B t, B o, B x); -B def_fn_ucw(B t, B o, B w, B x); +B def_fn_uc1(B t, B o, B x); +B def_fn_ucw(B t, B o, B w, B x); B def_m1_uc1(Md1* t, B o, B f, B x); B def_m1_ucw(Md1* t, B o, B f, B w, B x); B def_m2_uc1(Md2* t, B o, B f, B g, B x); @@ -251,8 +237,8 @@ B def_fn_im(B t, B x); B def_fn_is(B t, B x); B def_fn_iw(B t, B w, B x); B def_fn_ix(B t, B w, B x); - B def_decompose(B x); + void noop_visit(Value* x); #if HEAP_VERIFY void arr_visit(Value* x); @@ -298,10 +284,6 @@ static usz depth(B x) { // doesn't consume #ifdef USE_VALGRIND #include "../utils/valgrind.h" - #include - static void pst(char* msg) { - VALGRIND_PRINTF_BACKTRACE("%s", msg); - } #else #define vg_def_p(X, L) #define vg_undef_p(X, L) @@ -310,7 +292,6 @@ static usz depth(B x) { // doesn't consume #endif // call stuff - NORETURN B c1_bad(B f, B x); NORETURN B c2_bad(B f, B w, B x); NORETURN B m1c1_bad(Md1D* d, B x); @@ -334,7 +315,6 @@ static FC2 c2fn(B f) { } // alloc stuff - #ifdef ALLOC_STAT extern u64* ctr_a; extern u64* ctr_f; diff --git a/src/h.h b/src/h.h index a7382873..8a16155f 100644 --- a/src/h.h +++ b/src/h.h @@ -262,7 +262,7 @@ FORCE_INLINE B r_fB(f64 x) { return b(x); } /* 1*/ F(funBI) F(funBl) \ /* 3*/ F(md1BI) F(md1Bl) \ /* 5*/ F(md2BI) F(md2Bl) \ - /* 7*/ F(shape) /* doesn't get F(visited) shouldn't be unallocated by gc */ \ + /* 7*/ F(shape) /* doesn't get visited in arrays, won't be freed by gc */ \ \ /* 8*/ F(fork) F(atop) \ /*10*/ F(md1D) F(md2D) F(md2H) \ @@ -325,7 +325,7 @@ typedef struct Arr { #define assert(X) do { if (!(X)) assert_fail(#X, __FILE__, __LINE__, __PRETTY_FUNCTION__); } while (0) B VALIDATE(B x); Value* VALIDATEP(Value* x); - #define UD assert(false); + #define UD assert(false) extern bool cbqn_noAlloc; NOINLINE void cbqn_NOGC_start(); // function to allow breakpointing #define NOGC_CHECK if (cbqn_noAlloc && !gc_depth) err("allocating during noalloc"); @@ -335,7 +335,7 @@ typedef struct Arr { #define assert(X) {if (!(X)) __builtin_unreachable();} #define VALIDATE(X) (X) #define VALIDATEP(X) (X) - #define UD __builtin_unreachable(); + #define UD __builtin_unreachable() #define NOGC_S #define NOGC_E #define NOGC_CHECK @@ -404,6 +404,7 @@ B toKCells(B x, ur k); // consumes B withFill(B x, B f); // consumes both void cbqn_init(void); +NORETURN void bqn_exit(i32 code); B bqn_exec(B str, B path, B args); // consumes all B bqn_execFile(B path, B args); // consumes B bqn_explain(B str, B path); // consumes str @@ -556,12 +557,12 @@ typedef B (*D2C2)(Md2D*, B, B); F(BSS2A, slice) /* consumes; create slice from a starting position and length; add shape & rank yourself; may not actually be a Slice object; preserves fill */ \ F(B2B, identity) /* return identity element of this function; doesn't consume */ \ \ - F( BBB2B, fn_uc1) /* t,o, x→r; r≡O⌾( T ) x; consumes x */ \ - F( BBBB2B, fn_ucw) /* t,o, w,x→r; r≡O⌾(w⊸ T ) x; consumes w,x */ \ - F(M1C3, m1_uc1) /* t,o,f, x→r; r≡O⌾( F _T ) x; consumes x */ \ - F(M1C4, m1_ucw) /* t,o,f, w,x→r; r≡O⌾(w⊸(F _T )) x; consumes w,x */ \ - F(M2C4, m2_uc1) /* t,o,f,g, x→r; r≡O⌾( F _T_ G ) x; consumes x */ \ - F(M2C5, m2_ucw) /* t,o,f,g,w,x→r; r≡O⌾(w⊸(F _T_ G)) x; consumes w,x */ \ + F( BBB2B, fn_uc1) /* t,o, x→r; r≡O⌾( T ) x; consumes x */ \ + F(BBBB2B, fn_ucw) /* t,o, w,x→r; r≡O⌾(w⊸ T ) x; consumes w,x */ \ + F(M1C3, m1_uc1) /* t,o,f, x→r; r≡O⌾( F _T ) x; consumes x */ \ + F(M1C4, m1_ucw) /* t,o,f, w,x→r; r≡O⌾(w⊸(F _T )) x; consumes w,x */ \ + F(M2C4, m2_uc1) /* t,o,f,g, x→r; r≡O⌾( F _T_ G ) x; consumes x */ \ + F(M2C5, m2_ucw) /* t,o,f,g,w,x→r; r≡O⌾(w⊸(F _T_ G)) x; consumes w,x */ \ \ F(FC1, fn_im) /* t, x; function monadic inverse; consumes x */ \ F(FC1, fn_is) /* t, x; function equal-arg inverse; consumes x */ \ diff --git a/src/jit/x86_64.h b/src/jit/x86_64.h index 675ab8f0..f048ef93 100644 --- a/src/jit/x86_64.h +++ b/src/jit/x86_64.h @@ -70,7 +70,7 @@ static void asmRestorer_free(Value* v) { asm_rel = ((AsmRestorer*)v)->rel; } static NOINLINE void asm_init() { - AsmRestorer* r = customObj(sizeof(AsmRestorer), noop_visit, asmRestorer_free); + AsmRestorer* r = m_customObj(sizeof(AsmRestorer), noop_visit, asmRestorer_free); r->depth = asm_depth; r->ins = asm_ins; r->rel = asm_rel; diff --git a/src/load.c b/src/load.c index 7dce909c..f6dcdcfe 100644 --- a/src/load.c +++ b/src/load.c @@ -648,7 +648,7 @@ static B funBI_ixInit(B t, B w, B x) { B f=c(BFn,t)->rtInvReg; if(f.u==0) f=c(BF static B funBI_iwInit(B t, B w, B x) { B f=c(BFn,t)->rtInvSwap =c1rt(invFnSwap, inc(t)); c(BFn,t)->iw=funBI_iwRt; return c2(f, w, x); } -void* customObj(u64 size, V2v visit, V2v freeO) { +void* m_customObj(u64 size, V2v visit, V2v freeO) { CustomObj* r = mm_alloc(size, t_customObj); r->visit = visit; r->freeO = freeO; diff --git a/src/utils/includeSingeli.h b/src/utils/includeSingeli.h index 282afd7f..06b388b3 100644 --- a/src/utils/includeSingeli.h +++ b/src/utils/includeSingeli.h @@ -14,7 +14,7 @@ #define SINGELI_FILE0(X) #X #define SINGELI_FILE1(X) SINGELI_FILE0(X) - #define si_unreachable() ({UD}) + #define si_unreachable() UD #endif diff --git a/src/utils/mut.c b/src/utils/mut.c index 3d604872..1d20c053 100644 --- a/src/utils/mut.c +++ b/src/utils/mut.c @@ -627,8 +627,7 @@ NOINLINE void apd_sh_init(ApdMut* m, B x) { Arr* a = apd_setArr(m, ria, xe); if (xe==el_B) a->ia = pos0; - if (rr<=1) arr_rnk01(a, rr); - else arr_shSetU(a, rr, rsh); + arr_shSetUO(a, rr, rsh); if (isArr(x)) COPY_TO(m->a, xe, 0, x, 0, IA(x)); else m->apd(m, x); @@ -658,9 +657,7 @@ NOINLINE void apd_widen(ApdMut* m, B x, ApdFn** fns) { Arr* na = apd_setArr(m, tia, re); if (re==el_B) na->ia = pos; - ur pr = PRNK(pa); - if (pr<=1) arr_rnk01(na, pr); - else arr_shSetU(na, pr, shObjP((Value*)pa)); + arr_shSetUO(na, PRNK(pa), shObjP((Value*)pa)); COPY_TO(m->a, re, 0, taga(pa), 0, pos); if (re==el_B) NOGC_E; diff --git a/src/utils/valgrind.h b/src/utils/valgrind.h index fb2e4342..6070c6a6 100644 --- a/src/utils/valgrind.h +++ b/src/utils/valgrind.h @@ -1,5 +1,9 @@ #pragma once +#include #include +static void pst(char* msg) { + VALGRIND_PRINTF_BACKTRACE("%s", msg); +} static u64 vg_getDefined_u64(u64 x) { // for each bit, returns whether it is defined u64 r;