wasm_milkir

WebAssembly dialect adapter for MilkIR extension operations

wasm
webassembly
milkir
compiler
dialect
Download zip
Author
Version
0.12.5
License
Apache-2.0
Last updated
1 hour ago
Downloads
113

Dependencies

#wasm_milkir

WebAssembly dialect adapter for MilkIR extension operations.

wasm_milkir provides the Wasm-specific opcode set, extension descriptors, and builder helpers used with MilkIR. Frontends encode Wasm operations through typed WasmOpcode constructors, then a lowering adapter checks and decodes those extensions before machine lowering.

Typed Wasm builders only emit IR data; they do not attach validator closures to the MilkIR function. Generic MilkIR finalization checks the extension envelope and its explicit signature, while verify_function applies context-free schema contracts. Operations whose contracts depend on module or linker metadata must use an explicit WasmValidationContext and verify_function_with_context. Wasm lowering requires the same context and validates it immediately before instruction selection.

Typed constructors, serialized opcode names, and immediate layouts are defined once in wasm_opcodes.schema. During development, dev_build runs the deterministic tools/generate_wasm_opcodes.py generator to refresh the committed dialect_generated.mbt source. Published packages include that generated MoonBit source, so downstream builds neither load the schema at runtime nor execute development build rules.

#Packages

  • Milky2018/wasm_milkir: Wasm opcode encoding/decoding and builder helpers for Milky2018/milkir.

#How it fits

MilkIR represents common SSA operations directly. This package represents WebAssembly operations that need additional immediates or lowering semantics as typed MilkIR extensions. The extension descriptor lets a lowering pipeline validate the encoded operation before decoding it.

Common arithmetic, calls, references, and SIMD operations use MilkIR's semantic opcode families directly. In particular, the Wasm frontend consumes SIMD memidx, alignment, and offset fields while constructing the effective address; the resulting MilkIR VectorOp carries only vector load/store semantics.

Linear-memory base pointers use MilkIR GlobalValue declarations rather than a Wasm extension opcode. memory_base_context_field identifies the memory index, the declaration records Heap(memidx) provenance, and the frontend chooses Stable only when the embedding guarantees that the base cannot move during the function invocation. Contextual validation checks that the memory exists; wasm_machv resolves the opaque field through its embedding environment.

#Example: map Wasm reference types to MilkIR

///|
test "map Wasm reference spelling to generic MilkIR references" {
inspect(wasm_funcref_type().to_string(), content="callable_ref")
inspect(wasm_externref_type().to_string(), content="opaque_ref")
}

#Example: encode a Wasm memory operation

///|
test "build a Wasm memory.size extension instruction" {
let builder = @milkir.FunctionBuilder::FunctionBuilder("memory_size")
let symbols = RuntimeSymbols::with_runtime_prefix("example.runtime")
let vmctx = builder.add_param(I64)
builder.add_result(I32)
let size = memory_size(builder, symbols, vmctx, 0)
builder.return_([size])
let func = builder.get_function()
inspect(func.blocks.length(), content="1")
verify_function(func)
match func.blocks[0].instructions[1].opcode {
Call(Direct(symbol, _)) =>
inspect(symbol.name, content="example.runtime.memory_size")
_ => inspect(false, content="true")
}
}

#Example: validate and decode a Wasm extension

///|
test "validate and decode a typed Wasm extension operation" {
let opcode = WasmOpcode::RefTest(3, true)
let ext = encode(opcode)
let desc = descriptor(opcode)
inspect(ext.matches_descriptor(desc), content="true")
inspect(decode(ext) == Some(opcode), content="true")
let malformed = @milkir.ExtOp(
"wasm",
"ref_test",
FixedArray::makei(2, fn(i) { if i == 0 { 3 } else { 2 } }),
)
debug_inspect(
decode_error(malformed),
content=(
#|Some("malformed Wasm MilkIR extension 'ref_test': immediate 1 is a bool flag encoded as 0 or 1, got 2")
),
)
}

RuntimeSymbols

type RuntimeSymbols derive(Eq,
Debug
)

Embedding-specific external names for WebAssembly runtime helpers.

RuntimeSymbols::symbol_name

fn RuntimeSymbols::symbol_name(self : RuntimeSymbols, helper : WasmRuntimeHelper) -> String

RuntimeSymbols::with_runtime_prefix

fn RuntimeSymbols::with_runtime_prefix(prefix : String) -> RuntimeSymbols

WasmDefinedTypeContract

pub(all) enum WasmDefinedTypeContract {
Function(WasmFunctionContract)
Struct(Array[WasmFieldContract])
Array(WasmFieldContract)
} derive(Eq,
Debug
)

The contextual contract for a WebAssembly indexed type.

WasmFieldContract

pub(all) struct WasmFieldContract {
storage : WasmStorageContract
mutable_ : Bool
defaultable : Bool
} derive(Eq,
Debug
)

The contextual contract for one WebAssembly struct field or array element.

WasmFunctionContract

pub(all) struct WasmFunctionContract {
params : Array[
Type
]
results : Array[
Type
]
} derive(Eq,
Debug
)

The lowered MilkIR carrier contract for a WebAssembly function type.

WasmOpcode

pub(all) enum WasmOpcode {
WasmCall(Int)
WasmCallIndirect(Int, Int)
CallRef(Int)
ReturnCall(Int)
ReturnCallIndirect(Int, Int)
ReturnCallRef(Int)
GetFuncRef(Int)
StructNew(Int)
StructNewDefault(Int)
StructGet(Int, Int)
StructGetS(Int, Int, Int)
StructGetU(Int, Int, Int)
StructSet(Int, Int)
ArrayNew(Int)
ArrayNewDefault(Int)
ArrayNewFixed(Int, Int)
ArrayGet(Int)
ArrayGetS(Int, Int)
ArrayGetU(Int, Int)
ArraySet(Int)
ArrayLen
ArrayFill(Int)
ArrayCopy(Int, Int)
ArrayNewData(Int, Int)
ArrayNewElem(Int, Int)
ArrayInitData(Int, Int)
ArrayInitElem(Int, Int)
I31New
I31GetS
I31GetU
RefTest(Int, Bool)
RefCast(Int, Bool)
AnyConvertExtern
ExternConvertAny
RefEq
Throw(Int)
ThrowRef
TryTableBegin(Int)
TryTableEnd(Int)
GetExceptionTag
GetExceptionValue(Int)
GetExceptionValueCount
Delegate(Int)
SpillLocalsForThrow(Int)
GetSpilledLocal(Int)
} derive(Eq, Hash,
Debug
)

WasmRuntimeHelper

pub(all) enum WasmRuntimeHelper {
MemoryGrow
MemorySize
MemoryFill
MemoryCopy
MemoryInit
DataDrop
TableGrow
TableFill
TableCopy
TableInit
ElemDrop
CancelPoll
GcRefTest
GcRefCast
GcStructGet
GcStructSet
GcArrayGet
GcArraySet
GcArrayLen
GcArrayFill
GcArrayCopy
GcArrayNewData
GcArrayNewElem
GcArrayInitData
GcArrayInitElem
GcTypeCheckSubtype
GcRegisterStructInline
GcRegisterArrayInline
GcAllocStructSlow
GcAllocArrayFromValuesSlow
GcAllocArraySlow
GcStructGetV128
GcStructSetV128
GcArrayGetV128
GcArraySetV128
GcArrayFillV128
GcAllocStructWideSlow
GcAllocArrayWideSlow
GcAllocArrayFromSlotsSlow
ExceptionTryBegin
ExceptionTryEnd
ExceptionThrow
ExceptionThrowTag
ExceptionThrowRef
ExceptionDelegate
ExceptionGetTag
ExceptionGetValue
ExceptionGetValueCount
ExceptionSigsetjmp
ExceptionSpillLocals
ExceptionGetSpilledLocal
} derive(Eq,
Debug
)

Runtime operations required by WebAssembly lowering.

The helper identity stays typed throughout lowering. An embedding assigns its external symbol spelling only when the operation enters MilkIR or MachV.

WasmStorageContract

pub(all) enum WasmStorageContract {
Value(
Type
)
Packed8
Packed16
} derive(Eq,
Debug
)

The lowered MilkIR carrier and packed representation of a WebAssembly field.

WasmTableContract

pub(all) struct WasmTableContract {
index_type :
Type

element_type :
Type

} derive(Eq,
Debug
)

The contextual contract for a WebAssembly table.

WasmValidationContext

type WasmValidationContext

Module and linker metadata required to validate Wasm extension operations.

The context is supplied explicitly at the Wasm adapter seam and is never stored in MilkIR. Linked direct functions use their remapped global index; indexed types, tables, tags, and segments use module-local indices.

WasmValidationContext::empty

Construct a context that rejects every module-indexed operation.

This is useful for lowering functions that contain only context-free Wasm operations; it is not a fallback for module-produced MilkIR.

WasmValidationContext::new

Construct an explicit contextual-validation adapter.

WasmValidationContext::validate_extension

Validate one Wasm extension against module and linker metadata.

WasmValidationContext::validate_global_value

WasmValidationResolvers

pub(all) struct WasmValidationResolvers {
function_contract : (Int) -> WasmFunctionContract?
defined_type_contract : (Int) -> WasmDefinedTypeContract?
table_contract : (Int) -> WasmTableContract?
tag_contract : (Int) -> WasmFunctionContract?
memory_exists : (Int) -> Bool
data_segment_exists : (Int) -> Bool
element_segment_type : (Int) ->
Type
?
}

Resolver interface used to construct a contextual-validation adapter.

EXTERNREF_TAG

let EXTERNREF_TAG : Int64

Tag for externref values: bit 62 set.

FUNCREF_TAG

let FUNCREF_TAG : Int64

Tag for funcref pointer values: bit 61 set.

NULL_REF

let NULL_REF : Int64

Null reference value in the lowered reference representation.

WASM_DIALECT

let WASM_DIALECT : String

Serialized dialect name used by Wasm MilkIR extension operations.

array_copy

fn array_copy(builder :
FunctionBuilder
, dst_type_idx : Int, src_type_idx : Int, dst :
Value
, dst_offset :
Value
, src :
Value
, src_offset :
Value
, count :
Value
) -> Unit

array_get_s

fn array_get_s(builder :
FunctionBuilder
, type_idx : Int, array_ref :
Value
, index :
Value
, byte_width : Int) ->
Value

array_get_u

fn array_get_u(builder :
FunctionBuilder
, type_idx : Int, array_ref :
Value
, index :
Value
, byte_width : Int) ->
Value

array_init_data

fn array_init_data(builder :
FunctionBuilder
, type_idx : Int, data_idx : Int, array_ref :
Value
, arr_offset :
Value
, data_offset :
Value
, length :
Value
) -> Unit

array_init_elem

fn array_init_elem(builder :
FunctionBuilder
, type_idx : Int, elem_idx : Int, array_ref :
Value
, arr_offset :
Value
, elem_offset :
Value
, length :
Value
) -> Unit

array_new_data

fn array_new_data(builder :
FunctionBuilder
, type_idx : Int, data_idx : Int, data_offset :
Value
, length :
Value
) ->
Value

array_new_default

array_new_elem

fn array_new_elem(builder :
FunctionBuilder
, type_idx : Int, elem_idx : Int, elem_offset :
Value
, length :
Value
) ->
Value

array_new_fixed

fn array_new_fixed(builder :
FunctionBuilder
, type_idx : Int, count : Int, elements : Array[
Value
]) ->
Value

array_set

call_indirect_multi

data_drop

fn data_drop(builder :
FunctionBuilder
, runtime_symbols : RuntimeSymbols, vmctx :
Value
, data_idx : Int) -> Unit

decode_error

fn decode_error(ext :
ExtOp
) -> String?

decode_memory_base_context_field

fn decode_memory_base_context_field(field :
ContextField
) -> Int?

decode_opcode

fn decode_opcode(opcode :
Opcode
) -> WasmOpcode?

delegate

fn delegate(builder :
FunctionBuilder
, depth : Int) -> Unit

descriptor_by_name

fn descriptor_by_name(name : String) ->
ExtOpDescriptor
?

elem_drop

fn elem_drop(builder :
FunctionBuilder
, runtime_symbols : RuntimeSymbols, vmctx :
Value
, elem_idx : Int) -> Unit

emit_throw

fn emit_throw(builder :
FunctionBuilder
, tag_idx : Int, values : Array[
Value
]) -> Unit

emit_throw_ref

encode

get_exception_value

get_exception_value_count

get_func_ref

get_spilled_local

memory_base_context_field

fn memory_base_context_field(memory_index : Int) ->
ContextField

memory_copy

fn memory_copy(builder :
FunctionBuilder
, runtime_symbols : RuntimeSymbols, vmctx :
Value
, dst_memidx : Int, src_memidx : Int, dst :
Value
, src :
Value
, size :
Value
) -> Unit

memory_grow

fn memory_grow(builder :
FunctionBuilder
, runtime_symbols : RuntimeSymbols, vmctx :
Value
, memidx : Int, delta :
Value
, max_pages? : Int, is_memory64? : Bool) ->
Value

memory_init

fn memory_init(builder :
FunctionBuilder
, runtime_symbols : RuntimeSymbols, vmctx :
Value
, memidx : Int, data_idx : Int, dst :
Value
, src :
Value
, size :
Value
) -> Unit

memory_size

fn memory_size(builder :
FunctionBuilder
, runtime_symbols : RuntimeSymbols, vmctx :
Value
, memidx : Int, is_memory64? : Bool) ->
Value

ref_cast

fn ref_cast(builder :
FunctionBuilder
, type_idx : Int, nullable : Bool, ref_val :
Value
, result_type :
Type
) ->
Value

ref_test

fn ref_test(builder :
FunctionBuilder
, type_idx : Int, nullable : Bool, ref_val :
Value
) ->
Value

return_call_indirect_multi

fn return_call_indirect_multi(builder :
FunctionBuilder
, type_idx : Int, table_idx : Int, callee :
Value
, args : Array[
Value
]) -> Unit

return_call_multi

fn return_call_multi(builder :
FunctionBuilder
, func_idx : Int, args : Array[
Value
]) -> Unit

return_call_ref_multi

fn return_call_ref_multi(builder :
FunctionBuilder
, type_idx : Int, func_ref :
Value
, args : Array[
Value
]) -> Unit

spill_locals_for_throw

fn spill_locals_for_throw(builder :
FunctionBuilder
, locals : Array[
Value
]) -> Unit

struct_get

fn struct_get(builder :
FunctionBuilder
, type_idx : Int, field_idx : Int, struct_ref :
Value
, field_type :
Type
) ->
Value

struct_get_s

fn struct_get_s(builder :
FunctionBuilder
, type_idx : Int, field_idx : Int, struct_ref :
Value
, byte_width : Int) ->
Value

struct_get_u

fn struct_get_u(builder :
FunctionBuilder
, type_idx : Int, field_idx : Int, struct_ref :
Value
, byte_width : Int) ->
Value

struct_new_default

fn struct_new_default(builder :
FunctionBuilder
, type_idx : Int) ->
Value

struct_set

fn struct_set(builder :
FunctionBuilder
, type_idx : Int, field_idx : Int, struct_ref :
Value
, value :
Value
) -> Unit

table_copy

fn table_copy(builder :
FunctionBuilder
, runtime_symbols : RuntimeSymbols, vmctx :
Value
, dst_table_idx : Int, src_table_idx : Int, dst :
Value
, src :
Value
, size :
Value
) -> Unit

table_grow

fn table_grow(builder :
FunctionBuilder
, runtime_symbols : RuntimeSymbols, vmctx :
Value
, table_idx : Int, delta :
Value
, init_value :
Value
, is_table64? : Bool) ->
Value

table_init

fn table_init(builder :
FunctionBuilder
, runtime_symbols : RuntimeSymbols, vmctx :
Value
, table_idx : Int, elem_idx : Int, dst :
Value
, src :
Value
, size :
Value
) -> Unit

try_table_begin

fn try_table_begin(builder :
FunctionBuilder
, handler_id : Int) ->
Value

try_table_end

fn try_table_end(builder :
FunctionBuilder
, handler_id : Int) -> Unit

validate_extension

fn validate_extension(view :
ExtensionInstView
) -> String?

Validate one read-only Wasm extension instruction at an adapter seam.

validate_global_value

fn validate_global_value(data :
GlobalValueData
) -> String?

verify_function

Verify core MilkIR invariants and every extension against the Wasm schema.

verify_function_with_context

fn verify_function_with_context(func :
Function
, context : WasmValidationContext) -> Unit raise
VerifyError

Verify core MilkIR, local Wasm schema, and module-contextual contracts.

wasm_externref_type

fn wasm_externref_type() ->
Type

wasm_funcref_type

fn wasm_funcref_type() ->
Type

Powered by MoonBit

Site sourceReport issuePackagesBuild queueSkillsStatistics

© 2026 mooncakes.io