Skip to content

[WebAssembly] Non-canonical LEB128 parameters wasting significant space #124874

Open
@Photosounder

Description

@Photosounder

WebAssembly binaries made by clang (currently using 19.1.7) do something strange, they write LEB128 immediate parameters in the longest padded out form (long enough for 32 or 64 bits, regardless of the actual value's needs) which is both wasteful and non-canonical, like writing 82 80 80 80 00 instead of simply 02. It seems that at least a few percent of the binary size is made of those unnecessary padded LEB128 bytes.

Examples from a binary compiled with a wasm64 target:

global.get 0: 23 80 80 80 80 00 (23 is the global.get opcode and what follows is the immediate argument which is the global's ID)
global.set 0: 24 80 80 80 80 00
local.set and local.get don't have this problem, for instance local.get 0: 20 00
i64.const 21093: 42 e5 a4 81 80 80 80 80 80 80 00
i32.store 2 91016: 36 02 88 c7 85 80 80 80 80 80 80 00
i32.load 2 91008: 28 02 80 c7 85 80 80 80 80 80 80 00
call 20: 10 94 80 80 80 00
call_indirect 14 0: 11 8e 80 80 80 00 80 80 80 80 00
return_call 46: 12 ae 80 80 80 00

Oddly something like i32.store is inconsistent, sometimes it's canonical like 36 02 01, other times it's not, seemingly when the argument (the address offset) is a long address like 0x15060 instead of a small offset like 4, presumably because the long address offset could be 32 or 64 bits while the small offset (like when accessing a struct element) is known to be a small number right away.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions