Skip to content

AIR Reference

This page lists the current AIR instruction contract.

For conceptual background, read AIR internals first.

Instruction shape

An AIR instruction has:

FieldMeaning
UOpCodeoperation code
Operandsoperation-specific operands
Metadataadditional metadata, currently implementation-facing
Commentoptional debugging/comment text

Current implementation type:

csharp
Instruction(UOpCode uOpCode, List<object>? operands = null, List<object>? metadata = null, string? comment = null)

Opcode table

OpcodeOperandsStack effectControl effectNotes
Nopnonenonenoneno operation
Push[value]push valuenonevalue type affects CIL return/type simulation
Dropnonepop top valuenoneinterpreter ignores empty stack; CIL path expects stack discipline
Jmp[labelId]nonejump to labellabel id is currently Guid in normal control-flow paths
JmpIf[labelId]pop booljump when truecondition must be boolean-compatible
JmpIfNot[labelId]pop booljump when falsecondition must be boolean-compatible
Label[labelId]nonemark targetinterpreter precomputes positions; CIL defines/marks IL labels
Annotateannotation operandsnonenonemetadata-like instruction; not required runtime semantics
Intrinsic[intrinsicId, ...operands]intrinsic-specificintrinsic-specificbackend support required

Builder methods

GenericAbstractIR<TIdentifier> exposes helper methods:

MethodEmitted opcode
Nop()Nop
Push<T>(T value)Push
Drop()Drop
Jmp(identifier)Jmp
JmpIf(identifier)JmpIf
JmpIfNot(identifier)JmpIfNot
SetLabel(label)Label
Annotate(...)Annotate
Intrinsic(instructionIdentifier, operands...)Intrinsic
AppendInstructions(...)appends existing instructions

Stack contract

AIR uses a value stack model.

Important rules:

  • expression producers must leave their result on the stack;
  • consumers must pop the values they consume;
  • JmpIf and JmpIfNot consume a condition;
  • final execution returns the top value when a value remains;
  • empty-stack final behavior is backend-specific but should be parity-tested.

Label contract

Labels and jumps use an identifier operand.

Current normal control-flow paths use Guid labels. Backends must map those labels to their own execution representation:

  • interpreter: instruction indexes;
  • CIL: IL labels.

Intrinsic contract

Intrinsic operands begin with an intrinsic identifier, followed by operation-specific operands.

The exact stack effect and runtime behavior depend on the intrinsic. A backend must support the intrinsic form before it can execute or compile it.

Do not assume Intrinsic is portable across all backends.

Backend notes

BackendAIR consumption model
Interpreterexecutes instructions sequentially with an instruction pointer, value stack and label map
CILsimulates stack types, emits IL for each instruction and compiles a DynamicMethod

Stability note

The opcode enum is a developer-facing contract for backend and optimizer work. The exact object types inside operands and metadata are more implementation-sensitive and should be documented per feature/intrinsic when they matter.

Built for developers who want to use, extend, or understand UniversalToolchain.