From ab69f86cb5b3a965b1f42f0e29c9e08579cc25ef Mon Sep 17 00:00:00 2001 From: dzaima Date: Sat, 11 Jun 2022 17:36:51 +0300 Subject: [PATCH] store fill in FillSlice --- src/core/fillarr.c | 75 ++++++++++++++++++++++++---------------------- src/core/fillarr.h | 5 ++-- src/core/stuff.c | 7 +++-- 3 files changed, 46 insertions(+), 41 deletions(-) diff --git a/src/core/fillarr.c b/src/core/fillarr.c index d65b56c3..12f47ad3 100644 --- a/src/core/fillarr.c +++ b/src/core/fillarr.c @@ -30,14 +30,15 @@ B asFill(B x) { // consumes return bi_noFill; } -static Arr* m_fillslice(Arr* p, B* ptr, usz ia) { +static Arr* m_fillslice(Arr* p, B* ptr, usz ia, B fill) { FillSlice* r = m_arr(sizeof(FillSlice), t_fillslice, ia); r->p = p; r->a = ptr; + r->fill = fill; return (Arr*)r; } -static Arr* fillarr_slice (B x, usz s, usz ia) { return m_fillslice(a(x), c(FillArr,x)->a+s, ia); } -static Arr* fillslice_slice(B x, usz s, usz ia) { Arr* p = ptr_inc(c(Slice,x)->p); Arr* r = m_fillslice(p, c(FillSlice,x)->a+s, ia); decG(x); return r; } +static Arr* fillarr_slice (B x, usz s, usz ia) { FillArr* a=c(FillArr ,x); return m_fillslice((Arr*)a, a->a+s, ia, inc(a->fill)); } +static Arr* fillslice_slice(B x, usz s, usz ia) { FillSlice* a=c(FillSlice,x); Arr* r=m_fillslice(ptr_inc(a->p), a->a+s, ia, inc(a->fill)); decG(x); return r; } static B fillarr_get (Arr* x, usz n) { assert(x->type==t_fillarr ); return inc(((FillArr* )x)->a[n]); } static B fillslice_get (Arr* x, usz n) { assert(x->type==t_fillslice); return inc(((FillSlice*)x)->a[n]); } @@ -57,13 +58,18 @@ static void fillarr_visit(Value* x) { assert(x->type == t_fillarr); } static bool fillarr_canStore(B x) { return true; } + +static void fillslice_visit(Value* x) { FillSlice* s=(void*)x; mm_visitP(s->p); mm_visit(s->fill); } +static void fillslice_freeO(Value* x) { FillSlice* s=(void*)x; ptr_dec(s->p); dec(s->fill); decSh(x); } +static void fillslice_freeF(Value* x) { fillslice_freeO(x); mm_free(x); } + void fillarr_init() { TIi(t_fillarr,get) = fillarr_get; TIi(t_fillslice,get) = fillslice_get; TIi(t_fillarr,getU) = fillarr_getU; TIi(t_fillslice,getU) = fillslice_getU; TIi(t_fillarr,slice) = fillarr_slice; TIi(t_fillslice,slice) = fillslice_slice; - TIi(t_fillarr,freeO) = fillarr_freeO; TIi(t_fillslice,freeO) = slice_freeO; - TIi(t_fillarr,freeF) = fillarr_freeF; TIi(t_fillslice,freeF) = slice_freeF; - TIi(t_fillarr,visit) = fillarr_visit; TIi(t_fillslice,visit) = slice_visit; + TIi(t_fillarr,freeO) = fillarr_freeO; TIi(t_fillslice,freeO) = fillslice_freeO; + TIi(t_fillarr,freeF) = fillarr_freeF; TIi(t_fillslice,freeF) = fillslice_freeF; + TIi(t_fillarr,visit) = fillarr_visit; TIi(t_fillslice,visit) = fillslice_visit; TIi(t_fillarr,print) = farr_print; TIi(t_fillslice,print) = farr_print; TIi(t_fillarr,isArr) = true; TIi(t_fillslice,isArr) = true; TIi(t_fillarr,canStore) = fillarr_canStore; @@ -113,7 +119,7 @@ B withFill(B x, B fill) { // consumes both case t_i32arr: case t_i32slice: case t_i16arr: case t_i16slice: case t_i8arr: case t_i8slice: if(fill.u == m_i32(0 ).u) return x; break; case t_c32arr: case t_c32slice: case t_c16arr: case t_c16slice: case t_c8arr: case t_c8slice: if(fill.u == m_c32(' ').u) return x; break; case t_fillslice: if (fillEqual(((FillArr*)c(Slice,x)->p)->fill, fill)) { dec(fill); return x; } break; - case t_fillarr: if (fillEqual(c(FillArr,x)->fill, fill)) { dec(fill); return x; } + case t_fillarr: if (fillEqual( c(FillArr,x) ->fill, fill)) { dec(fill); return x; } if (reusable(x)) { // keeping flags is fine probably dec(c(FillArr, x)->fill); c(FillArr, x)->fill = fill; @@ -122,36 +128,33 @@ B withFill(B x, B fill) { // consumes both break; } usz ia = a(x)->ia; - if (isNum(fill)) { - x = num_squeezeChk(x); - if (elNum(TI(x,elType))) return x; - FL_KEEP(x, ~fl_squoze); - } else if (isC32(fill)) { - x = chr_squeezeChk(x); - if (elChr(TI(x,elType))) return x; - FL_KEEP(x, ~fl_squoze); - } - FillArr* r = m_arr(fsizeof(FillArr,a,B,ia), t_fillarr, ia); - arr_shCopy((Arr*)r, x); - r->fill = fill; - if (xt==t_harr | xt==t_hslice) { - if (xt==t_harr && v(x)->refc==1) { - B* xp = harr_ptr(x); - B* rp = r->a; - memcpy(rp, xp, ia*sizeof(B)); - tyarr_freeF(v(x)); // manually free x so that decreasing its refcounts is skipped - } else { - B* xp = hany_ptr(x); - B* rp = r->a; - memcpy(rp, xp, ia*sizeof(B)); - for (usz i = 0; i < ia; i++) inc(rp[i]); - decG(x); + if (!FL_HAS(x,fl_squoze)) { + if (isNum(fill)) { + x = num_squeeze(x); + if (elNum(TI(x,elType))) return x; + FL_KEEP(x, ~fl_squoze); + } else if (isC32(fill)) { + x = chr_squeeze(x); + if (elChr(TI(x,elType))) return x; + FL_KEEP(x, ~fl_squoze); } - } else { - B* rp = r->a; - SGet(x) - for (usz i = 0; i < ia; i++) rp[i] = Get(x,i); - decG(x); } + Arr* r; + B* xbp = arr_bptr(x); + if (xbp!=NULL) { + Arr* xa = a(x); + if (IS_SLICE(xa->type)) xa = ptr_inc(((Slice*)xa)->p); + else ptr_inc(xa); + r = m_fillslice(xa, xbp, ia, fill); + } else { + FillArr* rf = m_arr(fsizeof(FillArr,a,B,ia), t_fillarr, ia); + rf->fill = fill; + + B* rp = rf->a; SGet(x) + for (usz i = 0; i < ia; i++) rp[i] = Get(x,i); + r = (Arr*)rf; + } + arr_shCopy(r, x); + decG(x); return taga(r); } diff --git a/src/core/fillarr.h b/src/core/fillarr.h index 2bbadee6..5404adc1 100644 --- a/src/core/fillarr.h +++ b/src/core/fillarr.h @@ -6,6 +6,7 @@ typedef struct FillArr { typedef struct FillSlice { struct Slice; B* a; + B fill; } FillSlice; B asFill(B x); // consumes @@ -33,8 +34,8 @@ static B getFillR(B x) { // doesn't consume; can return bi_noFill case el_c8: case el_c16: case el_c32: return m_c32(' '); case el_B:; u8 t = v(x)->type; - if (t==t_fillarr ) return inc(c(FillArr,x )->fill); - if (t==t_fillslice) return inc(((FillArr*)c(Slice,x)->p)->fill); + if (t==t_fillarr ) return inc(c(FillArr, x)->fill); + if (t==t_fillslice) return inc(c(FillSlice,x)->fill); return bi_noFill; } } diff --git a/src/core/stuff.c b/src/core/stuff.c index 76e8cc31..24476644 100644 --- a/src/core/stuff.c +++ b/src/core/stuff.c @@ -823,10 +823,11 @@ Arr* g_a(B x) { return a(x); } B g_t (void* x) { return tag(x,OBJ_TAG); } B g_ta(void* x) { return tag(x,ARR_TAG); } B g_tf(void* x) { return tag(x,FUN_TAG); } +bool ignore_bad_tag; void g_p(B x) { print(x); putchar(10); fflush(stdout); } void g_i(B x) { B r = info_c2(x, m_f64(1), inc(x)); print(r); dec(r); putchar(10); fflush(stdout); } -void g_pv(void* x) { print(tag(x,OBJ_TAG)); putchar(10); fflush(stdout); } -void g_iv(void* x) { B xo = tag(x, OBJ_TAG); B r = info_c2(xo, m_f64(1), inc(xo)); print(r); dec(r); putchar(10); fflush(stdout); } +void g_pv(void* x) { ignore_bad_tag=true; print(tag(x,OBJ_TAG)); putchar(10); fflush(stdout); ignore_bad_tag=false; } +void g_iv(void* x) { ignore_bad_tag=true; B xo = tag(x, OBJ_TAG); B r = info_c2(xo, m_f64(1), inc(xo)); print(r); dec(r); putchar(10); fflush(stdout); ignore_bad_tag=false; } void g_pst(void) { vm_pstLive(); fflush(stdout); fflush(stderr); } #ifdef DEBUG @@ -855,7 +856,7 @@ void g_pst(void) { vm_pstLive(); fflush(stdout); fflush(stderr); } NOINLINE B VALIDATE(B x) { if (!isVal(x)) return x; VALIDATEP(v(x)); - if(isArr(x)!=TI(x,isArr) && v(x)->type!=t_freed && v(x)->type!=t_harrPartial) { + if(isArr(x)!=TI(x,isArr) && v(x)->type!=t_freed && v(x)->type!=t_harrPartial && !ignore_bad_tag) { fprintf(stderr, "bad array tag/type: type=%d, obj=%p\n", v(x)->type, (void*)x.u); PRINT_ID(v(x)); fprint(stderr, x);