1pub(crate) use ruka_runtime::wasm_api;
2pub(crate) use ruka_runtime::wasm_api::WasmValType;
3pub(crate) use ruka_types::Ty;
4pub(crate) use std::collections::{BTreeMap, BTreeSet};
5pub(crate) use thiserror::Error;
6pub(crate) use walrus::ir::{
7 BinaryOp, InstrSeqId, Load, LoadKind, MemArg, Store, StoreKind, UnaryOp,
8};
9pub(crate) use walrus::{FunctionBuilder, FunctionId, LocalId, MemoryId, ValType};
10pub(crate) use wasmparser::Validator;
11pub(crate) use wasmprinter::{Config as WatPrinterConfig, PrintFmtWrite};
12
13#[path = "codegen/wasm/aggregate.rs"]
14pub(crate) mod aggregate;
15#[path = "codegen/wasm/linker.rs"]
16pub(crate) mod linker;
17#[path = "codegen/wasm/literals.rs"]
18pub(crate) mod literals;
19#[path = "codegen/wasm/types.rs"]
20pub(crate) mod types;
21
22pub use types::{WasmArtifacts, WasmDiagnostic};
23
24pub(crate) use linker::{RuntimeFunctions, link_runtime_with_literals};
25pub(crate) use literals::collect_string_literals;
26
27#[derive(Debug, Clone, Error)]
29pub(crate) enum LowerError {
30 #[error("failed to parse runtime artifact: {0}")]
31 ParseRuntime(String),
32 #[error("missing runtime export `{export_name}` for symbol `{symbol}`")]
33 MissingRuntimeExport { symbol: String, export_name: String },
34 #[error("missing exported runtime memory")]
35 MissingRuntimeMemory,
36 #[error("missing exported runtime global `{0}`")]
37 MissingRuntimeGlobal(&'static str),
38 #[error("unsupported instruction in wasm backend: {0}")]
39 UnsupportedInstruction(&'static str),
40 #[error("unknown callee id in wasm backend")]
41 UnknownCallee,
42 #[error("unknown string literal offset for `{0}`")]
43 UnknownStringLiteral(String),
44 #[error("unknown runtime symbol `{0}` in wasm backend")]
45 UnknownRuntimeSymbol(String),
46 #[error("unsupported block parameter arity mismatch")]
47 BlockParamArityMismatch,
48 #[error("missing block pc for block {0} in wasm backend")]
49 MissingBlockPc(u32),
50 #[error("missing block {0} in wasm backend")]
51 MissingBlock(u32),
52 #[error("value does not fit wasm32 for {0}")]
53 Int32Overflow(&'static str),
54 #[error("function `{function}` has unsupported borrowed return type `{return_ty}`")]
55 BorrowedReturnType { function: String, return_ty: String },
56}
57
58pub(crate) const ARRAY_HEADER_OFFSET: u32 = 0;
59pub(crate) const ARRAY_LEN_OFFSET: u32 = 4;
60pub(crate) const ARRAY_CAP_OFFSET: u32 = 8;
61pub(crate) const ARRAY_DATA_OFFSET: u32 = 12;
62pub(crate) const ARRAY_SLOT_BYTES: i32 = 8;
63pub(crate) const POINTER_VALUE_OFFSET: u32 = 8;
64pub(crate) const POINTER_CELL_BYTES: i32 = 16;
65pub(crate) const ALLOC_SITE_POINTER_NEW: i32 = wasm_api::ALLOC_SITE_POINTER_NEW;
66pub(crate) const ALLOC_SITE_POINTER_CLONE: i32 = wasm_api::ALLOC_SITE_POINTER_CLONE;
67pub(crate) const ALLOC_SITE_ARRAY_NEW: i32 = wasm_api::ALLOC_SITE_ARRAY_NEW;
68pub(crate) const ALLOC_SITE_AGGREGATE_NEW: i32 = wasm_api::ALLOC_SITE_AGGREGATE_NEW;
69pub(crate) const ALLOC_SITE_ENUM_NEW: i32 = wasm_api::ALLOC_SITE_ENUM_NEW;
70pub(crate) const STRING_HEADER_OFFSET: u32 = 0;
71pub(crate) const STRING_LEN_OFFSET: u32 = 4;
72pub(crate) const STRING_DATA_OFFSET: u32 = 8;
73pub(crate) const ENUM_TAG_OFFSET: u32 = 0;
74pub(crate) const ENUM_PAYLOAD_OFFSET: u32 = 4;
75
76#[derive(Clone, Copy)]
77pub(crate) struct LowerCtx<'a> {
78 pub(crate) function: &'a ruka_mir::MirFunction,
79 pub(crate) local_indices: &'a BTreeMap<u32, Option<LocalId>>,
80 pub(crate) local_runtime_types: &'a BTreeMap<u32, Option<ValType>>,
81 pub(crate) local_tys: &'a BTreeMap<u32, Ty>,
82 pub(crate) local_reprs: &'a BTreeMap<u32, ruka_mir::MirLocalRepr>,
83 pub(crate) local_heap_ownership: &'a BTreeMap<u32, ruka_mir::MirHeapOwnership>,
84 pub(crate) passthrough_place_locals: &'a BTreeSet<u32>,
85 pub(crate) shadow_stack_offsets: &'a BTreeMap<u32, u32>,
86 pub(crate) func_id_by_mir: &'a BTreeMap<u32, FunctionId>,
87 pub(crate) callee_param_runtime_mask: &'a BTreeMap<u32, Vec<bool>>,
88 pub(crate) callee_param_runtime_types: &'a BTreeMap<u32, Vec<ValType>>,
89 pub(crate) callee_param_inout_mask: &'a BTreeMap<u32, Vec<bool>>,
90 pub(crate) callee_returns_via_out_slot: &'a BTreeMap<u32, bool>,
91 pub(crate) callee_returns_runtime: &'a BTreeMap<u32, bool>,
92 pub(crate) runtime: &'a RuntimeFunctions,
93 pub(crate) pointer_drop_functions: &'a BTreeMap<String, FunctionId>,
94 pub(crate) memory_id: MemoryId,
95 pub(crate) string_literal_offsets: &'a BTreeMap<String, u32>,
96 pub(crate) structs: &'a [ruka_mir::MirStructDecl],
97 pub(crate) enums: &'a [ruka_mir::MirEnumDecl],
98 pub(crate) function_line: i32,
99 pub(crate) scratch_i64_local: LocalId,
100 pub(crate) scratch_i32_local: LocalId,
101 pub(crate) scratch_i32_local_b: LocalId,
102 pub(crate) scratch_i32_local_c: LocalId,
103 pub(crate) scratch_i32_local_d: LocalId,
104 pub(crate) scratch_i32_local_e: LocalId,
105}
106
107#[derive(Clone, Copy)]
108pub(crate) struct ModuleLowerCtx<'a> {
109 pub(crate) func_id_by_mir: &'a BTreeMap<u32, FunctionId>,
110 pub(crate) callee_param_runtime_mask: &'a BTreeMap<u32, Vec<bool>>,
111 pub(crate) callee_param_runtime_types: &'a BTreeMap<u32, Vec<ValType>>,
112 pub(crate) callee_param_inout_mask: &'a BTreeMap<u32, Vec<bool>>,
113 pub(crate) callee_returns_via_out_slot: &'a BTreeMap<u32, bool>,
114 pub(crate) callee_returns_runtime: &'a BTreeMap<u32, bool>,
115 pub(crate) runtime: &'a RuntimeFunctions,
116 pub(crate) pointer_drop_functions: &'a BTreeMap<String, FunctionId>,
117 pub(crate) memory_id: MemoryId,
118 pub(crate) string_literal_offsets: &'a BTreeMap<String, u32>,
119 pub(crate) structs: &'a [ruka_mir::MirStructDecl],
120 pub(crate) enums: &'a [ruka_mir::MirEnumDecl],
121 pub(crate) function_lines: &'a BTreeMap<String, usize>,
122}
123
124#[derive(Clone, Copy)]
125pub(crate) struct TerminatorCtx<'a> {
126 pub(crate) function: &'a ruka_mir::MirFunction,
127 pub(crate) local_indices: &'a BTreeMap<u32, Option<LocalId>>,
128 pub(crate) local_runtime_types: &'a BTreeMap<u32, Option<ValType>>,
129 pub(crate) local_heap_ownership: &'a BTreeMap<u32, ruka_mir::MirHeapOwnership>,
130 pub(crate) runtime: &'a RuntimeFunctions,
131 pub(crate) pointer_drop_functions: &'a BTreeMap<String, FunctionId>,
132 pub(crate) memory_id: MemoryId,
133 pub(crate) structs: &'a [ruka_mir::MirStructDecl],
134 pub(crate) enums: &'a [ruka_mir::MirEnumDecl],
135 pub(crate) block_id_to_pc: &'a BTreeMap<u32, i32>,
136 pub(crate) pc_local: LocalId,
137 pub(crate) break_target: InstrSeqId,
138 pub(crate) out_slot_param_local: Option<LocalId>,
139 pub(crate) out_slot_payload_bytes: u32,
140 pub(crate) scratch_i32_local: LocalId,
141 pub(crate) scratch_i32_local_b: LocalId,
142 pub(crate) scratch_i32_local_c: LocalId,
143 pub(crate) scratch_i32_local_d: LocalId,
144 pub(crate) scratch_i64_local: LocalId,
145 pub(crate) shadow_stack_frame_bytes: u32,
146 pub(crate) parallel_tmp_i64_locals: &'a [LocalId],
147 pub(crate) parallel_tmp_i32_locals: &'a [LocalId],
148}