modifiable defines

This commit is contained in:
dzaima 2021-06-06 16:47:32 +03:00
parent 47f8984e74
commit 7e994dd913
19 changed files with 79 additions and 41 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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");

49
src/h.h
View File

@ -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

View File

@ -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
}

View File

@ -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');

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -38,5 +38,6 @@ static u64 mm_size(Value* x) {
}
void mm_forHeap(V2v f);
#undef BN
#undef BSZ
#undef BSZI

View File

@ -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

View File

@ -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,"") \

View File

@ -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);

View File

@ -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;

View File

@ -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{

View File

@ -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

View File

@ -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