diff --git a/src/builtins/fns.c b/src/builtins/fns.c index b46264b5..2efd805d 100644 --- a/src/builtins/fns.c +++ b/src/builtins/fns.c @@ -312,7 +312,11 @@ B count_c2(B t, B w, B x) { H_b2i* prevImports; i32 prevImportIdx(B path, i32 pos) { if (prevImports==NULL) prevImports = m_b2i(16); - return swap_b2i(&prevImports, path, pos, -1); + bool had; + i32 prev = mk_b2i(&prevImports, path, &had); + if (had) return prevImports->a[prev].val; + prevImports->a[prev].val = pos; + return -1; } void fun_gcFn() { if (prevImports!=NULL) mm_visitP(prevImports); diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index 7307951c..7c0c3e0b 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -637,7 +637,7 @@ B import_c2(B d, B w, B x) { } i32 prevImportIdx(B path, i32 pos); // defined in fns.c -static B importKeyList; +static B importKeyList; // exists for GC roots static B importValList; B import_c1(B d, B x) { if (importKeyList.u==0) { @@ -645,8 +645,14 @@ B import_c1(B d, B x) { importValList = emptyHVec(); } B path = path_abs(path_rel(nfn_objU(d), x)); - i32 prevIdx = prevImportIdx(path, a(importKeyList)->ia); - if (prevIdx!=-1) { dec(path); return IGet(importValList, prevIdx); } + i32 prevLen = a(importKeyList)->ia; + i32 prevIdx = prevImportIdx(path, prevLen); + if (prevIdx!=-1) { + // print_fmt("cached: %R @ %i/%i\n", path, prevIdx, prevLen); + if (prevIdx>=prevLen) thrF("•Import: cyclic import of \"%R\"", path); + dec(path); + return IGet(importValList, prevIdx); + } B r = bqn_execFile(inc(path), emptySVec()); importKeyList = vec_add(importKeyList, path); importValList = vec_add(importValList, inc(r)); @@ -881,9 +887,9 @@ void sysfn_init() { fileAtDesc = registerNFn(m_str8l("(file).At"), fileAt_c1, fileAt_c2); fLinesDesc = registerNFn(m_str8l("(file).Lines"), flines_c1, flines_c2); fBytesDesc = registerNFn(m_str8l("(file).Bytes"), fbytes_c1, fbytes_c2); + listDesc = registerNFn(m_str8l("(file).List"), list_c1, c2_bad); importDesc = registerNFn(m_str32(U"•Import"), import_c1, import_c2); reBQNDesc = registerNFn(m_str8l("(REPL)"), repl_c1, repl_c2); - listDesc = registerNFn(m_str32(U"•file.List"), list_c1, c2_bad); } void sysfnPost_init() { file_nsGen = bqn_exec(m_str32(U"{⟨path,At,List,Bytes,Chars,Lines⟩⇐𝕩}"), emptyCVec(), emptySVec()); gc_add(file_nsGen); diff --git a/src/core/stuff.c b/src/core/stuff.c index 84eb2540..74bc6b96 100644 --- a/src/core/stuff.c +++ b/src/core/stuff.c @@ -317,6 +317,7 @@ NOINLINE void print_fmt(char* p, ...) { B r = do_fmt(emptyCVec(), p, a); va_end(a); printRaw(r); + dec(r); } NOINLINE void thrF(char* p, ...) { va_list a; diff --git a/src/opt/gc.c b/src/opt/gc.c index a348c3a7..0250d4af 100644 --- a/src/opt/gc.c +++ b/src/opt/gc.c @@ -2,10 +2,10 @@ u64 gc_depth = 1; -vfn gc_roots[16]; +vfn gc_roots[32]; u32 gc_rootSz; void gc_addFn(vfn f) { - if (gc_rootSz>=16) err("Too many GC roots"); + if (gc_rootSz>=32) err("Too many GC root functions"); gc_roots[gc_rootSz++] = f; }