wasm_leb128 (wasm v0.1.0)

View Source

LEB128 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

encode_s32(V)

-spec encode_s32(integer()) -> binary().

encode_s64(V)

-spec encode_s64(integer()) -> binary().

encode_u32/1

-spec encode_u32(non_neg_integer()) -> binary().

s32/1

-spec s32(binary()) -> {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.

s33/1

-spec s33(binary()) -> {integer(), binary()}.

Decode the s33 used by block types, which must distinguish a negative value type encoding from a non-negative type index.

s64/1

-spec s64(binary()) -> {integer(), binary()}.

sleb(Bin, Bits)

-spec sleb(binary(), pos_integer()) -> {integer(), binary()}.

Decode a signed LEB128 of at most Bits bits.

u32/1

-spec u32(binary()) -> {non_neg_integer(), binary()}.

Decode an unsigned 32-bit LEB128. Returns the value and the rest.

u64/1

-spec u64(binary()) -> {non_neg_integer(), binary()}.

uleb(Bin, Bits)

-spec uleb(binary(), pos_integer()) -> {non_neg_integer(), binary()}.

Decode an unsigned LEB128 of at most Bits bits.