///|
pub(all) enum RuntimeComponent {
Cli
RuntimeObjects
InterpreterExecutor
WasiPreview1
JitSelection
} derive(Eq, Debug)
///|
pub(all) struct RuntimeAssembly {
product_module : String
owned_components : Array[RuntimeComponent]
reusable_modules : Array[String]
} derive(Eq, Debug)
///|
pub(all) struct CompilerInfrastructureAssembly {
signature : @milkir.Signature
machv_function : @machv.Function
allocated_function : @machv.Function
code_object : @machv_emit.MachineCode
x64_abi : @x64_target.AbiPolicy
aarch64_abi : @aarch64_target.AbiPolicy
jit_glue : Array[@wasmoon_jit.NativeGlueBinding]
}
///|
pub suberror WasmCompilerPipelineError {
WasmCompilerPipelineFailure(message~ : String)
} derive(Debug, Eq)
///|
pub impl Show for WasmCompilerPipelineError with fn output(self, logger) {
logger.write_string(to_repr(self).to_string())
}
///|
pub fn wasm_frontend_embedding_environment(
runtime_symbol_prefix? : String = "wasmoon",
hidden_context_type? : @milkir.Type? = Some(Ptr),
) -> @wasm_frontend.EmbeddingEnvironment {
let vm = @wasmoon_jit.vmcontext_layout()
let memory = @wasmoon_jit.memory_descriptor_layout()
EmbeddingEnvironment(
runtime_symbol_prefix~,
hidden_context_type~,
runtime_layout=Some({
memory0_base_offset: vm.memory0_base_offset,
memory0_size_offset: vm.memory0_size_offset,
func_table_offset: vm.func_table_offset,
table0_base_offset: vm.table0_base_offset,
table0_elements_offset: vm.table0_elements_offset,
globals_offset: vm.globals_offset,
tables_offset: vm.tables_offset,
table_sizes_offset: vm.table_sizes_offset,
memories_offset: vm.memories_offset,
pointer_stride: vm.pointer_stride,
global_value_stride: vm.global_value_stride,
table_entry_value_offset: vm.table_entry_value_offset,
table_entry_stride: vm.table_entry_stride,
func_table_entry_stride: vm.func_table_entry_stride,
}),
memory_descriptor_layout=Some({
base_offset: memory.base_offset,
current_length_offset: memory.current_length_offset,
}),
)
}
///|
fn wasm_body_embedding_env(
env : @wasm_frontend.EmbeddingEnvironment,
) -> @wasm_frontend.EmbeddingEnvironment {
if env.hidden_context_param() is Some(_) {
env
} else {
EmbeddingEnvironment(
runtime_symbol_prefix=env.runtime_symbol_prefix,
runtime_layout=env.runtime_layout(),
memory_descriptor_layout=env.memory_descriptor_layout(),
)
}
}
///|
pub fn runtime_assembly() -> RuntimeAssembly {
{
product_module: "Milky2018/wasmoon",
owned_components: [
Cli,
RuntimeObjects,
InterpreterExecutor,
WasiPreview1,
JitSelection,
],
reusable_modules: [
"Milky2018/wasm_core", "Milky2018/milkir", "Milky2018/machv", "Milky2018/regalloc",
"Milky2018/machv_regalloc", "Milky2018/machv_emit", "Milky2018/x64_target",
"Milky2018/aarch64_target", "Milky2018/wasmoon_jit",
],
}
}
///|
pub fn compiler_infrastructure_assembly() -> CompilerInfrastructureAssembly {
let signature = @milkir.Signature::Signature([], [])
let milk = @milkir.Function::Function("wasmoon_runtime_probe", signature)
let entry = milk.new_block0()
entry.set_terminator(Return([]))
let embedding_abi = @wasmoon_jit.wasm_embedding_abi()
let machv_function = @lower.lower_function(
milk,
run_ir_opt=false,
embedding_abi=Some(embedding_abi),
)
let (allocated_function, output) = @machv_regalloc.allocate_registers_backtracking_output(
machv_function,
embedding_abi=Some(embedding_abi),
)
{
signature,
machv_function,
allocated_function,
code_object: @machv_emit.emit_function_with_regalloc(
allocated_function,
output,
embedding_abi=Some(embedding_abi),
),
x64_abi: @x64_target.abi_policy(),
aarch64_abi: @aarch64_target.abi_policy(),
jit_glue: @wasmoon_jit.default_native_glue(),
}
}
///|
pub fn plan_wasm_function_with_compiler_infra(
env : @wasm_frontend.EmbeddingEnvironment,
mod_ : @types.Module,
func_local_idx : Int,
target : @machv_emit.EmitTarget,
opt_level? : Int = 2,
) -> @wasmoon_jit.JitIntegrationPlan raise WasmCompilerPipelineError {
try {
let body_env = wasm_body_embedding_env(env)
let milk = @wasm_frontend.lower_function(body_env, mod_, func_local_idx)
@milkir.optimize_with_level(milk, @milkir.OptLevel::from_int(opt_level))
|> ignore
@wasmoon_jit.plan_wasm_body_milkir_integration_for_target(milk, target)
} catch {
err => raise WasmCompilerPipelineFailure(message=to_repr(err).to_string())
}
}