diff --git a/src/builtins/md2.c b/src/builtins/md2.c index 328be309..fc6a6cf6 100644 --- a/src/builtins/md2.c +++ b/src/builtins/md2.c @@ -9,7 +9,7 @@ B val_c1(B d, B x) { return c1(c(Md2D,d)->f, x); } B val_c2(B d, B w, B x) { return c2(c(Md2D,d)->g, w,x); } -#ifdef CATCH_ERRORS +#if CATCH_ERRORS B fillBy_c1(B d, B x) { B xf=getFillQ(x); B r = c1(c(Md2D,d)->f, x); diff --git a/src/builtins/sortTemplate.h b/src/builtins/sortTemplate.h index f93e3050..6cc914a9 100644 --- a/src/builtins/sortTemplate.h +++ b/src/builtins/sortTemplate.h @@ -171,7 +171,7 @@ static void BINARY_INSERTION_SORT_START(SORT_TYPE *dst, const size_t start, cons for (size_t j = i-1; j >= location; j--) { dst[j + 1] = dst[j]; - if (j==0) break; // check edge case because j is unsigned + if (j==0) break; // check edge case because j is unsigned } dst[location] = x; diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index 29de276f..617dab9c 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -45,7 +45,7 @@ B repr_c1(B t, B x) { snprintf(buf, BL, "%.14g", x.f); return m_str8(strlen(buf), buf); } else { - #ifdef FORMATTER + #if FORMATTER return bqn_repr(x); #else thrM("•Repr: Cannot represent non-numbers"); @@ -127,7 +127,7 @@ B asrt_c2(B t, B w, B x) { B sys_c1(B t, B x); B out_c1(B t, B x) { printRaw(x); putchar('\n'); return x; } B show_c1(B t, B x) { - #ifdef FORMATTER + #if FORMATTER B fmt = bqn_fmt(inc(x)); printRaw(fmt); dec(fmt); #else diff --git a/src/core/fillarr.h b/src/core/fillarr.h index 1bdd7c32..40b53ff5 100644 --- a/src/core/fillarr.h +++ b/src/core/fillarr.h @@ -44,7 +44,7 @@ static B getFillR(B x) { // doesn't consume; can return bi_noFill } static B getFillQ(B x) { // doesn't consume; returns 0 if !CATCH_ERRORS B r = getFillR(x); - #ifdef CATCH_ERRORS + #if CATCH_ERRORS return r; #endif return noFill(r)? m_f64(0) : r; diff --git a/src/core/stuff.c b/src/core/stuff.c index b1c2b08d..54cc4fe3 100644 --- a/src/core/stuff.c +++ b/src/core/stuff.c @@ -82,7 +82,7 @@ NOINLINE void printRaw(B x) { BS2B xgetU = TI(x).getU; for (usz i = 0; i < ia; i++) { B c = xgetU(x,i); - #ifndef CATCH_ERRORS + #if CATCH_ERRORS if (c.u==0 || noFill(c)) { printf(" "); continue; } #endif if (!isC32(c)) thrM("bad printRaw argument: expected all character items"); diff --git a/src/h.h b/src/h.h index 6d37f480..5b2d7ca5 100644 --- a/src/h.h +++ b/src/h.h @@ -4,8 +4,40 @@ #ifdef DEBUG // #define DEBUG_VM #endif -#define CATCH_ERRORS // whether to allow catching errors; currently means refcounts won't be accurate and can't be tested for -#define ENABLE_GC // whether to ever garbage-collect +#ifndef CATCH_ERRORS + #define CATCH_ERRORS 1 // whether to allow catching errors +#endif // currently means refcounts won't be accurate and can't be tested for +#ifndef ENABLE_GC + #define ENABLE_GC 1 // whether to ever garbage-collect +#endif +#ifndef TYPED_ARITH + #define TYPED_ARITH 1 // whether to use typed arith +#endif +#ifndef VM_POS + #define VM_POS 1 // whether to store detailed execution position information for stacktraces +#endif +#ifndef CHECK_VALID + #define CHECK_VALID 1 // whether to check for valid arguments in places where that would be detrimental to performance +#endif // e.g. left argument sortedness of ⍋/⍒, incompatible changes in ⌾, etc +#ifndef EACH_FILLS + #define EACH_FILLS 0 // whether to try to squeeze out fills for ¨ and ⌜ +#endif +#ifndef SFNS_FILLS + #define SFNS_FILLS 1 // whether to generate fills for structural functions (∾, ≍, etc) +#endif +#ifndef FAKE_RUNTIME + #define FAKE_RUNTIME 0 // whether to disable the self-hosted runtime +#endif +#ifndef MM + #define MM 1 // memory manager; 0 - malloc (no GC); 1 - buddy; 2 - 2buddy +#endif +#ifndef HEAP_MAX + #define HEAP_MAX ~0ULL // default heap max size +#endif +#ifndef FORMATTER + #define FORMATTER 1 // use self-hosted formatter for output +#endif + // #define HEAP_VERIFY // enable usage of heapVerify() // #define ALLOC_STAT // store basic allocation statistics // #define ALLOC_SIZES // store per-type allocation size statistics @@ -14,17 +46,8 @@ // #define OBJ_COUNTER // store a unique allocation number with each object for easier analysis // #define ALL_R0 // use all of r0.bqn for runtime_0 // #define ALL_R1 // use all of r1.bqn for runtime -#define TYPED_ARITH true // whether to use typed arith -#define VM_POS true // whether to store detailed execution position information for stacktraces -#define CHECK_VALID true // whether to check for valid arguments in places where that would be detrimental to performance (e.g. left argument sortedness of ⍋/⍒, incompatible changes in ⌾, etc) -#define EACH_FILLS false // whether to try to squeeze out fills for ¨ and ⌜ -#define SFNS_FILLS true // whether to insert fills for structural functions (∾, ≍, etc) -#define FAKE_RUNTIME false // whether to disable the self-hosted runtime -#define MM 1 // memory manager; 0 - malloc (no GC); 1 - buddy; 2 - 2buddy -#define HEAP_MAX ~0ULL // default heap max size // #define LOG_GC // log GC stats -#define FORMATTER // use self-hosted formatter for output // #define TIME // output runtime of every expression // #define RT_PERF // time runtime primitives // #define RT_VERIFY // compare native and runtime versions of primitives @@ -46,7 +69,7 @@ #define rtLen 63 -#ifdef CATCH_ERRORS +#if CATCH_ERRORS #define PROPER_FILLS (EACH_FILLS&SFNS_FILLS) #else #undef EACH_FILLS @@ -228,7 +251,7 @@ NOINLINE NORETURN void thrM(char* s); #define thrF(...) thr(append_fmt(inc(bi_emptyCVec), __VA_ARGS__)) NOINLINE NORETURN void thrOOM(); jmp_buf* prepareCatch(); -#ifdef CATCH_ERRORS +#if CATCH_ERRORS #define CATCH setjmp(*prepareCatch()) // use as `if (CATCH) { /*handle error*/ dec(catchMessage); } /*potentially erroring thing*/ popCatch();` #else // note: popCatch() must always be called if no error was caught, so no returns before it! #define CATCH false diff --git a/src/load.c b/src/load.c index 79dfac56..3da583fa 100644 --- a/src/load.c +++ b/src/load.c @@ -82,7 +82,7 @@ B load_comp; B load_rtObj; B load_compArg; -#ifdef FORMATTER +#if FORMATTER B load_fmt, load_repr; B bqn_fmt(B x) { // consumes return c1(load_fmt, x); @@ -272,7 +272,7 @@ static inline void load_init() { // very last init function gc_add(load_comp); - #ifdef FORMATTER + #if FORMATTER Block* fmt_b = load_compImport( #include "gen/formatter" ); @@ -302,7 +302,7 @@ void bqn_exit(i32 code) { static void freed_visit(Value* x) { - #ifndef CATCH_ERRORS + #if CATCH_ERRORS err("visiting t_freed\n"); #endif } diff --git a/src/main.c b/src/main.c index 56fec65c..4cd8a130 100644 --- a/src/main.c +++ b/src/main.c @@ -2,17 +2,13 @@ #include "vm.h" #include "utils/utf.h" -// TODO these are hacks around not needing tiny headers -Block* bqn_comp(B str, B path, B args); -Block* bqn_compSc(B str, B path, B args, Scope* sc, bool repl); - static B replPath; static Scope* gsc; static bool init = false; static void repl_init() { if (init) return; - cbqn_init(); + cbqn_init(); replPath = m_str32(U"REPL"); gc_add(replPath); Block* initBlock = bqn_comp(m_str32(U"\"(REPL initializer)\""), inc(replPath), m_f64(0)); gsc = m_scope(initBlock->body, NULL, 0); gc_add(tag(gsc,OBJ_TAG)); @@ -174,7 +170,7 @@ int main(int argc, char* argv[]) { #endif ptr_dec(block); - #ifdef FORMATTER + #if FORMATTER B resFmt = bqn_fmt(res); printRaw(resFmt); dec(resFmt); putchar('\n'); diff --git a/src/opt/gc.c b/src/opt/gc.c index 32236292..0158ecbd 100644 --- a/src/opt/gc.c +++ b/src/opt/gc.c @@ -33,7 +33,7 @@ void gc_tryFree(Value* v) { #ifdef DONT_FREE v->flags = t; #else - #ifdef CATCH_ERRORS + #if CATCH_ERRORS if (t==t_freed) { mm_free(v); return; } #endif #endif @@ -56,7 +56,7 @@ void gc_visitRoots() { } u64 gc_lastAlloc; void gc_forceGC() { - #ifdef ENABLE_GC + #if ENABLE_GC #ifdef LOG_GC u64 start = nsTime(); gc_visitBytes = 0; gc_freedBytes = 0; diff --git a/src/opt/mm_2buddy.c b/src/opt/mm_2buddy.c index 9b753f0e..d5a43707 100644 --- a/src/opt/mm_2buddy.c +++ b/src/opt/mm_2buddy.c @@ -4,6 +4,7 @@ u64 currObjCounter; #endif +#define ALSZ 20 #define BSZ(X) (1ull<<(X)) #define BSZI(X) ((u8)(64-__builtin_clzl((X)-1ull))) #define MMI(X) X @@ -15,6 +16,7 @@ u64 currObjCounter; #undef BSZ #undef BSZI +#define ALSZ 20 #define BSZ(X) (3ull<<(X)) #define BSZI(X) ((u8)(64-__builtin_clzl((X)/3-1ull))) #define MMI(X) ((X)|64) diff --git a/src/opt/mm_buddy.c b/src/opt/mm_buddy.c index d0f0bc29..7f91cc3d 100644 --- a/src/opt/mm_buddy.c +++ b/src/opt/mm_buddy.c @@ -4,9 +4,14 @@ u64 currObjCounter; #endif +#define ALSZ 20 #define BSZ(X) (1ull<<(X)) #define BSZI(X) ((u8)(64-__builtin_clzl((X)-1ull))) #define MMI(X) X #define BN(X) mm_##X #include "mm_buddyTemplate.c" + +#undef BN +#undef BSZ +#undef BSZI diff --git a/src/opt/mm_buddy.h b/src/opt/mm_buddy.h index 8bf4aa65..7c8f14ed 100644 --- a/src/opt/mm_buddy.h +++ b/src/opt/mm_buddy.h @@ -38,5 +38,6 @@ static u64 mm_size(Value* x) { } void mm_forHeap(V2v f); +#undef BN #undef BSZ #undef BSZI diff --git a/src/opt/mm_buddyTemplate.c b/src/opt/mm_buddyTemplate.c index da1c5a16..7605371a 100644 --- a/src/opt/mm_buddyTemplate.c +++ b/src/opt/mm_buddyTemplate.c @@ -2,6 +2,13 @@ #define al BN(al) #define alCap BN(alCap) #define alSize BN(alSize) +#define str(X) #X +#ifndef PROT + #define PROT PROT_READ|PROT_WRITE +#endif +#ifndef FLAGS + #define FLAGS MAP_NORESERVE|MAP_PRIVATE|MAP_ANON +#endif EmptyValue* buckets[64]; AllocInfo* al; @@ -19,12 +26,12 @@ NOINLINE EmptyValue* BN(makeEmpty)(u8 bucket) { // result->next is garbage buckets[cb] = c->next; break; } - if (cb >= 20) { + if (cb >= ALSZ) { u64 sz = BSZ(cb); if (mm_heapAlloc+sz >= mm_heapMax) { printf("Heap size limit reached\n"); exit(1); } mm_heapAlloc+= sz; // gc_maybeGC(); - c = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_NORESERVE|MAP_PRIVATE|MAP_ANON, -1, 0); + c = mmap(NULL, sz, PROT, FLAGS, -1, 0); #ifdef USE_VALGRIND VALGRIND_MAKE_MEM_UNDEFINED(c, sz); #endif @@ -63,8 +70,11 @@ void BN(forHeap)(V2v f) { } } +#undef FLAGS +#undef PROT #undef AllocInfo #undef al #undef alSize #undef alCap #undef MMI +#undef ALSZ diff --git a/src/utils/builtins.h b/src/utils/builtins.h index 291eb74d..07837955 100644 --- a/src/utils/builtins.h +++ b/src/utils/builtins.h @@ -13,7 +13,7 @@ #define FOR_PM1(A,M,D) \ /*md1.c*/ A(tbl,"⌜") A(each,"¨") A(fold,"´") A(scan,"`") A(const,"˙") A(swap,"˜") A(cell,"˘") \ - /*md1.c*/ A(timed,"•_timed") + /*md1.c*/ A(timed,"•_timed") #define FOR_PM2(A,M,D) \ /*md2.c*/ A(val,"⊘") A(repeat,"⍟") A(fillBy,"•_fillBy_") A(catch,"⎊") \ diff --git a/src/utils/each.h b/src/utils/each.h index 0a41f4ea..8c00a3d2 100644 --- a/src/utils/each.h +++ b/src/utils/each.h @@ -150,7 +150,7 @@ static B eachd(B f, B w, B x) { // complete w F¨ x without fills } -#ifdef CATCH_ERRORS +#if CATCH_ERRORS static inline B arith_recd(BBB2B f, B w, B x) { B fx = getFillQ(x); if (noFill(fx)) return eachd_fn(f, bi_N, w, x); diff --git a/src/utils/mut.h b/src/utils/mut.h index 323b739d..125a523f 100644 --- a/src/utils/mut.h +++ b/src/utils/mut.h @@ -34,7 +34,7 @@ static void mut_to(Mut* m, u8 n) { if (n==el_B && o==el_f64) { // hack to make toHArr calling f64arr_get not cry about possible sNaN floats usz ia = m->val->ia; f64* p = f64arr_ptr(tag(m->val,ARR_TAG)); - for (usz i = 0; i < ia; i++) if (!isF64(b(p[i]))) p[i] = 1.2217638442043777e161; // 0x6161616161616161 + for (usz i = 0; i < ia; i++) if (!isF64(b(p[i]))) p[i] = 1.2217638442043777e161; // 0x6161616161616161 } #endif switch(n) { default: UD; diff --git a/src/utils/wyhash.h b/src/utils/wyhash.h index 9f78658d..ea20c830 100644 --- a/src/utils/wyhash.h +++ b/src/utils/wyhash.h @@ -21,7 +21,7 @@ #ifndef WYHASH_32BIT_MUM //0: normal version, slow on 32 bit systems //1: faster on 32 bit systems but produces different results, incompatible with wy2u0k function -#define WYHASH_32BIT_MUM 0 +#define WYHASH_32BIT_MUM 0 #endif //includes @@ -52,7 +52,7 @@ static inline void _wymum(uint64_t *A, uint64_t *B){ *A=_wyrot(hl)^hh; *B=_wyrot(lh)^ll; #endif #elif defined(__SIZEOF_INT128__) - __uint128_t r=*A; r*=*B; + __uint128_t r=*A; r*=*B; #if(WYHASH_CONDOM>1) *A^=(uint64_t)r; *B^=(uint64_t)(r>>64); #else @@ -123,7 +123,7 @@ static inline uint64_t wyhash(const void *key, size_t len, uint64_t seed, const else a=b=0; } else{ - size_t i=len; + size_t i=len; if(_unlikely_(i>48)){ uint64_t see1=seed, see2=seed; do{ diff --git a/src/vm.c b/src/vm.c index 578d6542..8e2d6705 100644 --- a/src/vm.c +++ b/src/vm.c @@ -260,7 +260,7 @@ Block* compileBlock(B block, Comp* comp, bool* bDone, i32* bc, usz bcIA, B block // consumes all; assumes arguments are valid (verifies some stuff, but definitely not everything) // if sc isn't NULL, this block must only be evaluated directly in that scope precisely once -NOINLINE Block* compile(B bcq, B objs, B blocks, B indices, B tokenInfo, B src, Scope* sc) { +NOINLINE Block* compile(B bcq, B objs, B blocks, B indices, B tokenInfo, B src, Scope* sc) { usz bIA = a(blocks)->ia; I32Arr* bca = toI32Arr(bcq); i32* bc = bca->a; @@ -791,7 +791,7 @@ jmp_buf* prepareCatch() { // in the case of returning false, must call popCatch( return &(cf++)->jmp; } void popCatch() { - #ifdef CATCH_ERRORS + #if CATCH_ERRORS assert(cf>cfStart); cf--; #endif diff --git a/src/vm.h b/src/vm.h index bf4d4ba8..f0d12d2b 100644 --- a/src/vm.h +++ b/src/vm.h @@ -58,7 +58,8 @@ struct Scope { B vars[]; }; - +Block* bqn_comp(B str, B path, B args); +Block* bqn_compSc(B str, B path, B args, Scope* sc, bool repl); Block* compile(B bcq, B objs, B blocksq, B indices, B tokenInfo, B src, Scope* sc); Scope* m_scope(Body* body, Scope* psc, u16 varAm); B evalBC(Body* b, Scope* sc); // doesn't consume; executes bytecode of the body directly in the scope