diff --git a/src/builtins/internal.c b/src/builtins/internal.c index efd07845..07e49345 100644 --- a/src/builtins/internal.c +++ b/src/builtins/internal.c @@ -234,6 +234,7 @@ static B unshare(B x) { if (!isArr(x)) return x; usz xia = a(x)->ia; switch (v(x)->type) { + case t_bitarr: return taga(cpyBitArr(inc(x))); case t_i8arr: return taga(cpyI8Arr (inc(x))); case t_i16arr: return taga(cpyI16Arr(inc(x))); case t_i32arr: return taga(cpyI32Arr(inc(x))); @@ -258,7 +259,15 @@ static B unshare(B x) { } } -B internalTemp_c1(B t, B x) { return x; } + + +B internalTemp_c1(B t, B x) { + #ifdef TEST_BITCPY + SGetU(x) + bit_cpy(bitarr_ptr(GetU(x,0)), o2s(GetU(x,1)), bitarr_ptr(GetU(x,2)), o2s(GetU(x,3)), o2s(GetU(x,4))); + #endif + return x; +} B internalTemp_c2(B t, B w, B x) { dec(w); return x; } B heapDump_c1(B t, B x) { diff --git a/src/utils/mut.h b/src/utils/mut.h index 068f2e4c..7c0a42e1 100644 --- a/src/utils/mut.h +++ b/src/utils/mut.h @@ -126,21 +126,40 @@ static void mut_copy(Mut* m, usz ms, B x, usz xs, usz l) { assert(isArr(x)); m-> -static void bit_cpy(u64* r, usz rs, u64* x, usz xs, usz l) { // TODO rewrite this whole thing to be all fancy - u64 i = rs; +static void bit_cpy(u64* r, usz rs, u64* x, usz xs, usz l) { u64 re = rs+(u64)l; i64 d = (i64)xs-(i64)rs; - if (l>128) { - for (; i>6; - u64 ei = (re>>6) - 2; - i64 dp = d>>6; - u64 df = ((u64)d)&63u; - if (df==0) for (; ti> df) | (x[ti+dp+1] << (64-df)); - i = ti<<6; + + u64 ti = rs>>6; + u64 ei = re>>6; + + i64 dp = d>>6; + u64 df = ((u64)d)&63u; + #define RDF0 x[ti+dp] + #define RDFp ((x[ti+dp] >> df) | (x[ti+dp+1] << (64-df))) + #define READ (df==0? RDF0 : RDFp) + if (ti!=ei) { + if (rs&63) { + u64 m = (1ULL << (rs&63))-1; + r[ti] = (READ & ~m) | (r[ti] & m); + ti++; + } + + if (df==0) for (; ti≥ ./BQN test/equal.bqn // fuzz-test 𝕨≡𝕩 +./BQN test/bitcpy.bqn // fuzz-test bit_cpy; requires a CBQN build with -DTEST_BITCPY ``` \ No newline at end of file diff --git a/test/bitcpy.bqn b/test/bitcpy.bqn new file mode 100644 index 00000000..ab8290ea --- /dev/null +++ b/test/bitcpy.bqn @@ -0,0 +1,41 @@ +⟨Temp, Type, Unshare, Squeeze, Info⟩ ← •internal +u ← •UnixTime@ +# u ↩ 123 + +r ← •MakeRand •Show u + + +Do ← { 𝕊: + al ← 1+r.Range 500 + aT ← al r.Range 2 + a ← Squeeze aT + ! a ≡ aT + ! "i32arr" ≡ Type aT + ! "bitarr" ≡ Type a + b ← Squeeze al r.Range 2 + { 𝕊: + bl ← r.Range 1+al + as ← r.Range 1+al-bl + bs ← r.Range 1+al-bl + i ← ↕bl + exp ← ((bs+i)⊏b)⌾((as+i)⊸⊏) a + aC ← Unshare a + Temp ⟨aC, as, b, bs, bl⟩ + aC ≢ exp? + •Out "Fail:" + F ← {(¬ ·∧`⌾⌽ ' '⊸=)⊸/ ⥊' '∾˘˜ ↑‿64⥊ '0'+𝕩} + •Out "Exp: "∾F exp + •Out "Got: "∾F aC + •Out "Inputs:" + •Out "r: "∾F a + •Out "rs: "∾•Repr as + •Out "x: "∾F b + •Out "xs: "∾•Repr bs + •Out "l: "∾•Repr bl + •Exit 1 + ;0 + }∘@⍟500 @ + ! a ≡ aT +} + +@∘Do⍟(⊑(•BQN¨•args)∾500) @ \ No newline at end of file diff --git a/test/equal.bqn b/test/equal.bqn index 4a93d5e7..5a606702 100644 --- a/test/equal.bqn +++ b/test/equal.bqn @@ -1,6 +1,6 @@ ⟨ListVariations, ClearRefs, Variation, Squeeze, Info⟩ ← •internal u ← •UnixTime@ -# u ↩ 1648896733 +# u ↩ 123 r ← •MakeRand •Show u @@ -40,7 +40,7 @@ Do ← { 𝕊: exp ← v = p⊑a b ← Squeeze v⌾(p⊸⊑) a (⊢◶exp‿{𝕊:∧´a=b} at=4) TestVars a‿b - }⍟100 @ + }∘@⍟100 @ } @∘Do⍟1000 @ \ No newline at end of file