WebAssembly dialect adapter for MilkIR extension operations
Dependencies
///|
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")
}///|
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")
}
}///|
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")
),
)
}pub(all) enum WasmDefinedTypeContract {
Function(WasmFunctionContract)
Struct(Array[WasmFieldContract])
Array(WasmFieldContract)
} derive(Eq, Debug)pub(all) struct WasmFieldContract {
storage : WasmStorageContract
mutable_ : Bool
defaultable : Bool
} derive(Eq, Debug)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)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)type WasmValidationContextfn WasmValidationContext::validate_extension(self : WasmValidationContext, view : ExtensionInstView, enclosing_results : Array[Type]) -> String?fn WasmValidationContext::validate_global_value(self : WasmValidationContext, data : GlobalValueData) -> String?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?
}let WASM_DIALECT : Stringfn array_fill(builder : FunctionBuilder, type_idx : Int, array_ref : Value, offset : Value, value : Value, count : Value) -> Unitfn array_get(builder : FunctionBuilder, type_idx : Int, array_ref : Value, index : Value, element_type : Type) -> Valuefn array_get_s(builder : FunctionBuilder, type_idx : Int, array_ref : Value, index : Value, byte_width : Int) -> Valuefn array_get_u(builder : FunctionBuilder, type_idx : Int, array_ref : Value, index : Value, byte_width : Int) -> Valuefn array_init_data(builder : FunctionBuilder, type_idx : Int, data_idx : Int, array_ref : Value, arr_offset : Value, data_offset : Value, length : Value) -> Unitfn array_init_elem(builder : FunctionBuilder, type_idx : Int, elem_idx : Int, array_ref : Value, arr_offset : Value, elem_offset : Value, length : Value) -> Unitfn array_new(builder : FunctionBuilder, type_idx : Int, init_value : Value, length : Value) -> Valuefn array_new_data(builder : FunctionBuilder, type_idx : Int, data_idx : Int, data_offset : Value, length : Value) -> Valuefn array_new_elem(builder : FunctionBuilder, type_idx : Int, elem_idx : Int, elem_offset : Value, length : Value) -> Valuefn array_new_fixed(builder : FunctionBuilder, type_idx : Int, count : Int, elements : Array[Value]) -> Valuefn array_set(builder : FunctionBuilder, type_idx : Int, array_ref : Value, index : Value, value : Value) -> Unitfn data_drop(builder : FunctionBuilder, runtime_symbols : RuntimeSymbols, vmctx : Value, data_idx : Int) -> Unitfn elem_drop(builder : FunctionBuilder, runtime_symbols : RuntimeSymbols, vmctx : Value, elem_idx : Int) -> Unitfn load_mem_base(builder : FunctionBuilder, vmctx : Value, memidx : Int, stability : GlobalValueStability) -> Valuefn memory_copy(builder : FunctionBuilder, runtime_symbols : RuntimeSymbols, vmctx : Value, dst_memidx : Int, src_memidx : Int, dst : Value, src : Value, size : Value) -> Unitfn memory_fill(builder : FunctionBuilder, runtime_symbols : RuntimeSymbols, vmctx : Value, memidx : Int, dst : Value, val : Value, size : Value) -> Unitfn memory_grow(builder : FunctionBuilder, runtime_symbols : RuntimeSymbols, vmctx : Value, memidx : Int, delta : Value, max_pages? : Int, is_memory64? : Bool) -> Valuefn memory_init(builder : FunctionBuilder, runtime_symbols : RuntimeSymbols, vmctx : Value, memidx : Int, data_idx : Int, dst : Value, src : Value, size : Value) -> Unitfn memory_size(builder : FunctionBuilder, runtime_symbols : RuntimeSymbols, vmctx : Value, memidx : Int, is_memory64? : Bool) -> Valuefn ref_cast(builder : FunctionBuilder, type_idx : Int, nullable : Bool, ref_val : Value, result_type : Type) -> Valuefn return_call_indirect_multi(builder : FunctionBuilder, type_idx : Int, table_idx : Int, callee : Value, args : Array[Value]) -> Unitfn return_call_ref_multi(builder : FunctionBuilder, type_idx : Int, func_ref : Value, args : Array[Value]) -> Unitfn struct_get(builder : FunctionBuilder, type_idx : Int, field_idx : Int, struct_ref : Value, field_type : Type) -> Valuefn struct_get_s(builder : FunctionBuilder, type_idx : Int, field_idx : Int, struct_ref : Value, byte_width : Int) -> Valuefn struct_get_u(builder : FunctionBuilder, type_idx : Int, field_idx : Int, struct_ref : Value, byte_width : Int) -> Valuefn struct_set(builder : FunctionBuilder, type_idx : Int, field_idx : Int, struct_ref : Value, value : Value) -> Unitfn table_copy(builder : FunctionBuilder, runtime_symbols : RuntimeSymbols, vmctx : Value, dst_table_idx : Int, src_table_idx : Int, dst : Value, src : Value, size : Value) -> Unitfn table_fill(builder : FunctionBuilder, runtime_symbols : RuntimeSymbols, vmctx : Value, table_idx : Int, dst : Value, val : Value, size : Value) -> Unitfn table_grow(builder : FunctionBuilder, runtime_symbols : RuntimeSymbols, vmctx : Value, table_idx : Int, delta : Value, init_value : Value, is_table64? : Bool) -> Valuefn table_init(builder : FunctionBuilder, runtime_symbols : RuntimeSymbols, vmctx : Value, table_idx : Int, elem_idx : Int, dst : Value, src : Value, size : Value) -> Unitfn verify_function_with_context(func : Function, context : WasmValidationContext) -> Unit raise VerifyErrorWebAssembly dialect adapter for MilkIR extension operations
Dependencies