wasm_leb128 (wasm v0.1.0)
View SourceLEB128 varint decoding, strict per the WebAssembly binary format.
Read this if you are wondering why a varint your encoder produced is rejected.
The specification does not merely require a decodable varint, it constrains
the encoding: uN/sN admit at most ceil(N/7) bytes, and the final byte
may only carry bits that fit the target width (for signed values, the unused
high bits must be a sign extension). Encodings that violate this are
malformed, not merely unusual, and the specification test suite checks for
exactly this. Accepting them silently is the classic decoder bug.
Both constraints reduce to two checks:
- a continuation bit still set on the last permitted byte means "integer representation too long";
- a decoded value outside the target width's range means "integer too large". This is provably equivalent to the per-byte
sign-extension rule, and it is one comparison instead of a mask and a branch on every byte.
Single-byte values dominate real modules (every small index and length), so that case is matched directly before entering the loop.
Summary
Functions
Decode a signed 32-bit LEB128. A one-byte encoding with bit 6 clear is a small non-negative value; with bit 6 set it is a small negative one.
Decode the s33 used by block types, which must distinguish a negative
value type encoding from a non-negative type index.
Decode a signed LEB128 of at most Bits bits.
Decode an unsigned 32-bit LEB128. Returns the value and the rest.
Decode an unsigned LEB128 of at most Bits bits.
Functions
-spec encode_u32(non_neg_integer()) -> binary().
Decode a signed 32-bit LEB128. A one-byte encoding with bit 6 clear is a small non-negative value; with bit 6 set it is a small negative one.
Decode the s33 used by block types, which must distinguish a negative
value type encoding from a non-negative type index.
-spec sleb(binary(), pos_integer()) -> {integer(), binary()}.
Decode a signed LEB128 of at most Bits bits.
-spec u32(binary()) -> {non_neg_integer(), binary()}.
Decode an unsigned 32-bit LEB128. Returns the value and the rest.
-spec u64(binary()) -> {non_neg_integer(), binary()}.
-spec uleb(binary(), pos_integer()) -> {non_neg_integer(), binary()}.
Decode an unsigned LEB128 of at most Bits bits.