err → fatal
This commit is contained in:
parent
aa68ed0730
commit
d1a5ed3e00
@ -365,7 +365,7 @@ See `#define CATCH` in `src/h.h` for how to catch errors.
|
|||||||
|
|
||||||
Use `assert(predicate)` for checks (for optimized builds they're replaced with `if (!predicate) invoke_undefined_behavior();` so it's still invoked!!). `UD;` can be used to explicitly invoke undefined behavior (equivalent in behavior to `assert(false);`), which is useful for things like untaken `default` branches in `switch` statements.
|
Use `assert(predicate)` for checks (for optimized builds they're replaced with `if (!predicate) invoke_undefined_behavior();` so it's still invoked!!). `UD;` can be used to explicitly invoke undefined behavior (equivalent in behavior to `assert(false);`), which is useful for things like untaken `default` branches in `switch` statements.
|
||||||
|
|
||||||
There's also `err("message")` that (at least currently) is kept in optimized builds as-is, and always kills the process on being called.
|
There's also `fatal("message")` that (at least currently) is kept in optimized builds as-is, and always kills the process on being called.
|
||||||
|
|
||||||
## Garbage collector
|
## Garbage collector
|
||||||
|
|
||||||
|
|||||||
@ -37,7 +37,7 @@ B type_c1(B t, B x) {
|
|||||||
else if (isNsp(x)) r = 6;
|
else if (isNsp(x)) r = 6;
|
||||||
if (RARE(r==-1)) {
|
if (RARE(r==-1)) {
|
||||||
if (x.u == bi_optOut.u) thrM("Reading variable that was optimized out by F↩ after error");
|
if (x.u == bi_optOut.u) thrM("Reading variable that was optimized out by F↩ after error");
|
||||||
printI(x); err(": getting type");
|
printI(x); fatal(": getting type");
|
||||||
}
|
}
|
||||||
decR(x);
|
decR(x);
|
||||||
return m_i32(r);
|
return m_i32(r);
|
||||||
@ -972,7 +972,7 @@ extern char** environ;
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
typedef struct pollfd pollfd;
|
typedef struct pollfd pollfd;
|
||||||
void shClose(int fd) { if (close(fd)) err("bad file descriptor close"); }
|
void shClose(int fd) { if (close(fd)) fatal("bad file descriptor close"); }
|
||||||
|
|
||||||
// #define shDbg(...) printf(__VA_ARGS__); fflush(stdout)
|
// #define shDbg(...) printf(__VA_ARGS__); fflush(stdout)
|
||||||
#define shDbg(...)
|
#define shDbg(...)
|
||||||
|
|||||||
@ -62,7 +62,7 @@ static void harrP_visit(Value* x) { assert(PTY(x) == t_harrPartial);
|
|||||||
usz am = PIA((HArr*)x);
|
usz am = PIA((HArr*)x);
|
||||||
for (usz i = 0; i < am; i++) mm_visit(p[i]);
|
for (usz i = 0; i < am; i++) mm_visit(p[i]);
|
||||||
}
|
}
|
||||||
static B harrP_get(Arr* x, usz n) { err("getting item from t_harrPartial"); }
|
static B harrP_get(Arr* x, usz n) { fatal("getting item from t_harrPartial"); }
|
||||||
static void harrP_print(FILE* f, B x) {
|
static void harrP_print(FILE* f, B x) {
|
||||||
B* p = c(HArr,x)->a;
|
B* p = c(HArr,x)->a;
|
||||||
usz am = *SH(x);
|
usz am = *SH(x);
|
||||||
|
|||||||
@ -9,23 +9,24 @@ bool please_tail_call_err = true;
|
|||||||
|
|
||||||
void before_exit(void);
|
void before_exit(void);
|
||||||
bool inErr;
|
bool inErr;
|
||||||
NORETURN NOINLINE void err(char* s) {
|
NORETURN NOINLINE void fatal(char* s) {
|
||||||
NOGC_E;
|
NOGC_E;
|
||||||
#if MM!=0
|
#if MM!=0
|
||||||
gc_depth=1;
|
gc_depth=1;
|
||||||
#endif
|
#endif
|
||||||
if (inErr) {
|
if (inErr) {
|
||||||
fputs("\nCBQN encountered fatal error during information printing of another fatal error. Exiting without printing more info.", stderr);
|
fputs("\nCBQN encountered a fatal error during information printing of another fatal error. Exiting without printing more info.", stderr);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
__builtin_trap();
|
__builtin_trap();
|
||||||
#endif
|
#endif
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
inErr = true;
|
inErr = true;
|
||||||
fputs(s, stderr); fputc('\n', stderr); fflush(stderr);
|
fputs("CBQN encountered a fatal error: ", stderr); fflush(stderr);
|
||||||
|
fputs(s, stderr); fflush(stderr);
|
||||||
|
fputc('\n', stderr); fflush(stderr);
|
||||||
vm_pstLive(); fflush(stderr); fflush(stdout);
|
vm_pstLive(); fflush(stderr); fflush(stdout);
|
||||||
print_vmStack(); fflush(stderr);
|
print_vmStack(); fflush(stderr);
|
||||||
fputs("CBQN interpreter entered unexpected state, exiting.\n", stderr);
|
|
||||||
before_exit();
|
before_exit();
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
__builtin_trap();
|
__builtin_trap();
|
||||||
@ -221,7 +222,7 @@ NOINLINE B do_fmt(B s, char* p, va_list a) {
|
|||||||
while (*p != 0) { c = *p++;
|
while (*p != 0) { c = *p++;
|
||||||
if (c!='%') continue;
|
if (c!='%') continue;
|
||||||
if (lp!=p-1) AJOIN(utf8Decode(lp, p-1-lp));
|
if (lp!=p-1) AJOIN(utf8Decode(lp, p-1-lp));
|
||||||
switch(c = *p++) { default: printf("Unknown format character '%c'", c); err(""); UD;
|
switch(c = *p++) { default: printf("Unknown format character '%c'", c); fatal(""); UD;
|
||||||
case 'R': {
|
case 'R': {
|
||||||
B b = va_arg(a, B);
|
B b = va_arg(a, B);
|
||||||
if (isNum(b)) AFMT("%f", o2f(b));
|
if (isNum(b)) AFMT("%f", o2f(b));
|
||||||
@ -238,7 +239,7 @@ NOINLINE B do_fmt(B s, char* p, va_list a) {
|
|||||||
ur r;
|
ur r;
|
||||||
usz* sh;
|
usz* sh;
|
||||||
if (c=='2') {
|
if (c=='2') {
|
||||||
if ('H' != *p++) err("Invalid format string: expected H after %2");
|
if ('H' != *p++) fatal("Invalid format string: expected H after %2");
|
||||||
r = va_arg(a, int);
|
r = va_arg(a, int);
|
||||||
sh = va_arg(a, usz*);
|
sh = va_arg(a, usz*);
|
||||||
} else {
|
} else {
|
||||||
@ -512,7 +513,7 @@ void g_pst(void) { vm_pstLive(); fflush(stdout); fflush(stderr); }
|
|||||||
PRINT_ID(x);
|
PRINT_ID(x);
|
||||||
fprintf(stderr, "bad refcount for type %d @ %p: %d\nattempting to print: ", x->type, x, x->refc); fflush(stderr);
|
fprintf(stderr, "bad refcount for type %d @ %p: %d\nattempting to print: ", x->type, x, x->refc); fflush(stderr);
|
||||||
fprintI(stderr, tag(x,OBJ_TAG)); fputc('\n', stderr); fflush(stderr);
|
fprintI(stderr, tag(x,OBJ_TAG)); fputc('\n', stderr); fflush(stderr);
|
||||||
err("");
|
fatal("");
|
||||||
}
|
}
|
||||||
if (TIv(x,isArr)) {
|
if (TIv(x,isArr)) {
|
||||||
Arr* a = (Arr*)x;
|
Arr* a = (Arr*)x;
|
||||||
@ -531,13 +532,13 @@ void g_pst(void) { vm_pstLive(); fflush(stdout); fflush(stderr); }
|
|||||||
fprintf(stderr, "bad array tag/type: type=%d, obj=%p\n", v(x)->type, TOPTR(void, x.u));
|
fprintf(stderr, "bad array tag/type: type=%d, obj=%p\n", v(x)->type, TOPTR(void, x.u));
|
||||||
PRINT_ID(v(x));
|
PRINT_ID(v(x));
|
||||||
fprintI(stderr, x);
|
fprintI(stderr, x);
|
||||||
err("\n");
|
fatal("\n");
|
||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
NOINLINE NORETURN void assert_fail(char* expr, char* file, int line, const char fn[]) {
|
NOINLINE NORETURN void assert_fail(char* expr, char* file, int line, const char fn[]) {
|
||||||
fprintf(stderr, "%s:%d: %s: Assertion `%s` failed.\n", file, line, fn, expr);
|
fprintf(stderr, "%s:%d: %s: Assertion `%s` failed.\n", file, line, fn, expr);
|
||||||
err("");
|
fatal("");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if WARN_SLOW
|
#if WARN_SLOW
|
||||||
|
|||||||
@ -367,7 +367,7 @@ FORCE_INLINE void preFree(Value* x, bool mmx) {
|
|||||||
if (!mmx) tailVerifyFree(x);
|
if (!mmx) tailVerifyFree(x);
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (x->type==t_empty) err("double-free");
|
if (x->type==t_empty) fatal("double-free");
|
||||||
// u32 undef;
|
// u32 undef;
|
||||||
// x->refc = undef;
|
// x->refc = undef;
|
||||||
x->refc = -1431655000;
|
x->refc = -1431655000;
|
||||||
|
|||||||
@ -972,7 +972,7 @@ void ffi_init(void) {
|
|||||||
#else // i.e. FFI==0
|
#else // i.e. FFI==0
|
||||||
#if !FOR_BUILD
|
#if !FOR_BUILD
|
||||||
void ffi_init() { }
|
void ffi_init() { }
|
||||||
B ffiload_c2(B t, B w, B x) { err("•FFI called"); }
|
B ffiload_c2(B t, B w, B x) { fatal("•FFI called"); }
|
||||||
#else // whatever build.bqn uses from •FFI
|
#else // whatever build.bqn uses from •FFI
|
||||||
#include "nfns.h"
|
#include "nfns.h"
|
||||||
#include "utils/cstr.h"
|
#include "utils/cstr.h"
|
||||||
@ -982,7 +982,7 @@ void ffi_init(void) {
|
|||||||
NFnDesc* forbuildDesc;
|
NFnDesc* forbuildDesc;
|
||||||
B forbuild_c1(B t, B x) {
|
B forbuild_c1(B t, B x) {
|
||||||
i32 id = o2i(nfn_objU(t));
|
i32 id = o2i(nfn_objU(t));
|
||||||
switch (id) { default: err("bad id");
|
switch (id) { default: fatal("bad id");
|
||||||
case 0: {
|
case 0: {
|
||||||
char* s = toCStr(x);
|
char* s = toCStr(x);
|
||||||
decG(x);
|
decG(x);
|
||||||
|
|||||||
4
src/h.h
4
src/h.h
@ -327,7 +327,7 @@ typedef struct Arr {
|
|||||||
#define UD assert(false)
|
#define UD assert(false)
|
||||||
extern bool cbqn_noAlloc;
|
extern bool cbqn_noAlloc;
|
||||||
NOINLINE void cbqn_NOGC_start(); // function to allow breakpointing
|
NOINLINE void cbqn_NOGC_start(); // function to allow breakpointing
|
||||||
#define NOGC_CHECK if (cbqn_noAlloc && !gc_depth) err("allocating during noalloc");
|
#define NOGC_CHECK if (cbqn_noAlloc && !gc_depth) fatal("allocating during noalloc");
|
||||||
#define NOGC_S cbqn_NOGC_start()
|
#define NOGC_S cbqn_NOGC_start()
|
||||||
#define NOGC_E cbqn_noAlloc=false
|
#define NOGC_E cbqn_noAlloc=false
|
||||||
#else
|
#else
|
||||||
@ -451,7 +451,7 @@ void print_vmStack(void);
|
|||||||
B validate(B x);
|
B validate(B x);
|
||||||
Value* validateP(Value* x);
|
Value* validateP(Value* x);
|
||||||
#endif
|
#endif
|
||||||
NORETURN NOINLINE void err(char* s);
|
NORETURN NOINLINE void fatal(char* s);
|
||||||
|
|
||||||
// tag checks
|
// tag checks
|
||||||
FORCE_INLINE bool isFun(B x) { return (x.u>>48) == FUN_TAG; }
|
FORCE_INLINE bool isFun(B x) { return (x.u>>48) == FUN_TAG; }
|
||||||
|
|||||||
@ -42,7 +42,7 @@ static void* mmap_nvm(u64 sz) {
|
|||||||
i32 attempt = 0;
|
i32 attempt = 0;
|
||||||
// printf("binary at %p\n", &bqn_exec);
|
// printf("binary at %p\n", &bqn_exec);
|
||||||
while(true) {
|
while(true) {
|
||||||
if (attempt++ > 200) err("Failed to allocate memory for JIT 200 times; stopping trying");
|
if (attempt++ > 200) fatal("Failed to allocate memory for JIT 200 times; stopping trying");
|
||||||
u64 randOff = wyrand(&nvm_mmap_seed) & (MAX_DIST>>1)-1;
|
u64 randOff = wyrand(&nvm_mmap_seed) & (MAX_DIST>>1)-1;
|
||||||
u64 loc = near+randOff & ~(ps-1);
|
u64 loc = near+randOff & ~(ps-1);
|
||||||
// printf("request %d: %p\n", attempt, (void*)loc);
|
// printf("request %d: %p\n", attempt, (void*)loc);
|
||||||
@ -304,7 +304,7 @@ static OptRes opt(u32* bc0) {
|
|||||||
u8 cact = 0;
|
u8 cact = 0;
|
||||||
#define L64 ({ u64 r = bc[0] | ((u64)bc[1])<<32; bc+= 2; r; })
|
#define L64 ({ u64 r = bc[0] | ((u64)bc[1])<<32; bc+= 2; r; })
|
||||||
#define S(N,I) SRef N = stk[TSSIZE(stk)-1-(I)];
|
#define S(N,I) SRef N = stk[TSSIZE(stk)-1-(I)];
|
||||||
switch (*bc++) { case FN1Ci: case FN1Oi: case FN2Ci: case FN2Oi: err("optimization: didn't expect already immediate FN__");
|
switch (*bc++) { case FN1Ci: case FN1Oi: case FN2Ci: case FN2Oi: fatal("optimization: didn't expect already immediate FN__");
|
||||||
case ADDU: case ADDI: cact = 0; TSADD(stk,SREF(b(L64), pos)); break;
|
case ADDU: case ADDI: cact = 0; TSADD(stk,SREF(b(L64), pos)); break;
|
||||||
case POPS: { assert(TSSIZE(actions) > 0);
|
case POPS: { assert(TSSIZE(actions) > 0);
|
||||||
u64 asz = TSSIZE(actions);
|
u64 asz = TSSIZE(actions);
|
||||||
@ -366,7 +366,7 @@ static OptRes opt(u32* bc0) {
|
|||||||
}
|
}
|
||||||
case TR3D: case TR3O: { S(f,0) S(g,1) S(h,2)
|
case TR3D: case TR3O: { S(f,0) S(g,1) S(h,2)
|
||||||
if (f.p==-1 | g.p==-1 | h.p==-1) goto defIns;
|
if (f.p==-1 | g.p==-1 | h.p==-1) goto defIns;
|
||||||
if (q_N(f.v)) err("JIT optimization: didn't expect constant ·");
|
if (q_N(f.v)) fatal("JIT optimization: didn't expect constant ·");
|
||||||
B d = m_fork(inc(f.v), inc(g.v), inc(h.v));
|
B d = m_fork(inc(f.v), inc(g.v), inc(h.v));
|
||||||
cact = 5; RM(f.p); RM(g.p); RM(h.p);
|
cact = 5; RM(f.p); RM(g.p); RM(h.p);
|
||||||
TSADD(data, d.u);
|
TSADD(data, d.u);
|
||||||
@ -680,7 +680,7 @@ Nvm_res m_nvm(Body* body) {
|
|||||||
case DFND0: case DFND1: case DFND2: TOPs; // (u32* bc, Scope* sc, Block* bl)
|
case DFND0: case DFND1: case DFND2: TOPs; // (u32* bc, Scope* sc, Block* bl)
|
||||||
Block* bl = (Block*)L64;
|
Block* bl = (Block*)L64;
|
||||||
u64 fn = (u64)(bl->ty==0? i_DFND_0 : bl->ty==1? i_DFND_1 : bl->ty==2? i_DFND_2 : NULL);
|
u64 fn = (u64)(bl->ty==0? i_DFND_0 : bl->ty==1? i_DFND_1 : bl->ty==2? i_DFND_2 : NULL);
|
||||||
if (fn==0) err("JIT: Bad DFND argument");
|
if (fn==0) fatal("JIT: Bad DFND argument");
|
||||||
GET(R_A3,-1,2);
|
GET(R_A3,-1,2);
|
||||||
IMM(R_A0,off); MOV(R_A1,r_SC); IMM(R_A2,bl); CCALL(fn);
|
IMM(R_A0,off); MOV(R_A1,r_SC); IMM(R_A2,bl); CCALL(fn);
|
||||||
break;
|
break;
|
||||||
@ -726,7 +726,7 @@ Nvm_res m_nvm(Body* body) {
|
|||||||
case RETD: if (lGPos!=0) GS_SET(r_CS); MOV(R_A0,r_SC); CCALL(i_RETD); ret=true; break; // (Scope* sc)
|
case RETD: if (lGPos!=0) GS_SET(r_CS); MOV(R_A0,r_SC); CCALL(i_RETD); ret=true; break; // (Scope* sc)
|
||||||
case RETN: if (lGPos!=0) GS_SET(r_CS); ret=true; break;
|
case RETN: if (lGPos!=0) GS_SET(r_CS); ret=true; break;
|
||||||
case FAIL: TOPs; IMM(R_A0,off); MOV(R_A1,r_SC); INV(2,0,i_FAIL); ret=true; break;
|
case FAIL: TOPs; IMM(R_A0,off); MOV(R_A1,r_SC); INV(2,0,i_FAIL); ret=true; break;
|
||||||
default: print_fmt("JIT: Unsupported bytecode %i/%S\n", *s, bc_repr(*s)); err("");
|
default: print_fmt("JIT: Unsupported bytecode %i/%S\n", *s, bc_repr(*s)); fatal("");
|
||||||
}
|
}
|
||||||
#undef GET
|
#undef GET
|
||||||
#undef GS_SET
|
#undef GS_SET
|
||||||
@ -739,7 +739,7 @@ Nvm_res m_nvm(Body* body) {
|
|||||||
#undef INV
|
#undef INV
|
||||||
#undef SPOS
|
#undef SPOS
|
||||||
#undef L64
|
#undef L64
|
||||||
if (n!=bc) err("JIT: Wrong parsing of bytecode");
|
if (n!=bc) fatal("JIT: Wrong parsing of bytecode");
|
||||||
depth+= stackDiff(s);
|
depth+= stackDiff(s);
|
||||||
if (ret) break;
|
if (ret) break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -171,8 +171,8 @@ static const u8 cL = 0xC; static const u8 cGE = 0xD;
|
|||||||
static const u8 cLE = 0xE; static const u8 cG = 0xF;
|
static const u8 cLE = 0xE; static const u8 cG = 0xF;
|
||||||
#define J1(T, L) u64 L=ASM_SIZE; { ASMS; ASM1((i8)(0x70+(T)));ASM1(-2);ASME; } // -2 comes from the instruction being 2 bytes long and L being defined at the start
|
#define J1(T, L) u64 L=ASM_SIZE; { ASMS; ASM1((i8)(0x70+(T)));ASM1(-2);ASME; } // -2 comes from the instruction being 2 bytes long and L being defined at the start
|
||||||
#define J4(T, L) u64 L=ASM_SIZE; { ASMS; ASM1(0x0f);ASM1((i8)(0x80+(T)));ASM4(-6);ASME; }
|
#define J4(T, L) u64 L=ASM_SIZE; { ASMS; ASM1(0x0f);ASM1((i8)(0x80+(T)));ASM4(-6);ASME; }
|
||||||
#define LBL1(L) { i64 t= (i8)asm_ins.s[L+1] + ASM_SIZE-(i64)L; if(t!=(i8 )t) err("x86-64 codegen: jump too long!"); asm_ins.s[L+1] = t; }
|
#define LBL1(L) { i64 t= (i8)asm_ins.s[L+1] + ASM_SIZE-(i64)L; if(t!=(i8 )t) fatal("x86-64 codegen: jump too long!"); asm_ins.s[L+1] = t; }
|
||||||
#define LBL4(L) { i64 t=asm_r4(asm_ins.s+(L+2)) + ASM_SIZE-(i64)L; if(t!=(i32)t) err("x86-64 codegen: jump too long!"); asm_w4(asm_ins.s+(L+2), t); }
|
#define LBL4(L) { i64 t=asm_r4(asm_ins.s+(L+2)) + ASM_SIZE-(i64)L; if(t!=(i32)t) fatal("x86-64 codegen: jump too long!"); asm_w4(asm_ins.s+(L+2), t); }
|
||||||
|
|
||||||
#define ASMS u8* ic=asm_ins.c
|
#define ASMS u8* ic=asm_ins.c
|
||||||
#define ASME asm_ins.c = ic; asm_r()
|
#define ASME asm_ins.c = ic; asm_r()
|
||||||
|
|||||||
24
src/load.c
24
src/load.c
@ -438,7 +438,7 @@ void load_init() { // very last init function
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (IA(rtObjRaw) != RT_LEN) err("incorrectly defined RT_LEN!");
|
if (IA(rtObjRaw) != RT_LEN) fatal("incorrectly defined RT_LEN!");
|
||||||
HArr_p runtimeH = m_harrUc(rtObjRaw);
|
HArr_p runtimeH = m_harrUc(rtObjRaw);
|
||||||
SGet(rtObjRaw)
|
SGet(rtObjRaw)
|
||||||
|
|
||||||
@ -461,11 +461,11 @@ void load_init() { // very last init function
|
|||||||
#else
|
#else
|
||||||
bool nnbi = !rtComplete[i];
|
bool nnbi = !rtComplete[i];
|
||||||
#if !defined(WRAP_NNBI)
|
#if !defined(WRAP_NNBI)
|
||||||
if (nnbi) err("Refusing to load non-native builtin into runtime without -DWRAP_NNBI");
|
if (nnbi) fatal("Refusing to load non-native builtin into runtime without -DWRAP_NNBI");
|
||||||
#endif
|
#endif
|
||||||
B r = nnbi? Get(rtObjRaw, i) : inc(fruntime[i]);
|
B r = nnbi? Get(rtObjRaw, i) : inc(fruntime[i]);
|
||||||
#endif
|
#endif
|
||||||
if (q_N(r)) err("· in runtime!\n");
|
if (q_N(r)) fatal("· in runtime!\n");
|
||||||
if (isVal(r)) v(r)->flags|= i+1;
|
if (isVal(r)) v(r)->flags|= i+1;
|
||||||
#if defined(RT_WRAP) || defined(WRAP_NNBI)
|
#if defined(RT_WRAP) || defined(WRAP_NNBI)
|
||||||
r = rtWrap_wrap(r, nnbi);
|
r = rtWrap_wrap(r, nnbi);
|
||||||
@ -598,21 +598,21 @@ B bqn_explain(B str, B path) {
|
|||||||
|
|
||||||
static void freed_visit(Value* x) {
|
static void freed_visit(Value* x) {
|
||||||
#if CATCH_ERRORS
|
#if CATCH_ERRORS
|
||||||
err("visiting t_freed\n");
|
fatal("visiting t_freed\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
static void empty_free(Value* x) { err("FREEING EMPTY\n"); }
|
static void empty_free(Value* x) { fatal("FREEING EMPTY\n"); }
|
||||||
static void builtin_free(Value* x) { err("FREEING BUILTIN\n"); }
|
static void builtin_free(Value* x) { fatal("FREEING BUILTIN\n"); }
|
||||||
DEF_FREE(def) { }
|
DEF_FREE(def) { }
|
||||||
static void def_visit(Value* x) { err("undefined visit for object\n"); }
|
static void def_visit(Value* x) { fatal("undefined visit for object\n"); }
|
||||||
static void def_print(FILE* f, B x) { fprintf(f, "(%d=%s)", v(x)->type, type_repr(v(x)->type)); }
|
static void def_print(FILE* f, B x) { fprintf(f, "(%d=%s)", v(x)->type, type_repr(v(x)->type)); }
|
||||||
static bool def_canStore(B x) { return false; }
|
static bool def_canStore(B x) { return false; }
|
||||||
static B def_identity(B f) { return bi_N; }
|
static B def_identity(B f) { return bi_N; }
|
||||||
static B def_get(Arr* x, usz n) { err("def_get"); }
|
static B def_get(Arr* x, usz n) { fatal("def_get"); }
|
||||||
static B def_getU(Arr* x, usz n) { err("def_getU"); }
|
static B def_getU(Arr* x, usz n) { fatal("def_getU"); }
|
||||||
static B def_m1_d(B m, B f ) { thrM("cannot derive this"); }
|
static B def_m1_d(B m, B f ) { thrM("cannot derive this"); }
|
||||||
static B def_m2_d(B m, B f, B g) { thrM("cannot derive this"); }
|
static B def_m2_d(B m, B f, B g) { thrM("cannot derive this"); }
|
||||||
static Arr* def_slice(B x, usz s, usz ia) { err("cannot slice non-array!"); }
|
static Arr* def_slice(B x, usz s, usz ia) { fatal("cannot slice non-array!"); }
|
||||||
|
|
||||||
B rt_invFnReg, rt_invFnSwap;
|
B rt_invFnReg, rt_invFnSwap;
|
||||||
FC1 rt_invFnRegFn;
|
FC1 rt_invFnRegFn;
|
||||||
@ -631,14 +631,14 @@ B def_m2_ix(Md2D* t, B w, B x) { return def_fn_ix(tag(t,FUN_TAG), w, x); }
|
|||||||
#ifdef DONT_FREE
|
#ifdef DONT_FREE
|
||||||
static B empty_get(Arr* x, usz n) {
|
static B empty_get(Arr* x, usz n) {
|
||||||
x->type = x->flags;
|
x->type = x->flags;
|
||||||
if (x->type==t_empty) err("getting from empty without old type data");
|
if (x->type==t_empty) fatal("getting from empty without old type data");
|
||||||
B r = TIv(x,get)(x, n);
|
B r = TIv(x,get)(x, n);
|
||||||
x->type = t_empty;
|
x->type = t_empty;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
static B empty_getU(Arr* x, usz n) {
|
static B empty_getU(Arr* x, usz n) {
|
||||||
x->type = x->flags;
|
x->type = x->flags;
|
||||||
if (x->type==t_empty) err("getting from empty without old type data");
|
if (x->type==t_empty) fatal("getting from empty without old type data");
|
||||||
B r = TIv(x,getU)(x, n);
|
B r = TIv(x,getU)(x, n);
|
||||||
x->type = t_empty;
|
x->type = t_empty;
|
||||||
return r;
|
return r;
|
||||||
|
|||||||
@ -30,7 +30,7 @@ B nfn_name(B x) { VTY(x, t_nfn);
|
|||||||
DEF_FREE(nfn) { dec(((NFn*)x)->obj); }
|
DEF_FREE(nfn) { dec(((NFn*)x)->obj); }
|
||||||
void nfn_visit(Value* x) { mm_visit(((NFn*)x)->obj); }
|
void nfn_visit(Value* x) { mm_visit(((NFn*)x)->obj); }
|
||||||
void nfn_print(FILE* f, B x) { fprintsB(f, c(NFnDesc,IGetU(nfn_list,c(NFn,x)->id))->name); }
|
void nfn_print(FILE* f, B x) { fprintsB(f, c(NFnDesc,IGetU(nfn_list,c(NFn,x)->id))->name); }
|
||||||
DEF_FREE(nfnDesc) { err("nfnDesc shouldn't be freed!"); }
|
DEF_FREE(nfnDesc) { fatal("nfnDesc shouldn't be freed!"); }
|
||||||
void nfnDesc_visit(Value* x) { mm_visit(((NFnDesc*)x)->name); }
|
void nfnDesc_visit(Value* x) { mm_visit(((NFnDesc*)x)->name); }
|
||||||
void nfnDesc_print(FILE* f, B x) { fprintf(f, "(native function description)"); }
|
void nfnDesc_print(FILE* f, B x) { fprintf(f, "(native function description)"); }
|
||||||
|
|
||||||
|
|||||||
10
src/opt/gc.c
10
src/opt/gc.c
@ -14,7 +14,7 @@ u64 gc_depth = 1;
|
|||||||
vfn gc_roots[8];
|
vfn gc_roots[8];
|
||||||
u32 gc_rootSz;
|
u32 gc_rootSz;
|
||||||
void gc_addFn(vfn f) {
|
void gc_addFn(vfn f) {
|
||||||
if (gc_rootSz>=8) err("Too many GC root functions");
|
if (gc_rootSz>=8) fatal("Too many GC root functions");
|
||||||
gc_roots[gc_rootSz++] = f;
|
gc_roots[gc_rootSz++] = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,13 +22,13 @@ Value* gc_rootObjs[512];
|
|||||||
u32 gc_rootObjSz;
|
u32 gc_rootObjSz;
|
||||||
void gc_add(B x) {
|
void gc_add(B x) {
|
||||||
assert(isVal(x));
|
assert(isVal(x));
|
||||||
if (gc_rootObjSz>=512) err("Too many GC root objects");
|
if (gc_rootObjSz>=512) fatal("Too many GC root objects");
|
||||||
gc_rootObjs[gc_rootObjSz++] = v(x);
|
gc_rootObjs[gc_rootObjSz++] = v(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
B* gc_rootBRefs[64]; u32 gc_rootBRefsSz;
|
B* gc_rootBRefs[64]; u32 gc_rootBRefsSz;
|
||||||
void gc_add_ref(B* x) {
|
void gc_add_ref(B* x) {
|
||||||
if (gc_rootBRefsSz>=64) err("Too many GC root B refs");
|
if (gc_rootBRefsSz>=64) fatal("Too many GC root B refs");
|
||||||
gc_rootBRefs[gc_rootBRefsSz++] = x;
|
gc_rootBRefs[gc_rootBRefsSz++] = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ void gc_visitRoots() {
|
|||||||
static void gc_tryFree(Value* v) {
|
static void gc_tryFree(Value* v) {
|
||||||
u8 t = v->type;
|
u8 t = v->type;
|
||||||
#if defined(DEBUG) && !defined(CATCH_ERRORS)
|
#if defined(DEBUG) && !defined(CATCH_ERRORS)
|
||||||
if (t==t_freed) err("GC found t_freed\n");
|
if (t==t_freed) fatal("GC found t_freed\n");
|
||||||
#endif
|
#endif
|
||||||
if (t!=t_empty && !(v->mmInfo&0x80)) {
|
if (t!=t_empty && !(v->mmInfo&0x80)) {
|
||||||
if (t==t_shape || t==t_temp || t==t_talloc) return;
|
if (t==t_shape || t==t_temp || t==t_talloc) return;
|
||||||
@ -90,7 +90,7 @@ void gc_onVisit(Value* x) {
|
|||||||
switch (visit_mode) { default: UD;
|
switch (visit_mode) { default: UD;
|
||||||
case GC_DEC_REFC:
|
case GC_DEC_REFC:
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if(x->refc==0) err("decrementing refc 0");
|
if(x->refc==0) fatal("decrementing refc 0");
|
||||||
#endif
|
#endif
|
||||||
x->refc--;
|
x->refc--;
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -80,7 +80,7 @@ static NOINLINE void* BN(allocateMore)(i64 bucket, u8 type, i64 from, i64 to) {
|
|||||||
fprintf(stderr, ": got %p\n", mem);
|
fprintf(stderr, ": got %p\n", mem);
|
||||||
#endif
|
#endif
|
||||||
if (mem==MAP_FAILED) thrOOM();
|
if (mem==MAP_FAILED) thrOOM();
|
||||||
if (ptr2u64(mem)+sz > (1ULL<<48)) err("mmap returned address range above 2⋆48");
|
if (ptr2u64(mem)+sz > (1ULL<<48)) fatal("mmap returned address range above 2⋆48");
|
||||||
#if ALLOC_MODE==0
|
#if ALLOC_MODE==0
|
||||||
// ux off = offsetof(TyArr,a);
|
// ux off = offsetof(TyArr,a);
|
||||||
// if (off&31) mem+= 32-(off&31); // align heap such that arr->a is 32-byte-aligned
|
// if (off&31) mem+= 32-(off&31); // align heap such that arr->a is 32-byte-aligned
|
||||||
|
|||||||
@ -32,7 +32,7 @@ void mm_dumpHeap(FILE* f);
|
|||||||
static u64 mm_round(usz x) { return x; }
|
static u64 mm_round(usz x) { return x; }
|
||||||
static u64 mm_size(Value* x) {
|
static u64 mm_size(Value* x) {
|
||||||
size_t r = malloc_usable_size(x);
|
size_t r = malloc_usable_size(x);
|
||||||
if (((ssize_t)r) < 16) err("MM=0 requires working malloc_usable_size");
|
if (((ssize_t)r) < 16) fatal("MM=0 requires working malloc_usable_size");
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
static u64 mm_totalAllocated() { return -1; }
|
static u64 mm_totalAllocated() { return -1; }
|
||||||
|
|||||||
@ -129,7 +129,7 @@ B vec_join(B w, B x) {
|
|||||||
} \
|
} \
|
||||||
static RT m_##N##G_##TY ARGS
|
static RT m_##N##G_##TY ARGS
|
||||||
|
|
||||||
DEF_S(void, set, MAX, false, x, (void* a, usz ms, B x), ms, x) { err("m_setG_MAX"); }
|
DEF_S(void, set, MAX, false, x, (void* a, usz ms, B x), ms, x) { fatal("m_setG_MAX"); }
|
||||||
DEF_S(void, set, bit, q_bit(x), x, (void* a, usz ms, B x), ms, x) { bitp_set((u64*)a, ms, o2bG(x)); }
|
DEF_S(void, set, bit, q_bit(x), x, (void* a, usz ms, B x), ms, x) { bitp_set((u64*)a, ms, o2bG(x)); }
|
||||||
DEF_S(void, set, i8, q_i8 (x), x, (void* a, usz ms, B x), ms, x) { (( i8*)a)[ms] = o2iG(x); }
|
DEF_S(void, set, i8, q_i8 (x), x, (void* a, usz ms, B x), ms, x) { (( i8*)a)[ms] = o2iG(x); }
|
||||||
DEF_S(void, set, i16, q_i16(x), x, (void* a, usz ms, B x), ms, x) { ((i16*)a)[ms] = o2iG(x); }
|
DEF_S(void, set, i16, q_i16(x), x, (void* a, usz ms, B x), ms, x) { ((i16*)a)[ms] = o2iG(x); }
|
||||||
@ -140,7 +140,7 @@ DEF_S(void, set, c32, q_c32(x), x, (void* a, usz ms, B x), ms, x) { ((u32*)a)[ms
|
|||||||
DEF_S(void, set, f64, q_f64(x), x, (void* a, usz ms, B x), ms, x) { ((f64*)a)[ms] = o2fG(x); }
|
DEF_S(void, set, f64, q_f64(x), x, (void* a, usz ms, B x), ms, x) { ((f64*)a)[ms] = o2fG(x); }
|
||||||
DEF_G(void, set, B, (void* a, usz ms, B x), ms, x) { (( B*)a)[ms] = x; }
|
DEF_G(void, set, B, (void* a, usz ms, B x), ms, x) { (( B*)a)[ms] = x; }
|
||||||
|
|
||||||
DEF_S(void, fill, MAX, false, x, (void* a, usz ms, B x, usz l), ms, x, l) { err("m_fillG_MAX"); }
|
DEF_S(void, fill, MAX, false, x, (void* a, usz ms, B x, usz l), ms, x, l) { fatal("m_fillG_MAX"); }
|
||||||
DEF_S(void, fill, bit, q_bit(x), x, (void* a, usz ms, B x, usz l), ms, x, l) { u64* p = (u64*)a; bool v = o2bG(x);
|
DEF_S(void, fill, bit, q_bit(x), x, (void* a, usz ms, B x, usz l), ms, x, l) { u64* p = (u64*)a; bool v = o2bG(x);
|
||||||
usz me = ms+l;
|
usz me = ms+l;
|
||||||
if (ms>>6 == me>>6) {
|
if (ms>>6 == me>>6) {
|
||||||
@ -230,7 +230,7 @@ DEF_COPY(c32, { u32* rp = ms+(u32*)a; void* xp = tyany_ptr(x);
|
|||||||
case t_c32arr: case t_c32slice: PTR_COPY(u32, u32)
|
case t_c32arr: case t_c32slice: PTR_COPY(u32, u32)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
DEF_E(void, copy, MAX, false, x, (void* a, usz ms, B x, usz xs, usz l), ms, x, xs, l) { err("m_copyG_MAX"); }
|
DEF_E(void, copy, MAX, false, x, (void* a, usz ms, B x, usz xs, usz l), ms, x, xs, l) { fatal("m_copyG_MAX"); }
|
||||||
NOINLINE void m_copyG_B_generic(void* a, B* mpo, B x, usz xs, usz l) {
|
NOINLINE void m_copyG_B_generic(void* a, B* mpo, B x, usz xs, usz l) {
|
||||||
SLOW1("copyG", x);
|
SLOW1("copyG", x);
|
||||||
SGet(x)
|
SGet(x)
|
||||||
@ -269,7 +269,7 @@ DEF_G(void, copy, B, (void* a, usz ms, B x, usz xs, usz l), ms, x, x
|
|||||||
typedef void (*copy_fn)(void*, void*, u64, void*);
|
typedef void (*copy_fn)(void*, void*, u64, void*);
|
||||||
|
|
||||||
static void badCopy(void* xp, void* rp, u64 len, void* xRaw) {
|
static void badCopy(void* xp, void* rp, u64 len, void* xRaw) {
|
||||||
err("Copying wrong array type");
|
fatal("Copying wrong array type");
|
||||||
}
|
}
|
||||||
|
|
||||||
#define COPY_FN(X,R) simd_copy_##X##_##R
|
#define COPY_FN(X,R) simd_copy_##X##_##R
|
||||||
@ -423,7 +423,7 @@ DEF_G(void, copy, B, (void* a, usz ms, B x, usz xs, usz l), ms, x, x
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static B m_getU_MAX(void* a, usz ms) { err("m_setG_MAX"); }
|
static B m_getU_MAX(void* a, usz ms) { fatal("m_setG_MAX"); }
|
||||||
static B m_getU_bit(void* a, usz ms) { return m_i32(bitp_get(((u64*) a), ms)); }
|
static B m_getU_bit(void* a, usz ms) { return m_i32(bitp_get(((u64*) a), ms)); }
|
||||||
static B m_getU_i8 (void* a, usz ms) { return m_i32(((i8* ) a)[ms]); }
|
static B m_getU_i8 (void* a, usz ms) { return m_i32(((i8* ) a)[ms]); }
|
||||||
static B m_getU_i16(void* a, usz ms) { return m_i32(((i16*) a)[ms]); }
|
static B m_getU_i16(void* a, usz ms) { return m_i32(((i16*) a)[ms]); }
|
||||||
@ -462,8 +462,8 @@ NOINLINE void apd_sh_fail(ApdMut* m, B x, u8 mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
void apd_dbg_apd(ApdMut* m, B x) { err("ApdMut default .apd invoked"); }
|
void apd_dbg_apd(ApdMut* m, B x) { fatal("ApdMut default .apd invoked"); }
|
||||||
Arr* apd_dbg_end(ApdMut* m, u32 ty) { err("ApdMut default .end invoked"); }
|
Arr* apd_dbg_end(ApdMut* m, u32 ty) { fatal("ApdMut default .end invoked"); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void apd_widen(ApdMut* m, B x, ApdFn** fns);
|
void apd_widen(ApdMut* m, B x, ApdFn** fns);
|
||||||
|
|||||||
@ -59,7 +59,7 @@ B vg_validateResult(B x) {
|
|||||||
if ((got&exp) != exp) {
|
if ((got&exp) != exp) {
|
||||||
printf("Expected %d defined trailing bits, got:\n", left);
|
printf("Expected %d defined trailing bits, got:\n", left);
|
||||||
vg_printDefined_u64(NULL, last);
|
vg_printDefined_u64(NULL, last);
|
||||||
err("");
|
fatal("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -74,7 +74,7 @@ B vg_validateResult(B x) {
|
|||||||
if (VALGRIND_CHECK_MEM_IS_DEFINED(data, len)) {
|
if (VALGRIND_CHECK_MEM_IS_DEFINED(data, len)) {
|
||||||
printf("Expected "N64d" defined bytes, got:\n", len);
|
printf("Expected "N64d" defined bytes, got:\n", len);
|
||||||
vg_printDump_p(NULL, data, len);
|
vg_printDump_p(NULL, data, len);
|
||||||
err("");
|
fatal("");
|
||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
@ -99,7 +99,7 @@ NOINLINE u64 vg_loadLUT64(u64* p, u64 i) {
|
|||||||
|
|
||||||
i32 undefCount = POPC(unk);
|
i32 undefCount = POPC(unk);
|
||||||
if (undefCount>0) {
|
if (undefCount>0) {
|
||||||
if (undefCount>8) err("too many unknown bits in index of vg_loadLUT64");
|
if (undefCount>8) fatal("too many unknown bits in index of vg_loadLUT64");
|
||||||
res = vg_withDefined_u64(res, loadMask(p, unk, res, i & ~unk, 1));
|
res = vg_withDefined_u64(res, loadMask(p, unk, res, i & ~unk, 1));
|
||||||
}
|
}
|
||||||
#if DBG_VG_OVERRIDES
|
#if DBG_VG_OVERRIDES
|
||||||
@ -132,7 +132,7 @@ NOINLINE u64 vg_pext_u64(u64 src, u64 mask) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NOINLINE u64 vg_pdep_u64(u64 src, u64 mask) {
|
NOINLINE u64 vg_pdep_u64(u64 src, u64 mask) {
|
||||||
if (0 != ~vg_getDefined_u64(mask)) err("pdep impl assumes mask is defined everywhere");
|
if (0 != ~vg_getDefined_u64(mask)) fatal("pdep impl assumes mask is defined everywhere");
|
||||||
u64 c = src;
|
u64 c = src;
|
||||||
u64 r = 0;
|
u64 r = 0;
|
||||||
for (i32 i = 0; i < 64; i++) {
|
for (i32 i = 0; i < 64; i++) {
|
||||||
|
|||||||
@ -9,13 +9,13 @@ static u64 vg_getDefined_u64(u64 x) { // for each bit, returns whether it is def
|
|||||||
u64 r;
|
u64 r;
|
||||||
i32 v = VALGRIND_GET_VBITS(&x, &r, 8);
|
i32 v = VALGRIND_GET_VBITS(&x, &r, 8);
|
||||||
if(v==0) return ~0ULL; // don't do weird stuff if not on valgrind
|
if(v==0) return ~0ULL; // don't do weird stuff if not on valgrind
|
||||||
if (v!=1) err("unexpected VALGRIND_GET_VBITS result");
|
if (v!=1) fatal("unexpected VALGRIND_GET_VBITS result");
|
||||||
return ~r;
|
return ~r;
|
||||||
}
|
}
|
||||||
static u64 vg_withDefined_u64(u64 x, u64 where) {
|
static u64 vg_withDefined_u64(u64 x, u64 where) {
|
||||||
where = ~where;
|
where = ~where;
|
||||||
i32 v = VALGRIND_SET_VBITS(&x, &where, 8);
|
i32 v = VALGRIND_SET_VBITS(&x, &where, 8);
|
||||||
if (v>1) err("unexpected VALGRIND_SET_VBITS result");
|
if (v>1) fatal("unexpected VALGRIND_SET_VBITS result");
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
static u64 vg_undef_u64(u64 x) {
|
static u64 vg_undef_u64(u64 x) {
|
||||||
|
|||||||
12
src/vm.c
12
src/vm.c
@ -1167,7 +1167,7 @@ static void allocStack(void** curr, void** start, void** end, i32 elSize, i32 co
|
|||||||
void* mem = calloc(sz+ps, 1);
|
void* mem = calloc(sz+ps, 1);
|
||||||
#else
|
#else
|
||||||
void* mem = mmap(NULL, sz+ps, PROT_READ|PROT_WRITE, MAP_NORESERVE|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
void* mem = mmap(NULL, sz+ps, PROT_READ|PROT_WRITE, MAP_NORESERVE|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||||
if (*curr == MAP_FAILED) err("Failed to allocate stack");
|
if (*curr == MAP_FAILED) fatal("Failed to allocate stack");
|
||||||
#endif
|
#endif
|
||||||
*curr = *start = mem;
|
*curr = *start = mem;
|
||||||
*end = ((char*)*start)+sz;
|
*end = ((char*)*start)+sz;
|
||||||
@ -1536,7 +1536,7 @@ static bool isPathREPL(B path) {
|
|||||||
return isArr(path) && IA(path)==1 && IGetU(path,0).u==m_c32('.').u;
|
return isArr(path) && IA(path)==1 && IGetU(path,0).u==m_c32('.').u;
|
||||||
}
|
}
|
||||||
usz profiler_getResults(B* compListRes, B* mapListRes, bool keyPath) {
|
usz profiler_getResults(B* compListRes, B* mapListRes, bool keyPath) {
|
||||||
if (profiler_mode!=1) err("profiler_getResults called on mode!=1");
|
if (profiler_mode!=1) fatal("profiler_getResults called on mode!=1");
|
||||||
Profiler_ent* c = profiler_buf_s;
|
Profiler_ent* c = profiler_buf_s;
|
||||||
|
|
||||||
B compList = emptyHVec();
|
B compList = emptyHVec();
|
||||||
@ -1629,7 +1629,7 @@ void profiler_displayResults(void) {
|
|||||||
gsc_exec_inplace(utf8Decode0("profilerResult←•args⋄@"), bi_N, r);
|
gsc_exec_inplace(utf8Decode0("profilerResult←•args⋄@"), bi_N, r);
|
||||||
printf("wrote result to profilerResult\n");
|
printf("wrote result to profilerResult\n");
|
||||||
#endif
|
#endif
|
||||||
} else err("profiler_displayResults called with unexpected active mode");
|
} else fatal("profiler_displayResults called with unexpected active mode");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
bool profiler_alloc() {
|
bool profiler_alloc() {
|
||||||
@ -1678,7 +1678,7 @@ NOINLINE NORETURN void throwImpl(bool rethrow) {
|
|||||||
// printf("gStack %p-%p:\n", gStackStart, gStack); B* c = gStack;
|
// printf("gStack %p-%p:\n", gStackStart, gStack); B* c = gStack;
|
||||||
// while (c>gStackStart) { printI(*--c); putchar('\n'); } printf("gStack printed\n");
|
// while (c>gStackStart) { printI(*--c); putchar('\n'); } printf("gStack printed\n");
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (cbqn_noAlloc && !gc_depth) err("throwing during noAlloc");
|
if (cbqn_noAlloc && !gc_depth) fatal("throwing during noAlloc");
|
||||||
#endif
|
#endif
|
||||||
if (!rethrow) envPrevHeight = envCurr-envStart + 1;
|
if (!rethrow) envPrevHeight = envCurr-envStart + 1;
|
||||||
#if CATCH_ERRORS
|
#if CATCH_ERRORS
|
||||||
@ -1691,7 +1691,7 @@ NOINLINE NORETURN void throwImpl(bool rethrow) {
|
|||||||
unwindEnv(envStart + cf->envDepth - 1);
|
unwindEnv(envStart + cf->envDepth - 1);
|
||||||
|
|
||||||
|
|
||||||
if (cfStart+cf->cfDepth > cf) err("bad catch cfDepth");
|
if (cfStart+cf->cfDepth > cf) fatal("bad catch cfDepth");
|
||||||
cf = cfStart+cf->cfDepth;
|
cf = cfStart+cf->cfDepth;
|
||||||
longjmp(cf->jmp, 1);
|
longjmp(cf->jmp, 1);
|
||||||
} else { // uncaught error
|
} else { // uncaught error
|
||||||
@ -1729,6 +1729,6 @@ NOINLINE NORETURN void thrM(char* s) {
|
|||||||
thr(utf8Decode0(s));
|
thr(utf8Decode0(s));
|
||||||
}
|
}
|
||||||
NOINLINE NORETURN void thrOOM() {
|
NOINLINE NORETURN void thrOOM() {
|
||||||
if (oomMessage.u==0) err("out-of-memory encountered before out-of-memory error message object was initialized");
|
if (oomMessage.u==0) fatal("out-of-memory encountered before out-of-memory error message object was initialized");
|
||||||
thr(incG(oomMessage));
|
thr(incG(oomMessage));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user