Master the fundamental concepts of webassembly internals through this focused micro-challenge.
Once you have an interpreter, compiling hot Wasm functions to native code removes dispatch overhead. Template or trace JITs map Wasm opcodes to machine instructions, reusing techniques from your bytecode VM track.
Approaches:
Executable memory via \`mmap\` + \`mprotect\` matches what you built for the bytecode VM JIT task.
For example, \`i32.add\` becomes x86 \`add\` after two loads from the Wasm stack slots mapped to registers or a native stack frame.
Fallback to the interpreter keeps rare opcodes simple.
Map Wasm locals to native stack slots or registers consistently for the whole function. Changing mapping mid-function makes debugging generated code nearly impossible without a side table.
This exercise asks you to add a basic JIT to your Wasm runtime using prior JIT knowledge. You will emit native code for a short Wasm function and call it instead of interpreting opcode by opcode.
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.
Write a C program that documents Wasm-to-native JIT compilation and shows how instructions map to x86-64.
Requirements:
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
All starter code and reference implementations are available for your local setup.
View on Github