Master the fundamental concepts of webassembly internals through this focused micro-challenge.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksA \`.wasm\` file is a sequence of sections, each with an ID, size, and payload. Parsers walk them in order to build types, functions, memories, and code bodies.
Standard sections include:
LEB128 encodes variable-length integers compactly. Function bodies prefix local decls then expr bytecode terminated by \`end\`.
For example, a module exporting \`add\` might have type section entry \`(func (param i32 i32) (result i32))\`, export name \`add\`, and a two-instruction body: \`local.get 0; local.get 1; i32.add\`.
Magic: \`00 61 73 6D\` (\`\\0asm\`), version \`01 00 00 00\`.
LEB128 decode errors cascade: one wrong length corrupts every following section offset. Parse section sizes strictly and bounds-check before advancing the cursor.
This exercise asks you to parse Wasm section headers and dump structure. You will read magic, version, and section IDs from bytes the way wasm-tools and browsers do at load time.
You will use the same mental model here when reading production interpreter source later in the track. Sketch one concrete input on paper, predict the outcome, then confirm with code. That discipline catches logic errors early and makes debugging far faster when you extend the implementation in follow-on tasks.
Parse a WebAssembly binary module and print what it contains: every section with its offset and size, the types, imports, function-to-type mapping, memories and exports, and a disassembly of each function body. Every integer in the format is LEB128, so decoding must be bounds-checked and length-checked everywhere.
Hex bytes separated by whitespace. A token starting with # comments out the rest of its line. The token next separates modules, whose outputs are separated by ---.
00 61 73 6d, then the version as a u32 little-endian, which must be 1.id:u8 size:uleb, then size bytes. Non-custom sections must appear in increasing id order. Ids above 11 are unknown.60 params results, with value types i32 7F, i64 7E, f32 7D, f64 7C.module:name field:name kind. Kind 0 is a func (a type index). Kind 2 is a memory (limits: flag 0 = min, flag 1 = min max). Imported functions take the first function indices.name kind:u8 index (kinds func/table/memory/global).size:uleb, then local groups (count type), then instructions up to 0B.uleb length + bytes, and vectors are uleb count + items.The opcodes from the assembler task:
unreachable nop return call drop.local.get/set/tee.i32.const (signed LEB, 32-bit) and i64.const (64-bit).eqz eq ne lt_s gt_s.add sub mul div_s rem_s and or shl.i64.add i64.mul i32.wrap_i64 i64.extend_i32_s.cLoading…
memory 0: min 2 pages (64 KiB each), or memory 0: min 1, max 4 pages (64 KiB each).module.field, and anything else is unnamed. An unnamed body prints func N: …. A call prints call I <NAME>, where NAME is func I for unnamed functions. OFFS: unknown opcode 0xXX, skipping the rest of the body. A body whose bytes run out without end prints missing end.These stop the module with error: …:
bad magic (expected 00 61 73 6d), unsupported version Ntruncated at 0xN (reads are also limited to the current section and body)LEB128 too long at 0xNunknown section id N at 0xN, section NAME out of order at 0xNsection NAME declared N bytes but used Mtype index N out of rangecode count N does not match function count Mbad value type 0xNN at 0xN, expected 0x60 at 0xN, unsupported import kind Nbody N ends at 0xN, expected 0xNfunction section without code section, empty inputA bad hex token prints bad byte: X for that module.
Input:
cLoading…
Output:
cLoading…
Hidden tests cover imports that shift function indices, a memory section, a custom section, an unknown opcode, and each structural error: version, order, LEB length, size mismatch, count mismatch, truncation and a bad type index.