Skip to content

Commit

Permalink
Enhanced Orthogonal Persistence: Refactor 64-bit Port of SLEB128 for …
Browse files Browse the repository at this point in the history
…BigInt (#4486)

* Refactor 64-bit port of SLEB128 for BigInt

* Remove redundant test file
  • Loading branch information
luc-blaeser authored Apr 5, 2024
1 parent 588204f commit 4e628b3
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 12 deletions.
14 changes: 2 additions & 12 deletions rts/motoko-rts/src/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -610,10 +610,6 @@ pub unsafe extern "C" fn bigint_sleb128_decode_word64(
mut bits: u64,
buf: *mut Buf,
) -> Value {
const BITS_IN_LAST_CHUNK: usize = usize::BITS as usize % BITS_PER_CHUNK;
const _: () = assert!(BITS_IN_LAST_CHUNK > 0);
const SIGN_BITS_IN_LAST_CHUNK: u32 = usize::BITS - (BITS_IN_LAST_CHUNK + 1) as u32;

let continuations = bits as usize / 8;
buf.advance(continuations + 1);

Expand All @@ -633,12 +629,6 @@ pub unsafe extern "C" fn bigint_sleb128_decode_word64(
sleb >>= 1;
}

let signed = (acc as i64) << SIGN_BITS_IN_LAST_CHUNK >> SIGN_BITS_IN_LAST_CHUNK; // sign extend
let tentative = (signed as isize) << 1 >> 1; // top two bits must match
if tentative as i64 == signed {
// roundtrip is valid
return int_from_int64(tentative);
}

bigint_of_int64(signed)
// No unused bits in 64-bit representation. The sign bit is already set at bit 63.
int_from_int64(acc as isize)
}
44 changes: 44 additions & 0 deletions test/run/leb-random.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
object Random {
let max = 0xF_FFFF_FFFF_FFFF_FFFF;
let seed = 4711;
var number = seed;

public func nextInt() : Int {
let number = +nextNat();
let sign = if (number % 2 == 0) { -1 } else { +1 };
number * sign;
};

public func nextNat() : Nat {
number := (123138118391 * number + 133489131) % 9_999_999;
(number * number) % max;
};
};

func serializeInt(a : [Int]) : Blob = to_candid (a);
func deserialzeInt(b : Blob) : ?[Int] = from_candid (b);

func serializeNat(a : [Nat]) : Blob = to_candid (a);
func deserialzeNat(b : Blob) : ?[Nat] = from_candid (b);

let rounds = 100000;

var count = 0;
while (count < rounds) {
let number = Random.nextInt();
assert ((?[number]) == deserialzeInt(serializeInt([number])));
count += 1;
};


count := 0;
while (count < rounds) {
let number = Random.nextNat();
assert ((?[number]) == deserialzeNat(serializeNat([number])));
count += 1;
};


//SKIP run
//SKIP run-ir
//SKIP run-low

0 comments on commit 4e628b3

Please sign in to comment.