split up h.h
This commit is contained in:
parent
776a77f033
commit
6d5c04e62a
@ -28,7 +28,7 @@ B m_str8(usz sz, char* s) {
|
||||
for (u64 i = 0; i < sz; i++) p[i] = s[i];
|
||||
return r;
|
||||
}
|
||||
NOINLINE B m_str32(u32* s) { // meant to be used as m_str32(U"{𝕨‿𝕩}")
|
||||
NOINLINE B m_str32(u32* s) {
|
||||
u64 sz = 0; while(s[sz]) sz++;
|
||||
B r = m_c32arrv(sz); u32* p = c32arr_ptr(r);
|
||||
for (u64 i = 0; i < sz; i++) p[i] = s[i];
|
||||
|
||||
280
src/h.h
280
src/h.h
@ -34,15 +34,15 @@ CTR_FOR(CTR_DEF)
|
||||
|
||||
#ifdef DEBUG
|
||||
#include<assert.h>
|
||||
#define VALIDATE(x) validate(x)
|
||||
#define VALIDATEP(x) validateP(x)
|
||||
B VALIDATE(B x);
|
||||
Value* VALIDATEP(Value* x);
|
||||
#else
|
||||
#define assert(x) {if (!(x)) __builtin_unreachable();}
|
||||
#define VALIDATE(x) (x)
|
||||
#define VALIDATEP(x) (x)
|
||||
#endif
|
||||
|
||||
#define fsizeof(T,F,E,n) (offsetof(T, F) + sizeof(E)*(n)) // type; FAM name; FAM type; amount
|
||||
#define fsizeof(T,F,E,n) (offsetof(T, F) + sizeof(E)*(n)) // type, flexible array member name, flexible array member type, item amount
|
||||
#define ftag(x) ((u64)(x) << 48)
|
||||
#define tag(v, t) b(((u64)(v)) | ftag(t))
|
||||
// .111111111110000000000000000000000000000000000000000000000000000 infinity
|
||||
@ -137,13 +137,6 @@ char* format_pm2(u8 u) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_VALGRIND
|
||||
#include <valgrind/valgrind.h>
|
||||
#include <valgrind/memcheck.h>
|
||||
void pst(char* msg) {
|
||||
VALGRIND_PRINTF_BACKTRACE("%s", msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef union B {
|
||||
u64 u;
|
||||
@ -199,14 +192,22 @@ void dec(B x);
|
||||
B inc(B x);
|
||||
void ptr_dec(void* x);
|
||||
void ptr_inc(void* x);
|
||||
void print(B x);
|
||||
void arr_print(B x);
|
||||
B m_v1(B a );
|
||||
B m_v2(B a, B b );
|
||||
B m_v3(B a, B b, B c );
|
||||
B m_v4(B a, B b, B c, B d);
|
||||
B m_unit(B a);
|
||||
B m_str32(u32* s);
|
||||
void printUTF8(u32 c);
|
||||
void printRaw(B x); // doesn't consume
|
||||
void print(B x); // doesn't consume
|
||||
bool equal(B w, B x); // doesn't consume
|
||||
void arr_print(B x); // doesn't consume
|
||||
bool eqShape(B w, B x); // doesn't consume
|
||||
usz arr_csz(B x); // doesn't consume
|
||||
bool eqShPrefix(usz* w, usz* x, ur len);
|
||||
|
||||
B m_v1(B a ); // consumes all
|
||||
B m_v2(B a, B b ); // consumes all
|
||||
B m_v3(B a, B b, B c ); // consumes all
|
||||
B m_v4(B a, B b, B c, B d); // consumes all
|
||||
B m_unit(B a); // consumes
|
||||
B m_str32(u32* s); // meant to be used as m_str32(U"{𝕨‿𝕩}"), so doesn't free for you
|
||||
|
||||
NORETURN void thr(B b);
|
||||
NORETURN void thrM(char* s);
|
||||
jmp_buf* prepareCatch();
|
||||
@ -219,6 +220,7 @@ void popCatch();
|
||||
B catchMessage;
|
||||
|
||||
|
||||
|
||||
#define c(T,x) ((T*)((x).u&0xFFFFFFFFFFFFull))
|
||||
#define v(x) c(Value, x)
|
||||
#define a(x) c(Arr , x)
|
||||
@ -300,34 +302,6 @@ void arr_shCopy(B n, B o) { // copy shape from o to n
|
||||
a(n)->sh = a(o)->sh;
|
||||
}
|
||||
}
|
||||
bool eqShPrefix(usz* w, usz* x, ur len) {
|
||||
return memcmp(w, x, len*sizeof(usz))==0;
|
||||
}
|
||||
ur minRank(B w, B x) { // assumes both are arrays
|
||||
ur wr = rnk(w);
|
||||
ur xr = rnk(x);
|
||||
return wr<xr? wr : xr;
|
||||
}
|
||||
ur maxRank(B w, B x) { // assumes both are arrays
|
||||
ur wr = rnk(w);
|
||||
ur xr = rnk(x);
|
||||
return wr>xr? wr : xr;
|
||||
}
|
||||
bool eqShape(B w, B x) { assert(isArr(w)); assert(isArr(x));
|
||||
ur wr = rnk(w); usz* wsh = a(w)->sh;
|
||||
ur xr = rnk(x); usz* xsh = a(x)->sh;
|
||||
if (wr!=xr) return false;
|
||||
if (wsh==xsh) return true;
|
||||
return eqShPrefix(wsh, xsh, wr);
|
||||
}
|
||||
usz arr_csz(B x) {
|
||||
ur xr = rnk(x);
|
||||
if (xr<=1) return 1;
|
||||
usz* sh = a(x)->sh;
|
||||
usz r = 1;
|
||||
for (i32 i = 1; i < xr; i++) r*= sh[i];
|
||||
return r;
|
||||
}
|
||||
|
||||
// make objects
|
||||
B m_arr(usz min, u8 type) { return mm_alloc(min, type, ftag(ARR_TAG)); }
|
||||
@ -397,7 +371,7 @@ void do_nothing(B x) { }
|
||||
void empty_free(B x) { err("FREEING EMPTY\n"); }
|
||||
void builtin_free(B x) { err("FREEING BUILTIN\n"); }
|
||||
void def_visit(B x) { printf("(no visit for %d=%s)\n", v(x)->type, format_type(v(x)->type)); }
|
||||
void freeed_visit(B x) {
|
||||
void freed_visit(B x) {
|
||||
#ifndef CATCH_ERRORS
|
||||
err("visiting t_freed\n");
|
||||
#endif
|
||||
@ -411,40 +385,12 @@ B def_m2_d(B m, B f, B g) { return err("cannot derive this"); }
|
||||
B def_slice(B x, usz s) { return err("cannot slice non-array!"); }
|
||||
B def_decompose(B x) { return m_v2(m_i32((isFun(x)|isMd(x))? 0 : -1),x); }
|
||||
bool def_canStore(B x) { return false; }
|
||||
static inline void hdr_init() {
|
||||
for (i32 i = 0; i < t_COUNT; i++) {
|
||||
ti[i].free = do_nothing;
|
||||
ti[i].visit = def_visit;
|
||||
ti[i].get = def_get;
|
||||
ti[i].getU = def_getU;
|
||||
ti[i].print = def_print;
|
||||
ti[i].m1_d = def_m1_d;
|
||||
ti[i].m2_d = def_m2_d;
|
||||
ti[i].isArr = false;
|
||||
ti[i].arrD1 = false;
|
||||
ti[i].identity = def_identity;
|
||||
ti[i].decompose = def_decompose;
|
||||
ti[i].slice = def_slice;
|
||||
ti[i].canStore = def_canStore;
|
||||
}
|
||||
ti[t_empty].free = empty_free;
|
||||
ti[t_freed].free = do_nothing;
|
||||
ti[t_freed].visit = freeed_visit;
|
||||
ti[t_shape].visit = do_nothing;
|
||||
ti[t_funBI].visit = ti[t_md1BI].visit = ti[t_md2BI].visit = do_nothing;
|
||||
ti[t_funBI].free = ti[t_md1BI].free = ti[t_md2BI].free = builtin_free;
|
||||
bi_N = tag(0, TAG_TAG);
|
||||
bi_noVar = tag(1, TAG_TAG);
|
||||
bi_badHdr = tag(2, TAG_TAG);
|
||||
bi_optOut = tag(3, TAG_TAG);
|
||||
bi_noFill = tag(5, TAG_TAG);
|
||||
assert((MD1_TAG>>1) == (MD2_TAG>>1)); // just to be sure it isn't changed incorrectly, `isMd` depends on this
|
||||
}
|
||||
|
||||
bool isNothing(B b) { return b.u==bi_N.u; }
|
||||
|
||||
|
||||
// refcount
|
||||
bool reusable(B x) { return v(x)->refc==1; }
|
||||
static inline void value_free(B x, Value* vx) {
|
||||
ti[vx->type].free(x);
|
||||
mm_free(vx);
|
||||
@ -456,89 +402,18 @@ void dec(B x) {
|
||||
Value* vx = v(x);
|
||||
if(!--vx->refc) value_free(x, vx);
|
||||
}
|
||||
B inc(B x) {
|
||||
if (isVal(VALIDATE(x))) v(x)->refc++;
|
||||
return x;
|
||||
}
|
||||
void ptr_dec(void* x) { if(!--VALIDATEP((Value*)x)->refc) value_free(tag(x, OBJ_TAG), x); }
|
||||
void ptr_inc(void* x) { VALIDATEP((Value*)x)->refc++; }
|
||||
void ptr_decR(void* x) { if(!--VALIDATEP((Value*)x)->refc) value_freeR1(x); }
|
||||
void decR(B x) {
|
||||
if (!isVal(VALIDATE(x))) return;
|
||||
Value* vx = v(x);
|
||||
if(!--vx->refc) value_freeR2(vx, x);
|
||||
}
|
||||
bool reusable(B x) { return v(x)->refc==1; }
|
||||
|
||||
|
||||
|
||||
void printUTF8(u32 c);
|
||||
|
||||
void print(B x) {
|
||||
if (isF64(x)) {
|
||||
printf("%g", x.f);
|
||||
} else if (isC32(x)) {
|
||||
if ((u32)x.u>=32) { printf("'"); printUTF8((u32)x.u); printf("'"); }
|
||||
else if((u32)x.u>15) printf("\\x%x", (u32)x.u);
|
||||
else printf("\\x0%x", (u32)x.u);
|
||||
} else if (isI32(x)) {
|
||||
printf("%d", (i32)x.u);
|
||||
} else if (isVal(x)) {
|
||||
#ifdef DEBUG
|
||||
if (isVal(x) && (v(x)->type==t_freed || v(x)->type==t_empty)) {
|
||||
u8 t = v(x)->type;
|
||||
v(x)->type = v(x)->flags;
|
||||
printf(t==t_freed?"FREED:":"EMPTY:");
|
||||
TI(x).print(x);
|
||||
v(x)->type = t;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
TI(x).print(x);
|
||||
}
|
||||
else if (isVar(x)) printf("(var d=%d i=%d)", (u16)(x.u>>32), (i32)x.u);
|
||||
else if (x.u==bi_N.u) printf("·");
|
||||
else if (x.u==bi_optOut.u) printf("(value optimized out)");
|
||||
else if (x.u==bi_noVar.u) printf("(unset variable placeholder)");
|
||||
else if (x.u==bi_badHdr.u) printf("(bad header note)");
|
||||
else if (x.u==bi_noFill.u) printf("(no fill placeholder)");
|
||||
else printf("(todo tag %lx)", x.u>>48);
|
||||
}
|
||||
void printRaw(B x) {
|
||||
if (isAtm(x)) {
|
||||
if (isF64(x)) printf("%g", x.f);
|
||||
else if (isC32(x)) printUTF8((u32)x.u);
|
||||
else err("bad printRaw argument: atom arguments should be either numerical or characters");
|
||||
} else {
|
||||
usz ia = a(x)->ia;
|
||||
BS2B xget = TI(x).get;
|
||||
for (usz i = 0; i < ia; i++) {
|
||||
B c = xget(x,i);
|
||||
if (c.u==0 || noFill(c)) { printf(" "); continue; }
|
||||
if (!isC32(c)) err("bad printRaw argument: expected all character items");
|
||||
printUTF8((u32)c.u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
B eq_c2(B t, B w, B x);
|
||||
bool equal(B w, B x) { // doesn't consume
|
||||
bool wa = isArr(w);
|
||||
bool xa = isArr(x);
|
||||
if (wa!=xa) return false;
|
||||
if (!wa) return o2iu(eq_c2(bi_N, inc(w), inc(x)))?1:0;
|
||||
if (!eqShape(w,x)) return false;
|
||||
usz ia = a(x)->ia;
|
||||
BS2B xget = TI(x).get;
|
||||
BS2B wget = TI(w).get;
|
||||
for (usz i = 0; i < ia; i++) {
|
||||
B wc=wget(w,i); B xc=xget(x,i); // getdec
|
||||
bool eq=equal(wc,xc);
|
||||
decR(wc); decR(xc);
|
||||
if(!eq) return false;
|
||||
}
|
||||
return true;
|
||||
B inc(B x) {
|
||||
if (isVal(VALIDATE(x))) v(x)->refc++;
|
||||
return x;
|
||||
}
|
||||
void ptr_inc(void* x) { VALIDATEP((Value*)x)->refc++; }
|
||||
|
||||
|
||||
|
||||
@ -589,40 +464,6 @@ B m_md2H(B m, B g);
|
||||
B m_fork(B f, B g, B h);
|
||||
B m_atop( B g, B h);
|
||||
|
||||
void arr_print(B x) { // should accept refc=0 arguments for debugging purposes
|
||||
usz r = rnk(x);
|
||||
BS2B xgetU = TI(x).getU;
|
||||
usz ia = a(x)->ia;
|
||||
if (r!=1) {
|
||||
if (r==0) {
|
||||
printf("<");
|
||||
print(xgetU(x,0));
|
||||
return;
|
||||
}
|
||||
usz* sh = a(x)->sh;
|
||||
for (i32 i = 0; i < r; i++) {
|
||||
if(i==0)printf("%d",sh[i]);
|
||||
else printf("‿%d",sh[i]);
|
||||
}
|
||||
printf("⥊");
|
||||
} else if (ia>0) {
|
||||
for (usz i = 0; i < ia; i++) {
|
||||
B c = xgetU(x,i);
|
||||
if (!isC32(c) || (u32)c.u=='\n') goto reg;
|
||||
}
|
||||
printf("\"");
|
||||
for (usz i = 0; i < ia; i++) printUTF8((u32)xgetU(x,i).u); // c32, no need to decrement
|
||||
printf("\"");
|
||||
return;
|
||||
}
|
||||
reg:;
|
||||
printf("⟨");
|
||||
for (usz i = 0; i < ia; i++) {
|
||||
if (i!=0) printf(", ");
|
||||
print(xgetU(x,i));
|
||||
}
|
||||
printf("⟩");
|
||||
}
|
||||
|
||||
|
||||
#include <time.h>
|
||||
@ -631,71 +472,4 @@ u64 nsTime() {
|
||||
timespec_get(&t, TIME_UTC);
|
||||
// clock_gettime(CLOCK_REALTIME, &t);
|
||||
return t.tv_sec*1000000000ull + t.tv_nsec;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
Value* validateP(Value* x) {
|
||||
if (x->refc<=0 || (x->refc>>28) == 'a' || x->type==t_empty) {
|
||||
printf("bad refcount for type %d: %d\nattempting to print: ", x->type, x->refc); fflush(stdout);
|
||||
print(tag(x,OBJ_TAG)); puts(""); fflush(stdout);
|
||||
err("");
|
||||
}
|
||||
if (ti[x->type].isArr) {
|
||||
Arr* a = (Arr*)x;
|
||||
if (rnk(tag(x,ARR_TAG))<=1) assert(a->sh == &a->ia);
|
||||
else validate(tag(shObj(tag(x,ARR_TAG)),OBJ_TAG));
|
||||
}
|
||||
return x;
|
||||
}
|
||||
B validate(B x) {
|
||||
if (!isVal(x)) return x;
|
||||
validateP(v(x));
|
||||
if(isArr(x)!=TI(x).isArr && v(x)->type!=t_freed) {
|
||||
printf("wat %d %p\n", v(x)->type, (void*)x.u);
|
||||
print(x);
|
||||
err("\nk");
|
||||
}
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ALLOC_STAT
|
||||
u64* ctr_a = 0;
|
||||
u64* ctr_f = 0;
|
||||
u64 actrc = 21000;
|
||||
u64 talloc = 0;
|
||||
#ifdef ALLOC_SIZES
|
||||
u32** actrs;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static inline void onAlloc(usz sz, u8 type) {
|
||||
#ifdef ALLOC_STAT
|
||||
if (!ctr_a) {
|
||||
#ifdef ALLOC_SIZES
|
||||
actrs = malloc(sizeof(u32*)*actrc);
|
||||
for (i32 i = 0; i < actrc; i++) actrs[i] = calloc(t_COUNT, sizeof(u32));
|
||||
#endif
|
||||
ctr_a = calloc(t_COUNT, sizeof(u64));
|
||||
ctr_f = calloc(t_COUNT, sizeof(u64));
|
||||
}
|
||||
assert(type<t_COUNT);
|
||||
#ifdef ALLOC_SIZES
|
||||
actrs[(sz+3)/4>=actrc? actrc-1 : (sz+3)/4][type]++;
|
||||
#endif
|
||||
ctr_a[type]++;
|
||||
talloc+= sz;
|
||||
#endif
|
||||
}
|
||||
static inline void onFree(Value* x) {
|
||||
#ifdef ALLOC_STAT
|
||||
ctr_f[x->type]++;
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
if (x->type==t_empty) err("double-free");
|
||||
// u32 undef;
|
||||
// x->refc = undef;
|
||||
x->refc = -1431655000;
|
||||
#endif
|
||||
// x->refc = 0x61616161;
|
||||
}
|
||||
}
|
||||
@ -20,6 +20,7 @@
|
||||
|
||||
#define rtLen 63
|
||||
#include "h.h"
|
||||
#include "stuff.c"
|
||||
#include "heap.c"
|
||||
#include "mm_buddy.c"
|
||||
#include "harr.c"
|
||||
|
||||
@ -124,7 +124,10 @@ B eachm(B f, B x) { // complete F¨ x
|
||||
B eachd(B f, B w, B x) { // complete w F¨ x
|
||||
if (!isArr(w) & !isArr(x)) return m_unit(c2(f, w, x));
|
||||
if (isFun(f)) return eachd_fn(c(Fun,f)->c2, f, w, x);
|
||||
if (isArr(w) && isArr(x) && !eqShPrefix(a(w)->sh, a(x)->sh, minRank(w, x))) { decR(x); thrM("Mapping: Expected equal shape prefix"); }
|
||||
if (isArr(w) && isArr(x)) {
|
||||
ur mr = rnk(w); if(rnk(w)<mr) mr = rnk(w);
|
||||
if(!eqShPrefix(a(w)->sh, a(x)->sh, mr)) { decR(x); thrM("Mapping: Expected equal shape prefix"); }
|
||||
}
|
||||
if (isMd(f)) if ((isArr(w)&&a(w)->ia) || (isArr(x)&&a(x)->ia)) { decR(x); thrM("Calling a modifier"); } // case where both are scalars has already been taken care of
|
||||
|
||||
HArr_p r = m_harrc(!isArr(w)? x : rnk(w)>rnk(x)? w : x);
|
||||
|
||||
232
src/stuff.c
Normal file
232
src/stuff.c
Normal file
@ -0,0 +1,232 @@
|
||||
#include "h.h"
|
||||
// a bunch of random things that don't really belong in any other file
|
||||
|
||||
void arr_print(B x) { // should accept refc=0 arguments for debugging purposes
|
||||
usz r = rnk(x);
|
||||
BS2B xgetU = TI(x).getU;
|
||||
usz ia = a(x)->ia;
|
||||
if (r!=1) {
|
||||
if (r==0) {
|
||||
printf("<");
|
||||
print(xgetU(x,0));
|
||||
return;
|
||||
}
|
||||
usz* sh = a(x)->sh;
|
||||
for (i32 i = 0; i < r; i++) {
|
||||
if(i==0)printf("%d",sh[i]);
|
||||
else printf("‿%d",sh[i]);
|
||||
}
|
||||
printf("⥊");
|
||||
} else if (ia>0) {
|
||||
for (usz i = 0; i < ia; i++) {
|
||||
B c = xgetU(x,i);
|
||||
if (!isC32(c) || (u32)c.u=='\n') goto reg;
|
||||
}
|
||||
printf("\"");
|
||||
for (usz i = 0; i < ia; i++) printUTF8((u32)xgetU(x,i).u); // c32, no need to decrement
|
||||
printf("\"");
|
||||
return;
|
||||
}
|
||||
reg:;
|
||||
printf("⟨");
|
||||
for (usz i = 0; i < ia; i++) {
|
||||
if (i!=0) printf(", ");
|
||||
print(xgetU(x,i));
|
||||
}
|
||||
printf("⟩");
|
||||
}
|
||||
|
||||
void print(B x) {
|
||||
if (isF64(x)) {
|
||||
printf("%g", x.f);
|
||||
} else if (isC32(x)) {
|
||||
if ((u32)x.u>=32) { printf("'"); printUTF8((u32)x.u); printf("'"); }
|
||||
else if((u32)x.u>15) printf("\\x%x", (u32)x.u);
|
||||
else printf("\\x0%x", (u32)x.u);
|
||||
} else if (isI32(x)) {
|
||||
printf("%d", (i32)x.u);
|
||||
} else if (isVal(x)) {
|
||||
#ifdef DEBUG
|
||||
if (isVal(x) && (v(x)->type==t_freed || v(x)->type==t_empty)) {
|
||||
u8 t = v(x)->type;
|
||||
v(x)->type = v(x)->flags;
|
||||
printf(t==t_freed?"FREED:":"EMPTY:");
|
||||
TI(x).print(x);
|
||||
v(x)->type = t;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
TI(x).print(x);
|
||||
}
|
||||
else if (isVar(x)) printf("(var d=%d i=%d)", (u16)(x.u>>32), (i32)x.u);
|
||||
else if (x.u==bi_N.u) printf("·");
|
||||
else if (x.u==bi_optOut.u) printf("(value optimized out)");
|
||||
else if (x.u==bi_noVar.u) printf("(unset variable placeholder)");
|
||||
else if (x.u==bi_badHdr.u) printf("(bad header note)");
|
||||
else if (x.u==bi_noFill.u) printf("(no fill placeholder)");
|
||||
else printf("(todo tag %lx)", x.u>>48);
|
||||
}
|
||||
|
||||
void printRaw(B x) {
|
||||
if (isAtm(x)) {
|
||||
if (isF64(x)) printf("%g", x.f);
|
||||
else if (isC32(x)) printUTF8((u32)x.u);
|
||||
else err("bad printRaw argument: atom arguments should be either numerical or characters");
|
||||
} else {
|
||||
usz ia = a(x)->ia;
|
||||
BS2B xget = TI(x).get;
|
||||
for (usz i = 0; i < ia; i++) {
|
||||
B c = xget(x,i);
|
||||
if (c.u==0 || noFill(c)) { printf(" "); continue; }
|
||||
if (!isC32(c)) err("bad printRaw argument: expected all character items");
|
||||
printUTF8((u32)c.u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
B eq_c2(B t, B w, B x);
|
||||
bool equal(B w, B x) { // doesn't consume
|
||||
bool wa = isArr(w);
|
||||
bool xa = isArr(x);
|
||||
if (wa!=xa) return false;
|
||||
if (!wa) return o2iu(eq_c2(bi_N, inc(w), inc(x)))?1:0;
|
||||
if (!eqShape(w,x)) return false;
|
||||
usz ia = a(x)->ia;
|
||||
BS2B xget = TI(x).get;
|
||||
BS2B wget = TI(w).get;
|
||||
for (usz i = 0; i < ia; i++) {
|
||||
B wc=wget(w,i); B xc=xget(x,i); // getdec
|
||||
bool eq=equal(wc,xc);
|
||||
decR(wc); decR(xc);
|
||||
if(!eq) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool eqShPrefix(usz* w, usz* x, ur len) {
|
||||
return memcmp(w, x, len*sizeof(usz))==0;
|
||||
}
|
||||
bool eqShape(B w, B x) { assert(isArr(w)); assert(isArr(x));
|
||||
ur wr = rnk(w); usz* wsh = a(w)->sh;
|
||||
ur xr = rnk(x); usz* xsh = a(x)->sh;
|
||||
if (wr!=xr) return false;
|
||||
if (wsh==xsh) return true;
|
||||
return eqShPrefix(wsh, xsh, wr);
|
||||
}
|
||||
|
||||
usz arr_csz(B x) {
|
||||
ur xr = rnk(x);
|
||||
if (xr<=1) return 1;
|
||||
usz* sh = a(x)->sh;
|
||||
usz r = 1;
|
||||
for (i32 i = 1; i < xr; i++) r*= sh[i];
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
Value* VALIDATEP(Value* x) {
|
||||
if (x->refc<=0 || (x->refc>>28) == 'a' || x->type==t_empty) {
|
||||
printf("bad refcount for type %d: %d\nattempting to print: ", x->type, x->refc); fflush(stdout);
|
||||
print(tag(x,OBJ_TAG)); puts(""); fflush(stdout);
|
||||
err("");
|
||||
}
|
||||
if (ti[x->type].isArr) {
|
||||
Arr* a = (Arr*)x;
|
||||
if (rnk(tag(x,ARR_TAG))<=1) assert(a->sh == &a->ia);
|
||||
else VALIDATE(tag(shObj(tag(x,ARR_TAG)),OBJ_TAG));
|
||||
}
|
||||
return x;
|
||||
}
|
||||
B VALIDATE(B x) {
|
||||
if (!isVal(x)) return x;
|
||||
VALIDATEP(v(x));
|
||||
if(isArr(x)!=TI(x).isArr && v(x)->type!=t_freed) {
|
||||
printf("wat %d %p\n", v(x)->type, (void*)x.u);
|
||||
print(x);
|
||||
err("\nk");
|
||||
}
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_VALGRIND
|
||||
#include <valgrind/valgrind.h>
|
||||
#include <valgrind/memcheck.h>
|
||||
void pst(char* msg) {
|
||||
VALGRIND_PRINTF_BACKTRACE("%s", msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void hdr_init() {
|
||||
for (i32 i = 0; i < t_COUNT; i++) {
|
||||
ti[i].free = do_nothing;
|
||||
ti[i].visit = def_visit;
|
||||
ti[i].get = def_get;
|
||||
ti[i].getU = def_getU;
|
||||
ti[i].print = def_print;
|
||||
ti[i].m1_d = def_m1_d;
|
||||
ti[i].m2_d = def_m2_d;
|
||||
ti[i].isArr = false;
|
||||
ti[i].arrD1 = false;
|
||||
ti[i].identity = def_identity;
|
||||
ti[i].decompose = def_decompose;
|
||||
ti[i].slice = def_slice;
|
||||
ti[i].canStore = def_canStore;
|
||||
}
|
||||
ti[t_empty].free = empty_free;
|
||||
ti[t_freed].free = do_nothing;
|
||||
ti[t_freed].visit = freed_visit;
|
||||
ti[t_shape].visit = do_nothing;
|
||||
ti[t_funBI].visit = ti[t_md1BI].visit = ti[t_md2BI].visit = do_nothing;
|
||||
ti[t_funBI].free = ti[t_md1BI].free = ti[t_md2BI].free = builtin_free;
|
||||
bi_N = tag(0, TAG_TAG);
|
||||
bi_noVar = tag(1, TAG_TAG);
|
||||
bi_badHdr = tag(2, TAG_TAG);
|
||||
bi_optOut = tag(3, TAG_TAG);
|
||||
bi_noFill = tag(5, TAG_TAG);
|
||||
assert((MD1_TAG>>1) == (MD2_TAG>>1)); // just to be sure it isn't changed incorrectly, `isMd` depends on this
|
||||
}
|
||||
|
||||
|
||||
#ifdef ALLOC_STAT
|
||||
u64* ctr_a = 0;
|
||||
u64* ctr_f = 0;
|
||||
u64 actrc = 21000;
|
||||
u64 talloc = 0;
|
||||
#ifdef ALLOC_SIZES
|
||||
u32** actrs;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static inline void onAlloc(usz sz, u8 type) {
|
||||
#ifdef ALLOC_STAT
|
||||
if (!ctr_a) {
|
||||
#ifdef ALLOC_SIZES
|
||||
actrs = malloc(sizeof(u32*)*actrc);
|
||||
for (i32 i = 0; i < actrc; i++) actrs[i] = calloc(t_COUNT, sizeof(u32));
|
||||
#endif
|
||||
ctr_a = calloc(t_COUNT, sizeof(u64));
|
||||
ctr_f = calloc(t_COUNT, sizeof(u64));
|
||||
}
|
||||
assert(type<t_COUNT);
|
||||
#ifdef ALLOC_SIZES
|
||||
actrs[(sz+3)/4>=actrc? actrc-1 : (sz+3)/4][type]++;
|
||||
#endif
|
||||
ctr_a[type]++;
|
||||
talloc+= sz;
|
||||
#endif
|
||||
}
|
||||
static inline void onFree(Value* x) {
|
||||
#ifdef ALLOC_STAT
|
||||
ctr_f[x->type]++;
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
if (x->type==t_empty) err("double-free");
|
||||
// u32 undef;
|
||||
// x->refc = undef;
|
||||
x->refc = -1431655000;
|
||||
#endif
|
||||
// x->refc = 0x61616161;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user