[][src]Module metered_wasmi::isa

An instruction set used by metered_wasmi.

The instruction set is mostly derived from Wasm. However, there is a substantial difference.

Structured Stack Machine vs Plain One

Wasm is a structured stack machine. Wasm encodes control flow in structures similar to that commonly found in a programming languages such as if, while. That contrasts to a plain stack machine which encodes all control flow with goto-like instructions.

Structured stack machine code aligns well with goals of Wasm, namely providing fast validation of Wasm code and compilation to native code.

Unfortunately, the downside of structured stack machine code is that it is less convenient to interpret. For example, let's look at the following example in hypothetical structured stack machine:

loop
  ...
  if_true_jump_to_end
  ...
end

To execute if_true_jump_to_end , the interpreter needs to skip all instructions until it reaches the matching end. That's quite inefficient compared to a plain goto to the specific position.

Because of this, the translation from the Wasm structured stack machine into a plain one is taking place.

Locals

In a plain stack machine local variables and arguments live on the stack. Instead of accessing predefined locals slots in a plain stack machine locals are addressed relative to the current stack pointer. Because of this instead of taking an index of a local in {get,set,tee}_local operations, they take a relative depth as immediate. This works because at each instruction we always know the current stack height.

Roughly, the stack layout looks like this

| caller arguments | | - arg 1 | | - arg 2 | +------------------+ | callee locals | | - var 1 | | - var 2 | +------------------+ | operands | | - op 1 | | - op 2 | | | <-- current stack pointer +------------------+

Differences from Wasm

  • There is no nop instruction.
  • All control flow structures are flattened to plain gotos.
  • Implicit returns via reaching function scope End are replaced with an explicit return instruction.
  • Locals live on the value stack now.
  • Load/store instructions doesn't take align parameter.
  • *.const store value in straight encoding.
  • Reserved immediates are ignored for call_indirect, current_memory, grow_memory.

Structs

BrTargets
DropKeep

Specifies how many values we should keep and how many we should drop.

InstructionIter
Instructions
Target

Enums

Instruction

The main interpreted instruction type. This is what is returned by InstructionIter, but it is not what is stored internally. For that, see InstructionInternal.

Keep

Should we keep a value before "discarding" a stack frame?

Reloc

A relocation entry that specifies.