From 7768d6475f791f2ab6b22eef65842cface3ff413 Mon Sep 17 00:00:00 2001 From: dzaima Date: Mon, 23 Jan 2023 23:49:27 +0200 Subject: [PATCH] various OOM fixes --- src/builtins/md1.c | 4 ++-- src/builtins/md2.c | 2 ++ src/main.c | 11 ++++++++++- src/utils/utf.c | 42 ++++++++++++++++++++++++++---------------- src/vm.c | 10 ++++++---- 5 files changed, 46 insertions(+), 23 deletions(-) diff --git a/src/builtins/md1.c b/src/builtins/md1.c index 5f769e19..44707c33 100644 --- a/src/builtins/md1.c +++ b/src/builtins/md1.c @@ -210,7 +210,7 @@ B cell2_empty(B f, B w, B x, ur wr, ur xr) { if (!isPureFn(f) || !CATCH_ERRORS) { dec(w); dec(x); return emptyHVec(); } if (wr) w = to_fill_cell_1(w); if (xr) x = to_fill_cell_1(x); - if (CATCH) return emptyHVec(); + if (CATCH) { freeThrown(); return emptyHVec(); } B rc = c2(f, w, x); popCatch(); return merge_fill_result_1(rc); @@ -346,7 +346,7 @@ B cell_c1(Md1D* d, B x) { B f = d->f; if (cam==0) { if (!isPureFn(f) || !CATCH_ERRORS) { decG(x); return emptyHVec(); } B cf = to_fill_cell_1(x); - if (CATCH) return emptyHVec(); + if (CATCH) { freeThrown(); return emptyHVec(); } B rc = c1(f, cf); popCatch(); return merge_fill_result_1(rc); diff --git a/src/builtins/md2.c b/src/builtins/md2.c index 38207123..144867b7 100644 --- a/src/builtins/md2.c +++ b/src/builtins/md2.c @@ -274,6 +274,7 @@ static B rank2_empty(B f, B w, ur wk, B x, ur xk) { if (wk) w = to_fill_cell(w, wk); if (xk) x = to_fill_cell(x, xk); if (CATCH) { empty: + freeThrown(); r = empty_frame(sh, k); } else { B rc = c2(f, w, x); @@ -314,6 +315,7 @@ B rank_c1(Md2D* d, B x) { B f = d->f; B g = d->g; B cf = to_fill_cell(x, k); B r; if (CATCH) { empty: + freeThrown(); r = empty_frame(xsh, k); } else { B rc = c1(f, cf); diff --git a/src/main.c b/src/main.c index 70b245f0..aadf3dfc 100644 --- a/src/main.c +++ b/src/main.c @@ -154,7 +154,9 @@ static bool isCmd(char* s, char** e, const char* cmd) { return false; } + #define CATCH_OOM(X) if (CATCH) { freeThrown(); X; } void highlighter_replxx(const char* input, ReplxxColor* colors, int size, void* data) { + CATCH_OOM(return) B charObj = utf8Decode0(input); if (IA(charObj) != size) goto end; // don't want to kill the REPL if this happens, but gotta do _something_ @@ -195,6 +197,7 @@ static bool isCmd(char* s, char** e, const char* cmd) { } end: dec(charObj); + popCatch(); } B allNsFields(void); B str_norm(u32* chars, usz len, bool* upper) { @@ -223,6 +226,7 @@ static bool isCmd(char* s, char** e, const char* cmd) { return c; } NOINLINE void completion_impl(const char* inp, void* res, bool hint, int* dist) { + CATCH_OOM(return) B inpB = toC32Any(utf8Decode0(inp)); u32* chars = c32any_ptr(inpB); u32* we = chars+IA(inpB); @@ -289,6 +293,7 @@ static bool isCmd(char* s, char** e, const char* cmd) { } dec(inpB); + popCatch(); } void complete_replxx(const char* inp, replxx_completions* res, int* dist, void* data) { completion_impl(inp, res, false, dist); @@ -337,6 +342,7 @@ static bool isCmd(char* s, char** e, const char* cmd) { static bool inBackslash() { return b_pv.u!=0; } static void stopBackslash() { decG(b_pv); b_pv.u = 0; } ReplxxActionResult backslash_replxx(int code, void* data) { + CATCH_OOM(goto end) if (inBackslash()) { setState(insertChar('\\', false)); stopBackslash(); @@ -348,6 +354,8 @@ static bool isCmd(char* s, char** e, const char* cmd) { b_pv = utf8Decode0(st.text); b_pp = st.cursorPosition; } + popCatch(); + end: return REPLXX_ACTION_RESULT_CONTINUE; } ReplxxActionResult enter_replxx(int code, void* data) { @@ -376,7 +384,7 @@ static bool isCmd(char* s, char** e, const char* cmd) { void modified_replxx(char** s_res, int* p_res, void* userData) { if (!cfg_enableKeyboard) return; if (!inBackslash()) return; - + CATCH_OOM(return) TmpState t = getState(); B s = t.s; u64 pos = t.pos; @@ -392,6 +400,7 @@ static bool isCmd(char* s, char** e, const char* cmd) { stop: decG(s); stopBackslash(); + popCatch(); } diff --git a/src/utils/utf.c b/src/utils/utf.c index 7d3e612f..30f4abad 100644 --- a/src/utils/utf.c +++ b/src/utils/utf.c @@ -1,5 +1,6 @@ #include "../core.h" #include "utf.h" +#include "calls.h" static i8 utf8lenb(u8 ch) { if (ch<128) return 1; @@ -111,24 +112,33 @@ void fprintsB(FILE* f, B x) { if (xe==el_c32) { fprintsU32(f, c32any_ptr(x), ia); } else { - incG(x); - if (!elChr(xe)) { x=chr_squeeze(x); xe=TI(x,elType); } - if (!elChr(xe)) { - #if !CATCH_ERRORS - SGetU(x) - for (usz i = 0; i < ia; i++) { - B c = GetU(x, i); - if (isC32(c)) fprintCodepoint(f, o2cG(c)); - else if (c.u==0 || noFill(c)) fprintf(f, " "); - else thrM("Trying to output non-character"); + #define BUF_SZ 1024 + if (elChr(xe)) { + if (xe==el_c32) { + fprintsU32(f, c32any_ptr(x), ia); + } else { + u32 buf[BUF_SZ]; + usz i = 0; + while (i < ia) { + usz curr = ia-i; + if (curr>BUF_SZ) curr = BUF_SZ; + COPY_TO(buf, el_c32, 0, x, i, curr); + fprintsU32(f, buf, curr); + i+= curr; } - return; - #endif - thrM("Trying to output non-character"); + } + } else { + SGetU(x) + for (usz i = 0; i < ia; i++) { + B c = GetU(x, i); + if (isC32(c)) fprintCodepoint(f, o2cG(c)); +#if CATCH_ERRORS + else if (c.u==0 || noFill(c)) fprintf(f, " "); +#endif + else thrM("Trying to output non-character"); + } } - x = taga(cpyC32Arr(x)); - fprintsU32(f, c32any_ptr(x), ia); - decG(x); + #undef BUF_SZ } } diff --git a/src/vm.c b/src/vm.c index 75f1dc58..7ef368e6 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1344,7 +1344,7 @@ NOINLINE void vm_printPos(Comp* comp, i32 bcPos, i64 pos) { #if FORCE_NATIVE_ERROR_PRINT goto native_print; #endif - if (CATCH) goto native_print; + if (CATCH) { freeThrown(); goto native_print; } B s = emptyCVec(); B msg = vm_fmtPoint(src, s, comp->path, cs, ce); @@ -1600,9 +1600,11 @@ void unwindCompiler() { NOINLINE void printErrMsg(B msg) { if (isArr(msg)) { - SGetU(msg) - usz msgLen = IA(msg); - for (usz i = 0; i < msgLen; i++) if (!isC32(GetU(msg,i))) goto base; + if (!elChr(TI(msg,elType))) { + SGetU(msg) + usz msgLen = IA(msg); + for (usz i = 0; i < msgLen; i++) if (!isC32(GetU(msg,i))) goto base; + } fprintsB(stderr, msg); return; }