split up CATCH_ERRORS into functional and semantic options
allows running a non-heapverify build that functions exactly as a heapverify one, while allowing ⎊ to function
This commit is contained in:
parent
fd317ddce3
commit
54cec2fdf5
@ -323,14 +323,14 @@ po ← { # parsed options
|
||||
args∾↩ (singeli ∧ arch≡"aarch64") / ⟨"-DSINGELI_NEON"⟩
|
||||
args∾↩ (singeli ∧ ⊑arch<⊸∊"x86-64"‿"aarch64") / ⟨"-DSINGELI_SIMD"⟩
|
||||
args∾↩ ( wasm) / ⟨"-DWASM"⟩
|
||||
args∾↩ ( wasi) / ⟨"-DWASI", "-DNO_MMAP", "-DCATCH_ERRORS=0", "-D_WASI_EMULATED_MMAN", "--target=wasm32-wasi"⟩
|
||||
args∾↩ ( wasi) / ⟨"-DWASI", "-DNO_MMAP", "-DUSE_SETJMP=0", "-D_WASI_EMULATED_MMAN", "--target=wasm32-wasi"⟩
|
||||
args∾↩ ( emcc) / ⟨"-DEMCC", "-O3"⟩
|
||||
args∾↩ ( replxx) / ⟨"-DUSE_REPLXX", "-DREPLXX_STATIC=1", "-I"∾replxxDir∾"/include"⟩ # TODO maybe move to main.c only, and have it be in its own separate cache dir, so that adding replxx doesn't recompile everything?
|
||||
args∾↩ ( debug DOpt "g") / ⟨"-g"⟩
|
||||
args∾↩ ( o3) / ⟨"-O3"⟩
|
||||
args∾↩ ( debug) / ⟨"-DDEBUG"⟩
|
||||
args∾↩ ( rtverify) / ⟨"-DRT_VERIFY"⟩
|
||||
args∾↩ ( heapverify) / ⟨"-DHEAP_VERIFY", "-DCATCH_ERRORS=0"⟩
|
||||
args∾↩ ( heapverify) / ⟨"-DHEAP_VERIFY", "-DUSE_SETJMP=0"⟩
|
||||
args∾↩ ( exportSymbols) / ⟨"-DCBQN_EXPORT"⟩
|
||||
args∾↩ ( ¬pie) / ⟨"-fno-pie"⟩
|
||||
args∾↩ (pie ∧ ¬sharedLib) / ⟨"-fPIE"⟩
|
||||
|
||||
@ -401,7 +401,7 @@ Most toggles require a value of `1` to be enabled.
|
||||
|
||||
```c
|
||||
// (effective) usual default value is listed; (u) marks being not defined
|
||||
// default may change under some conditions (DEBUG, CATCH_ERRORS, heapverify, among maybe other things)
|
||||
// defaults may change under some conditions (DEBUG, USE_SETJMP, heapverify, among maybe other things)
|
||||
// some things fully configured by the build system may not be listed
|
||||
|
||||
// general config:
|
||||
@ -420,7 +420,6 @@ Most toggles require a value of `1` to be enabled.
|
||||
#define ALL_R0 0 // use all of r0.bqn for runtime_0
|
||||
#define ALL_R1 0 // use all of r1.bqn for runtime
|
||||
#define NO_RT 0 // whether to completely disable self-hosted runtime loading
|
||||
#define CATCH_ERRORS 1 // allow catching errors; means refcounts might stay too high if forgotten over a throw-catch; disabled for heapverify
|
||||
#define FAKE_RUNTIME 0 // disable the self-hosted runtime
|
||||
#define FORMATTER 1 // use self-hosted formatter for output
|
||||
#define NO_EXPLAIN 0 // disable )explain
|
||||
@ -429,6 +428,9 @@ Most toggles require a value of `1` to be enabled.
|
||||
#define SFNS_FILLS 1 // compute fills for structural functions (∾, ≍, etc)
|
||||
#define CHECK_VALID 1 // check for valid arguments in places where that would be detrimental to performance
|
||||
// e.g. left argument sortedness of ⍋/⍒, incompatible changes in ⌾, etc
|
||||
#define USE_SETJMP 1 // whether setjmp is available & should be used for error catching (makes refcounts leakable)
|
||||
#define SEMANTIC_CATCH USE_SETJMP // whether catching should be assumed to be usable for operations which need to semantically change depending on that
|
||||
#define SEMANTIC_CATCH_BI SEMANTIC_CATCH // whether ⎊ will catch stuff
|
||||
|
||||
#define RYU_OPTIMIZE_SIZE 0 // reduce size of Ryu tables at the cost of some performance for number •Repr
|
||||
#define FFI_CHECKS 1 // check for valid arguments passed to FFI-d functions
|
||||
|
||||
@ -83,12 +83,12 @@ B scan_arith(B f, B w, B x, usz* xsh) { // Used by scan.c
|
||||
|
||||
|
||||
#if TEST_CELL_FILLS
|
||||
i32 fullCellFills = 2*CATCH_ERRORS;
|
||||
i32 fullCellFills = 2*SEMANTIC_CATCH;
|
||||
i32 cellFillErrored = 0;
|
||||
#define DO_CELL_CATCH (fullCellFills==2)
|
||||
#define SET_FILL_ERRORED cellFillErrored = 1
|
||||
#else
|
||||
#define DO_CELL_CATCH CATCH_ERRORS
|
||||
#define DO_CELL_CATCH SEMANTIC_CATCH
|
||||
#define SET_FILL_ERRORED
|
||||
#endif
|
||||
|
||||
|
||||
@ -8,9 +8,7 @@
|
||||
B val_c1(Md2D* d, B x) { return c1(d->f, x); }
|
||||
B val_c2(Md2D* d, B w, B x) { return c2(d->g, w,x); }
|
||||
|
||||
#if CATCH_ERRORS && !BI_CATCH_DISABLED
|
||||
extern GLOBAL B lastErrMsg; // sysfn.c
|
||||
|
||||
#if SEMANTIC_CATCH
|
||||
B fillBy_c1(Md2D* d, B x) {
|
||||
B xf=getFillQ(x);
|
||||
B r = c1(d->f, x);
|
||||
@ -30,7 +28,13 @@ B fillBy_c2(Md2D* d, B w, B x) {
|
||||
popCatch();
|
||||
return withFill(r, fill);
|
||||
}
|
||||
#else
|
||||
B fillBy_c1(Md2D* d, B x) { return c1(d->f, x); }
|
||||
B fillBy_c2(Md2D* d, B w, B x) { return c2(d->f, w,x); }
|
||||
#endif
|
||||
|
||||
#if defined(SEMANTIC_CATCH_BI)? SEMANTIC_CATCH_BI : SEMANTIC_CATCH
|
||||
extern GLOBAL B lastErrMsg; // sysfn.c
|
||||
typedef struct ReObj {
|
||||
struct CustomObj;
|
||||
B msg;
|
||||
@ -48,8 +52,6 @@ void pushRe(void) {
|
||||
B catch_c1(Md2D* d, B x) { if(CATCH) { pushRe(); B r = c1(d->g, x); dec(gsPop()); return r; } B r = c1(d->f, inc(x)); popCatch(); dec(x); return r; }
|
||||
B catch_c2(Md2D* d, B w, B x) { if(CATCH) { pushRe(); B r = c2(d->g, w,x); dec(gsPop()); return r; } B r = c2(d->f, inc(w),inc(x)); popCatch(); dec(w); dec(x); return r; }
|
||||
#else
|
||||
B fillBy_c1(Md2D* d, B x) { return c1(d->f, x); }
|
||||
B fillBy_c2(Md2D* d, B w, B x) { return c2(d->f, w,x); }
|
||||
B catch_c1(Md2D* d, B x) { return c1(d->f, x); }
|
||||
B catch_c2(Md2D* d, B w, B x) { return c2(d->f, w,x); }
|
||||
#endif
|
||||
|
||||
@ -701,7 +701,7 @@ B repl_c1(B t, B x) {
|
||||
return repl_c2(t, emptyHVec(), x);
|
||||
}
|
||||
|
||||
#if CATCH_ERRORS
|
||||
#if USE_SETJMP
|
||||
GLOBAL B lastErrMsg;
|
||||
B currentError_c1(B t, B x) {
|
||||
if (isNsp(x)) thrM("•CurrentError: Namespace 𝕩 is reserved");
|
||||
@ -1992,7 +1992,7 @@ void sysfn_init(void) {
|
||||
#undef F
|
||||
NOGC_E;
|
||||
|
||||
#if CATCH_ERRORS
|
||||
#if USE_SETJMP
|
||||
lastErrMsg = bi_N;
|
||||
gc_add_ref(&lastErrMsg);
|
||||
#endif
|
||||
|
||||
@ -59,9 +59,9 @@ static B getFillR(B x) { // doesn't consume; can return bi_noFill
|
||||
if (isC32(x)) return m_c32(' ');
|
||||
return bi_noFill;
|
||||
}
|
||||
static B getFillQ(B x) { // doesn't consume; returns 0 if !CATCH_ERRORS
|
||||
static B getFillQ(B x) { // doesn't consume; returns 0 if !SEMANTIC_CATCH
|
||||
B r = getFillR(x);
|
||||
#if CATCH_ERRORS
|
||||
#if SEMANTIC_CATCH
|
||||
return r;
|
||||
#endif
|
||||
return noFill(r)? m_f64(0) : r;
|
||||
|
||||
15
src/h.h
15
src/h.h
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef CATCH_ERRORS
|
||||
#define CATCH_ERRORS 1
|
||||
#ifndef USE_SETJMP
|
||||
#define USE_SETJMP 1
|
||||
#endif
|
||||
#ifndef ENABLE_GC
|
||||
#define ENABLE_GC 1
|
||||
@ -43,14 +43,17 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#if CATCH_ERRORS
|
||||
#if USE_SETJMP
|
||||
#include <setjmp.h>
|
||||
#endif
|
||||
|
||||
#define RT_LEN 64
|
||||
|
||||
#if CATCH_ERRORS
|
||||
#define PROPER_FILLS (EACH_FILLS&SFNS_FILLS)
|
||||
#ifndef SEMANTIC_CATCH
|
||||
#define SEMANTIC_CATCH USE_SETJMP
|
||||
#endif
|
||||
#if SEMANTIC_CATCH
|
||||
#define PROPER_FILLS (EACH_FILLS & SFNS_FILLS)
|
||||
#else
|
||||
#undef EACH_FILLS
|
||||
#define EACH_FILLS 0
|
||||
@ -393,7 +396,7 @@ NOINLINE NORETURN void rethrow(void);
|
||||
NOINLINE NORETURN void thrM(char* s);
|
||||
NOINLINE NORETURN void thrF(char* s, ...);
|
||||
NOINLINE NORETURN void thrOOM(void);
|
||||
#if CATCH_ERRORS
|
||||
#if USE_SETJMP
|
||||
jmp_buf* prepareCatch(void);
|
||||
#define CATCH setjmp(*prepareCatch()) // use as `if (CATCH) { /*handle error*/ freeThrown(); return; } /*potentially erroring thing*/ popCatch(); /*no errors yay*/`
|
||||
void popCatch(void); // note: popCatch() must always be called if no error is thrown, so no returns before it!
|
||||
|
||||
@ -659,7 +659,7 @@ B bqn_explain(B str) {
|
||||
|
||||
|
||||
static void freed_visit(Value* x) {
|
||||
#if CATCH_ERRORS
|
||||
#if USE_SETJMP
|
||||
fatal("visiting t_freed\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ void gc_visitRoots() {
|
||||
|
||||
static void gc_tryFree(Value* v) {
|
||||
u8 t = v->type;
|
||||
#if DEBUG && !CATCH_ERRORS
|
||||
#if DEBUG && !USE_SETJMP
|
||||
if (t==t_freed) fatal("GC found t_freed\n");
|
||||
#endif
|
||||
if (t!=t_empty && !(v->mmInfo&0x80)) {
|
||||
@ -62,7 +62,7 @@ static void gc_tryFree(Value* v) {
|
||||
#if DONT_FREE
|
||||
v->flags = t;
|
||||
#else
|
||||
#if CATCH_ERRORS
|
||||
#if USE_SETJMP
|
||||
if (t==t_freed) { mm_free(v); return; }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -121,7 +121,7 @@ B eachm_fn(B fo, B x, FC1 f) {
|
||||
return any_squeeze(HARR_FCD(r, x));
|
||||
}
|
||||
|
||||
#if CATCH_ERRORS
|
||||
#if SEMANTIC_CATCH
|
||||
B arith_recd(FC2 f, B w, B x) {
|
||||
B fx = getFillR(x);
|
||||
if (noFill(fx)) return eachd_fn(bi_N, w, x, f);
|
||||
|
||||
@ -4,7 +4,7 @@ B eachd_fn(B fo, B w, B x, FC2 f); // consumes w,x; assumes at least one is arra
|
||||
B eachm_fn(B fo, B x, FC1 f); // consumes x; x must be array
|
||||
|
||||
|
||||
#if CATCH_ERRORS
|
||||
#if SEMANTIC_CATCH
|
||||
NOINLINE B arith_recd(FC2 f, B w, B x);
|
||||
#else
|
||||
static inline B arith_recd(FC2 f, B w, B x) { return eachd_fn(bi_N, w, x, f); }
|
||||
|
||||
@ -128,7 +128,7 @@ void fprintsB(FILE* f, B x) {
|
||||
for (usz i = 0; i < ia; i++) {
|
||||
B c = GetU(x, i);
|
||||
if (isC32(c)) fprintCodepoint(f, o2cG(c));
|
||||
#if !CATCH_ERRORS
|
||||
#if !SEMANTIC_CATCH
|
||||
else if (c.u==0 || noFill(c)) fprintf(f, " ");
|
||||
#endif
|
||||
else thrM("Trying to output non-character");
|
||||
|
||||
8
src/vm.c
8
src/vm.c
@ -1299,7 +1299,7 @@ void comp_init(void) {
|
||||
|
||||
|
||||
typedef struct CatchFrame {
|
||||
#if CATCH_ERRORS
|
||||
#if USE_SETJMP
|
||||
jmp_buf jmp;
|
||||
#endif
|
||||
u64 gsDepth;
|
||||
@ -1310,7 +1310,7 @@ GLOBAL CatchFrame* cf; // points to after end
|
||||
GLOBAL CatchFrame* cfStart;
|
||||
GLOBAL CatchFrame* cfEnd;
|
||||
|
||||
#if CATCH_ERRORS
|
||||
#if USE_SETJMP
|
||||
jmp_buf* prepareCatch() {
|
||||
if (cf==cfEnd) {
|
||||
u64 n = cfEnd-cfStart;
|
||||
@ -1689,7 +1689,7 @@ NOINLINE NORETURN void throwImpl(bool rethrow) {
|
||||
// while (c>gStackStart) { printI(*--c); putchar('\n'); } printf("gStack printed\n");
|
||||
NOGC_CHECK("throwing during noAlloc");
|
||||
if (!rethrow) envPrevHeight = envCurr-envStart + 1;
|
||||
#if CATCH_ERRORS
|
||||
#if USE_SETJMP
|
||||
if (cf>cfStart) { // something wants to catch errors
|
||||
cf--;
|
||||
|
||||
@ -1715,7 +1715,7 @@ NOINLINE NORETURN void throwImpl(bool rethrow) {
|
||||
#else
|
||||
exit(1);
|
||||
#endif
|
||||
#if CATCH_ERRORS
|
||||
#if USE_SETJMP
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 path/to/mlochbaum/BQN"
|
||||
exit
|
||||
fi
|
||||
make f='-DDEBUG -DHEAP_VERIFY -DJIT_START=0' single-c
|
||||
make f='-DDEBUG -DHEAP_VERIFY -DUSE_SETJMP=0 -DJIT_START=0' single-c
|
||||
echo 'alljit+heapverify:' && ./BQN -M 1000 "$1/test/this.bqn" -noerr bytecode header identity literal namespace prim simple syntax token under undo unhead || exit
|
||||
echo 'native vfy:';make heapverifyn && ./BQN -M 1000 "$1/test/this.bqn" -noerr bytecode header identity literal namespace prim simple syntax token under undo unhead || exit
|
||||
echo 'native:';make o3n && ./BQN -M 1000 "$1/test/this.bqn" || exit
|
||||
|
||||
Loading…
Reference in New Issue
Block a user