diff --git a/src/README.md b/src/README.md index 810f5372..b4bb3878 100644 --- a/src/README.md +++ b/src/README.md @@ -299,9 +299,9 @@ if (TY(x)==t_harr || TY(x)==t_hslice) B* xp = hany_ptr(x); // note that elType== if (TY(x)==t_fillarr) B* xp = fillarr_ptr(x); B* xp = arr_bptr(x); // will return NULL if the array isn't backed by contiguous B*-s -// functions to convert arrays to a specific type array: (all consume their argument) +// functions to convert arrays to a specific type array: (all consume their argument, and assume that the elements fit in the desired type) I8Arr* a = toI8Arr(x); // convert x to an I8Arr instance (returns the argument if it already is) -I8Arr* a = cpyI8Arr(x); // get an I8Arr with reference count 1 with the same items +I8Arr* a = (I8Arr*)cpyI8Arr(x); // get an I8Arr with reference count 1 with the same items & shape B a = toI8Any(x); // get an object which be a valid argument to i8any_ptr // same logic applies for: // toBitArr/toI8Arr/toI16Arr/toI32Arr/toF64Arr/toC8Arr/toC16Arr/toC32Arr/toHArr diff --git a/src/builtins/grade.h b/src/builtins/grade.h index 49410350..9f8e8ceb 100644 --- a/src/builtins/grade.h +++ b/src/builtins/grade.h @@ -217,7 +217,7 @@ B SORT_C1(B t, B x) { } } else { B xf = getFillQ(x); - HArr* r0 = cpyHArr(inc(x)); + HArr* r0 = (HArr*)cpyHArr(inc(x)); CAT(GRADE_UD(bA,bD),tim_sort)(r0->a, n); r = withFill(taga(r0), xf); } @@ -376,12 +376,8 @@ B GRADE_CAT(c2)(B t, B w, B x) { gen:; SGetU(x) SLOW2("𝕨"GRADE_CHR"𝕩", w, x); - B* wp = arr_bptr(w); - if (wp==NULL) { - HArr* a = toHArr(w); - wp = a->a; - w = taga(a); - } + B* wp = TO_BPTR(w); + if (CHECK_VALID && !FL_HAS(w,fl)) { for (i64 i = 0; i < (i64)wia-1; i++) if (compare(wp[i], wp[i+1]) GRADE_UD(>,<) 0) thrM(GRADE_CHR": 𝕨 must be sorted"GRADE_UD(," in descending order")); FL_SET(w, fl); diff --git a/src/builtins/internal.c b/src/builtins/internal.c index 707bec38..3667696d 100644 --- a/src/builtins/internal.c +++ b/src/builtins/internal.c @@ -190,11 +190,7 @@ B variation_c2(B t, B w, B x) { arr_shCopy(t, x); HArr* h = NULL; - B* xp = arr_bptr(x); - if (xp==NULL) { - h = cpyHArr(incG(x)); - xp = h->a; - } + B* xp = TO_BPTR(x); B* rp = fillarr_ptr(t); for (usz i = 0; i < xia; i++) rp[i] = inc(xp[i]); diff --git a/src/builtins/select.c b/src/builtins/select.c index 70166e82..1d3789cb 100644 --- a/src/builtins/select.c +++ b/src/builtins/select.c @@ -401,7 +401,7 @@ B select_ucw(B t, B o, B w, B x) { u8 me = xe>re?xe:re; bool reuse = reusable(x); if (me==el_i32) { - I32Arr* xn = reuse? toI32Arr(REUSE(x)) : cpyI32Arr(x); + I32Arr* xn = reuse? toI32Arr(REUSE(x)) : (I32Arr*)cpyI32Arr(x); i32* xp = i32arrv_ptr(xn); rep = toI32Any(rep); i32* rp = i32any_ptr(rep); for (usz i = 0; i < wia; i++) { @@ -412,7 +412,7 @@ B select_ucw(B t, B o, B w, B x) { } decG(w); decG(rep); FREE_CHECK; return taga(xn); } else if (me==el_i8) { - I8Arr* xn = reuse? toI8Arr(REUSE(x)) : cpyI8Arr(x); + I8Arr* xn = reuse? toI8Arr(REUSE(x)) : (I8Arr*)cpyI8Arr(x); i8* xp = i8arrv_ptr(xn); rep = toI8Any(rep); i8* rp = i8any_ptr(rep); for (usz i = 0; i < wia; i++) { @@ -423,7 +423,7 @@ B select_ucw(B t, B o, B w, B x) { } decG(w); decG(rep); FREE_CHECK; return taga(xn); } else if (me==el_i16) { - I16Arr* xn = reuse? toI16Arr(REUSE(x)) : cpyI16Arr(x); + I16Arr* xn = reuse? toI16Arr(REUSE(x)) : (I16Arr*)cpyI16Arr(x); i16* xp = i16arrv_ptr(xn); rep = toI16Any(rep); i16* rp = i16any_ptr(rep); for (usz i = 0; i < wia; i++) { @@ -434,7 +434,7 @@ B select_ucw(B t, B o, B w, B x) { } decG(w); decG(rep); FREE_CHECK; return taga(xn); } else if (me==el_bit) { - BitArr* xn = reuse? toBitArr(REUSE(x)) : cpyBitArr(x); + BitArr* xn = reuse? toBitArr(REUSE(x)) : (BitArr*)cpyBitArr(x); u64* xp = bitarrv_ptr(xn); rep = taga(toBitArr(rep)); u64* rp = bitarr_ptr(rep); for (usz i = 0; i < wia; i++) { @@ -445,7 +445,7 @@ B select_ucw(B t, B o, B w, B x) { } decG(w); decG(rep); FREE_CHECK; return taga(xn); } else if (me==el_f64) { - F64Arr* xn = reuse? toF64Arr(REUSE(x)) : cpyF64Arr(x); + F64Arr* xn = reuse? toF64Arr(REUSE(x)) : (F64Arr*)cpyF64Arr(x); f64* xp = f64arrv_ptr(xn); rep = toF64Any(rep); f64* rp = f64any_ptr(rep); for (usz i = 0; i < wia; i++) { diff --git a/src/builtins/sfns.c b/src/builtins/sfns.c index bcd56ff9..f75f1f76 100644 --- a/src/builtins/sfns.c +++ b/src/builtins/sfns.c @@ -1288,7 +1288,7 @@ B transp_c1(B t, B x) { bool toBit = false; if (h==2) { if (xe==el_B) { - B* xp = arr_bptr(x); if (xp==NULL) { HArr* xa=cpyHArr(x); x=taga(xa); xp=xa->a; } + B* xp = TO_BPTR(x); B* x0 = xp; B* x1 = x0+w; HArr_p rp = m_harrUp(ia); for (usz i=0; ia; } // TODO extract this to an inline function + B* xp = TO_BPTR(x); HArr_p p = m_harrUp(ia); for(usz y=0;ya; } + B* xp = TO_BPTR(x); usz i,j; i64 max=-1; for (i = 0; i < xia; i++) { i64 c=o2i64(xp[i]); if (c<=max) break; max=c; } for (j = i; j < xia; j++) { i64 c=o2i64(xp[j]); max=c>max?c:max; if (c<0) thrM("/⁼: Argument cannot contain negative numbers"); } diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index f4430f6e..b6aa34fb 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -1190,11 +1190,11 @@ static B convert(CastType t, B x) { } static TyArr* copy(CastType t, B x) { switch (t.s) { - case 1: return cpyBitArr(x); - case 8: return t.c ? cpyC8Arr (x) : cpyI8Arr (x); - case 16: return t.c ? cpyC16Arr(x) : cpyI16Arr(x); - case 32: return t.c ? cpyC32Arr(x) : cpyI32Arr(x); - case 64: return cpyF64Arr(x); + case 1: return (TyArr*) (cpyBitArr(x)); + case 8: return (TyArr*) (t.c ? cpyC8Arr (x) : cpyI8Arr (x)); + case 16: return (TyArr*) (t.c ? cpyC16Arr(x) : cpyI16Arr(x)); + case 32: return (TyArr*) (t.c ? cpyC32Arr(x) : cpyI32Arr(x)); + case 64: return (TyArr*) (cpyF64Arr(x)); default: thrM("•bit._cast: unsupported input width"); } } diff --git a/src/core/chrarr.h b/src/core/chrarr.h index 20405623..881e32e9 100644 --- a/src/core/chrarr.h +++ b/src/core/chrarr.h @@ -26,14 +26,14 @@ B utf8Decode0(const char* x); B utf8Decode(const char* x, i64 sz); B utf8DecodeA(I8Arr* x); -C8Arr* cpyC8Arr (B x); // consumes -C16Arr* cpyC16Arr(B x); // consumes -C32Arr* cpyC32Arr(B x); // consumes +Arr* cpyC8Arr (B x); // consumes +Arr* cpyC16Arr(B x); // consumes +Arr* cpyC32Arr(B x); // consumes // all consume x -static C8Arr* toC8Arr (B x) { return TY(x)==t_c8arr ? c(C8Arr, x) : cpyC8Arr (x); } -static C16Arr* toC16Arr(B x) { return TY(x)==t_c16arr? c(C16Arr,x) : cpyC16Arr(x); } -static C32Arr* toC32Arr(B x) { return TY(x)==t_c32arr? c(C32Arr,x) : cpyC32Arr(x); } +static C8Arr* toC8Arr (B x) { return TY(x)==t_c8arr ? c(C8Arr, x) : (C8Arr*) cpyC8Arr (x); } +static C16Arr* toC16Arr(B x) { return TY(x)==t_c16arr? c(C16Arr,x) : (C16Arr*) cpyC16Arr(x); } +static C32Arr* toC32Arr(B x) { return TY(x)==t_c32arr? c(C32Arr,x) : (C32Arr*) cpyC32Arr(x); } static B toC8Any (B x) { u8 t=TY(x); return t==t_c8arr || t==t_c8slice ? x : taga(cpyC8Arr (x)); } static B toC16Any(B x) { u8 t=TY(x); return t==t_c16arr || t==t_c16slice? x : taga(cpyC16Arr(x)); } diff --git a/src/core/harr.h b/src/core/harr.h index f3c8592e..dbb27cb0 100644 --- a/src/core/harr.h +++ b/src/core/harr.h @@ -105,8 +105,10 @@ static B m_hunit(B x) { // consumes static B* harr_ptr(B x) { VTY(x,t_harr); return c(HArr,x)->a; } static B* hany_ptr(B x) { return TY(x)==t_hslice? c(HSlice,x)->a : harr_ptr(x); } -HArr* cpyHArr(B x); // consumes -static HArr* toHArr(B x) { return TY(x)==t_harr? c(HArr,x) : cpyHArr(x); } +Arr* cpyHArr(B x); // consumes +static HArr* toHArr(B x) { return TY(x)==t_harr? c(HArr,x) : (HArr*) cpyHArr(x); } +#define TO_BPTR(X) ({ B* bp_ = arr_bptr(X); if (bp_==NULL) { HArr* nha_ = (HArr*)cpyHArr(X); X=taga(nha_); bp_=nha_->a; }; bp_; }) + B m_caB(usz ia, B* a); // consumes all diff --git a/src/core/numarr.h b/src/core/numarr.h index 4da3c809..bfab0591 100644 --- a/src/core/numarr.h +++ b/src/core/numarr.h @@ -82,18 +82,18 @@ static u64* bitarr_ptr(B x) { VTY(x, t_bitarr); return (u64*)c(BitArr,x)->a; } static u64* bitarrv_ptr(TyArr* x) { return (u64*)x->a; } -I8Arr* cpyI8Arr (B x); // consumes -I16Arr* cpyI16Arr(B x); // consumes -I32Arr* cpyI32Arr(B x); // consumes -F64Arr* cpyF64Arr(B x); // consumes -BitArr* cpyBitArr(B x); // consumes +Arr* cpyI8Arr (B x); // consumes +Arr* cpyI16Arr(B x); // consumes +Arr* cpyI32Arr(B x); // consumes +Arr* cpyF64Arr(B x); // consumes +Arr* cpyBitArr(B x); // consumes // all consume x -static I8Arr* toI8Arr (B x) { return TY(x)==t_i8arr ? c(I8Arr, x) : cpyI8Arr (x); } -static I16Arr* toI16Arr(B x) { return TY(x)==t_i16arr? c(I16Arr,x) : cpyI16Arr(x); } -static I32Arr* toI32Arr(B x) { return TY(x)==t_i32arr? c(I32Arr,x) : cpyI32Arr(x); } -static F64Arr* toF64Arr(B x) { return TY(x)==t_f64arr? c(F64Arr,x) : cpyF64Arr(x); } -static BitArr* toBitArr(B x) { return TY(x)==t_bitarr? c(BitArr,x) : cpyBitArr(x); } +static I8Arr* toI8Arr (B x) { return TY(x)==t_i8arr ? c(I8Arr, x) : (I8Arr*) cpyI8Arr (x); } +static I16Arr* toI16Arr(B x) { return TY(x)==t_i16arr? c(I16Arr,x) : (I16Arr*) cpyI16Arr(x); } +static I32Arr* toI32Arr(B x) { return TY(x)==t_i32arr? c(I32Arr,x) : (I32Arr*) cpyI32Arr(x); } +static F64Arr* toF64Arr(B x) { return TY(x)==t_f64arr? c(F64Arr,x) : (F64Arr*) cpyF64Arr(x); } +static BitArr* toBitArr(B x) { return TY(x)==t_bitarr? c(BitArr,x) : (BitArr*) cpyBitArr(x); } static B toI8Any (B x) { u8 t=TY(x); return t==t_i8arr || t==t_i8slice ? x : taga(cpyI8Arr (x)); } static B toI16Any(B x) { u8 t=TY(x); return t==t_i16arr || t==t_i16slice? x : taga(cpyI16Arr(x)); } diff --git a/src/ffi.c b/src/ffi.c index d7b7f320..e3d046be 100644 --- a/src/ffi.c +++ b/src/ffi.c @@ -956,21 +956,21 @@ void ffi_init(void) { } case 3: { SGet(x) - int fd = o2i(Get(x,0)); - I8Arr* buf = cpyI8Arr(Get(x,1)); - usz maxlen = o2s(Get(x,2)); + int fd = o2i(Get(x,0)); + Arr* buf = cpyI8Arr(Get(x,1)); + usz maxlen = o2s(Get(x,2)); decG(x); assert(PIA(buf)==maxlen); - int res = read(fd, buf->a, maxlen); + int res = read(fd, ((TyArr*)buf)->a, maxlen); return m_vec2(m_f64(res), taga(buf)); } case 4: { SGet(x) - int fd = o2i(Get(x,0)); - I8Arr* buf = cpyI8Arr(Get(x,1)); - usz maxlen = o2s(Get(x,2)); + int fd = o2i(Get(x,0)); + Arr* buf = cpyI8Arr(Get(x,1)); + usz maxlen = o2s(Get(x,2)); decG(x); - int res = write(fd, buf->a, maxlen); + int res = write(fd, ((TyArr*)buf)->a, maxlen); ptr_dec(buf); return m_f64(res); } @@ -979,9 +979,9 @@ void ffi_init(void) { } case 6: { SGet(x) - I16Arr* buf = cpyI16Arr(Get(x,0)); i16* a = (i16*)buf->a; - int nfds = o2i(Get(x,1)); - int timeout = o2s(Get(x,2)); + Arr* buf = cpyI16Arr(Get(x,0)); i16* a = (i16*)((TyArr*)buf)->a; + int nfds = o2i(Get(x,1)); + int timeout = o2s(Get(x,2)); decG(x); TALLOC(pollfd, ps, nfds) diff --git a/src/utils/mut.c b/src/utils/mut.c index 3d69b8fa..2deea3a9 100644 --- a/src/utils/mut.c +++ b/src/utils/mut.c @@ -1,6 +1,13 @@ #include "../core.h" #include "mut.h" +static Arr* (*cpyFns[])(B) = { + [el_bit] = cpyBitArr, + [el_i8] = cpyI8Arr, [el_c8] = cpyC8Arr, + [el_i16] = cpyI16Arr, [el_c16] = cpyC16Arr, + [el_i32] = cpyI32Arr, [el_c32] = cpyC32Arr, + [el_f64] = cpyF64Arr, [el_B] = cpyHArr +}; NOINLINE void mut_to(Mut* m, u8 n) { u8 o = m->fns->elType; assert(o!=el_B); @@ -20,17 +27,9 @@ NOINLINE void mut_to(Mut* m, u8 n) { for (usz i = 0; i < ia; i++) if (!isF64(b(p[i]))) p[i] = 1.2217638442043777e161; // 0x6161616161616161 } #endif - switch(n) { default: UD; - case el_bit: { BitArr* t=cpyBitArr(taga(m->val)); m->val=(Arr*)t; m->a = t->a; return; } - case el_i8: { I8Arr* t=cpyI8Arr (taga(m->val)); m->val=(Arr*)t; m->a = t->a; return; } - case el_i16: { I16Arr* t=cpyI16Arr(taga(m->val)); m->val=(Arr*)t; m->a = t->a; return; } - case el_i32: { I32Arr* t=cpyI32Arr(taga(m->val)); m->val=(Arr*)t; m->a = t->a; return; } - case el_c8: { C8Arr* t=cpyC8Arr (taga(m->val)); m->val=(Arr*)t; m->a = t->a; return; } - case el_c16: { C16Arr* t=cpyC16Arr(taga(m->val)); m->val=(Arr*)t; m->a = t->a; return; } - case el_c32: { C32Arr* t=cpyC32Arr(taga(m->val)); m->val=(Arr*)t; m->a = t->a; return; } - case el_f64: { F64Arr* t=cpyF64Arr(taga(m->val)); m->val=(Arr*)t; m->a = t->a; return; } - case el_B : { HArr* t=cpyHArr (taga(m->val)); m->val=(Arr*)t; m->a = t->a; return; } - } + Arr* t = cpyFns[n](taga(m->val)); + m->val = t; + m->a = n==el_B? (void*)((HArr*)t)->a : (void*)((TyArr*)t)->a; } } @@ -242,15 +241,15 @@ DEF_G(void, copy, B, (void* a, usz ms, B x, usz xs, usz l), ms, x, x else cpy##T##Arr_BF(xp, rp, ia, xa); \ } \ static copy_fn copy##T##Fns[] = __VA_ARGS__; \ - T##Arr* cpy##T##Arr(B x) { \ - usz ia = IA(x); \ - MAKE; arr_shCopy(r, x); \ - if (ia>0) { \ + Arr* cpy##T##Arr(B x) { \ + usz ia = IA(x); \ + MAKE; arr_shCopy(r, x); \ + if (ia>0) { \ copy##T##Fns[TI(x,elType)](tyany_ptr(x), XRP, ia, a(x)); \ - } \ - if (TY) ptr_decT(a(x)); \ - else decG(x); \ - NOGC_E; return (T##Arr*)r; \ + } \ + if (TY) ptr_decT(a(x)); \ + else decG(x); \ + NOGC_E; return (Arr*)r; \ } #define BIT_PUT(V) bitp_set((u64*)rp, i, o2bG(V)) #define H2T_COPY(T) copy##T##Fns[el_MAX](bxp, rp, ia, xRaw) @@ -288,7 +287,7 @@ DEF_G(void, copy, B, (void* a, usz ms, B x, usz xs, usz l), ms, x, x bit_cpy((u64*)a, ms, bitarr_ptr(x), xs, l); } #else - #define MAKE_ICPY(T,E) T##Arr* cpy##T##Arr(B x) { \ + #define MAKE_ICPY(T,E) Arr* cpy##T##Arr(B x) { \ usz ia = IA(x); \ E* rp; Arr* r = m_##E##arrp(&rp, ia); \ arr_shCopy(r, x); \ @@ -304,28 +303,28 @@ DEF_G(void, copy, B, (void* a, usz ms, B x, usz xs, usz l), ms, x, x else { SGetU(x) for (usz i=0; iblockAm = 0; comp->objs = NULL; // and now finally it's safe to allocate stuff - HArr* objArr = cpyHArr(objs); + HArr* objArr = (HArr*)cpyHArr(objs); comp->objs = objArr; usz objAm = PIA(objArr); for (usz i = 0; i < objAm; i++) objArr->a[i] = squeeze_deep(objArr->a[i]);