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.

Public developer manual. Internal reviews, proposals and maintainer material live under internal-docs/.