wasmtime_environ/component/
vmcomponent_offsets.rs1use crate::GetPtrSize;
20use crate::PtrSize;
21use crate::component::*;
22
23pub const VMCOMPONENT_MAGIC: u32 = u32::from_le_bytes(*b"comp");
28
29#[derive(Debug, Clone, Copy)]
31pub struct VMComponentOffsets<P> {
32 pub ptr: P,
34
35 pub num_lowerings: u32,
37 pub num_runtime_memories: u32,
39 pub num_runtime_tables: u32,
41 pub num_runtime_reallocs: u32,
43 pub num_runtime_callbacks: u32,
45 pub num_runtime_post_returns: u32,
47 pub num_runtime_component_instances: u32,
50 pub num_trampolines: u32,
52 pub num_unsafe_intrinsics: u32,
55 pub num_resources: u32,
57
58 magic: u32,
60 builtins: u32,
61 vm_store_context: u32,
62 may_leave: u32,
63 task_may_block: u32,
64 trampoline_func_refs: u32,
65 intrinsic_func_refs: u32,
66 lowerings: u32,
67 memories: u32,
68 tables: u32,
69 reallocs: u32,
70 callbacks: u32,
71 post_returns: u32,
72 resource_destructors: u32,
73 size: u32,
74}
75
76impl<P: PtrSize> GetPtrSize for VMComponentOffsets<P> {
77 type Ptr = P;
78
79 #[inline]
80 fn get_ptr_size(&self) -> &Self::Ptr {
81 &self.ptr
82 }
83}
84
85#[inline]
86fn align(offset: u32, align: u32) -> u32 {
87 assert!(align.is_power_of_two());
88 (offset + (align - 1)) & !(align - 1)
89}
90
91impl<P: PtrSize> VMComponentOffsets<P> {
92 pub fn new(ptr: P, component: &Component) -> Self {
95 let mut ret = Self {
96 ptr,
97 num_lowerings: component.num_lowerings,
98 num_runtime_memories: component.num_runtime_memories,
99 num_runtime_tables: component.num_runtime_tables,
100 num_runtime_reallocs: component.num_runtime_reallocs,
101 num_runtime_callbacks: component.num_runtime_callbacks,
102 num_runtime_post_returns: component.num_runtime_post_returns,
103 num_runtime_component_instances: component.num_runtime_component_instances,
104 num_trampolines: component.trampolines.len().try_into().unwrap(),
105 num_unsafe_intrinsics: if let Some(i) = component
106 .unsafe_intrinsics
107 .iter()
108 .rposition(|x| x.is_some())
109 {
110 u32::try_from(i + 1).unwrap()
124 } else {
125 0
126 },
127 num_resources: component.num_resources,
128 magic: 0,
129 builtins: 0,
130 vm_store_context: 0,
131 may_leave: 0,
132 task_may_block: 0,
133 trampoline_func_refs: 0,
134 intrinsic_func_refs: 0,
135 lowerings: 0,
136 memories: 0,
137 tables: 0,
138 reallocs: 0,
139 callbacks: 0,
140 post_returns: 0,
141 resource_destructors: 0,
142 size: 0,
143 };
144
145 #[inline]
150 fn cmul(count: u32, size: u8) -> u32 {
151 count.checked_mul(u32::from(size)).unwrap()
152 }
153
154 let mut next_field_offset = 0;
155
156 macro_rules! fields {
157 (size($field:ident) = $size:expr, $($rest:tt)*) => {
158 ret.$field = next_field_offset;
159 next_field_offset = next_field_offset.checked_add(u32::from($size)).unwrap();
160 fields!($($rest)*);
161 };
162 (align($align:expr), $($rest:tt)*) => {
163 next_field_offset = align(next_field_offset, $align);
164 fields!($($rest)*);
165 };
166 () => {};
167 }
168
169 fields! {
170 size(magic) = 4u32,
171 align(u32::from(ret.ptr.size())),
172 size(builtins) = ret.ptr.size(),
173 size(vm_store_context) = ret.ptr.size(),
174 align(16),
175 size(may_leave) = cmul(ret.num_runtime_component_instances, ret.ptr.size_of_vmglobal_definition()),
176 size(task_may_block) = ret.ptr.size_of_vmglobal_definition(),
177 align(u32::from(ret.ptr.size())),
178 size(trampoline_func_refs) = cmul(ret.num_trampolines, ret.ptr.size_of_vm_func_ref()),
179 size(intrinsic_func_refs) = cmul(ret.num_unsafe_intrinsics, ret.ptr.size_of_vm_func_ref()),
180 size(lowerings) = cmul(ret.num_lowerings, ret.ptr.size() * 2),
181 size(memories) = cmul(ret.num_runtime_memories, ret.ptr.size()),
182 size(tables) = cmul(ret.num_runtime_tables, ret.size_of_vmtable_import()),
183 size(reallocs) = cmul(ret.num_runtime_reallocs, ret.ptr.size()),
184 size(callbacks) = cmul(ret.num_runtime_callbacks, ret.ptr.size()),
185 size(post_returns) = cmul(ret.num_runtime_post_returns, ret.ptr.size()),
186 size(resource_destructors) = cmul(ret.num_resources, ret.ptr.size()),
187 }
188
189 ret.size = next_field_offset;
190
191 assert_eq!(ret.magic, 0);
195
196 return ret;
197 }
198
199 #[inline]
201 pub fn pointer_size(&self) -> u8 {
202 self.ptr.size()
203 }
204
205 #[inline]
207 pub fn magic(&self) -> u32 {
208 self.magic
209 }
210
211 #[inline]
213 pub fn builtins(&self) -> u32 {
214 self.builtins
215 }
216
217 #[inline]
219 pub fn may_leave(&self, index: RuntimeComponentInstanceIndex) -> u32 {
220 assert!(index.as_u32() < self.num_runtime_component_instances);
221 self.may_leave + index.as_u32() * u32::from(self.ptr.size_of_vmglobal_definition())
222 }
223
224 pub fn task_may_block(&self) -> u32 {
226 self.task_may_block
227 }
228
229 #[inline]
231 pub fn vm_store_context(&self) -> u32 {
232 self.vm_store_context
233 }
234
235 #[inline]
237 pub fn trampoline_func_refs(&self) -> u32 {
238 self.trampoline_func_refs
239 }
240
241 #[inline]
243 pub fn trampoline_func_ref(&self, index: TrampolineIndex) -> u32 {
244 assert!(index.as_u32() < self.num_trampolines);
245 self.trampoline_func_refs() + index.as_u32() * u32::from(self.ptr.size_of_vm_func_ref())
246 }
247
248 #[inline]
250 pub fn unsafe_intrinsic_func_refs(&self) -> u32 {
251 self.intrinsic_func_refs
252 }
253
254 #[inline]
256 pub fn unsafe_intrinsic_func_ref(&self, intrinsic: UnsafeIntrinsic) -> u32 {
257 assert!(intrinsic.index() < self.num_unsafe_intrinsics);
258 self.unsafe_intrinsic_func_refs()
259 + intrinsic.index() * u32::from(self.ptr.size_of_vm_func_ref())
260 }
261
262 #[inline]
264 pub fn lowerings(&self) -> u32 {
265 self.lowerings
266 }
267
268 #[inline]
270 pub fn lowering(&self, index: LoweredIndex) -> u32 {
271 assert!(index.as_u32() < self.num_lowerings);
272 self.lowerings() + index.as_u32() * u32::from(2 * self.ptr.size())
273 }
274
275 #[inline]
277 pub fn lowering_callee(&self, index: LoweredIndex) -> u32 {
278 self.lowering(index) + self.lowering_callee_offset()
279 }
280
281 #[inline]
283 pub fn lowering_data(&self, index: LoweredIndex) -> u32 {
284 self.lowering(index) + self.lowering_data_offset()
285 }
286
287 #[inline]
289 pub fn lowering_size(&self) -> u8 {
290 2 * self.ptr.size()
291 }
292
293 #[inline]
295 pub fn lowering_callee_offset(&self) -> u32 {
296 0
297 }
298
299 #[inline]
301 pub fn lowering_data_offset(&self) -> u32 {
302 u32::from(self.ptr.size())
303 }
304
305 #[inline]
307 pub fn runtime_memories(&self) -> u32 {
308 self.memories
309 }
310
311 #[inline]
314 pub fn runtime_memory(&self, index: RuntimeMemoryIndex) -> u32 {
315 assert!(index.as_u32() < self.num_runtime_memories);
316 self.runtime_memories() + index.as_u32() * u32::from(self.ptr.size())
317 }
318
319 #[inline]
321 pub fn runtime_tables(&self) -> u32 {
322 self.tables
323 }
324
325 #[inline]
327 pub fn runtime_table(&self, index: RuntimeTableIndex) -> u32 {
328 assert!(index.as_u32() < self.num_runtime_tables);
329 self.runtime_tables() + index.as_u32() * u32::from(self.size_of_vmtable_import())
330 }
331
332 #[inline]
335 pub fn size_of_vmtable_import(&self) -> u8 {
336 3 * self.pointer_size()
337 }
338
339 #[inline]
341 pub fn runtime_reallocs(&self) -> u32 {
342 self.reallocs
343 }
344
345 #[inline]
348 pub fn runtime_realloc(&self, index: RuntimeReallocIndex) -> u32 {
349 assert!(index.as_u32() < self.num_runtime_reallocs);
350 self.runtime_reallocs() + index.as_u32() * u32::from(self.ptr.size())
351 }
352
353 #[inline]
355 pub fn runtime_callbacks(&self) -> u32 {
356 self.callbacks
357 }
358
359 #[inline]
362 pub fn runtime_callback(&self, index: RuntimeCallbackIndex) -> u32 {
363 assert!(index.as_u32() < self.num_runtime_callbacks);
364 self.runtime_callbacks() + index.as_u32() * u32::from(self.ptr.size())
365 }
366
367 #[inline]
369 pub fn runtime_post_returns(&self) -> u32 {
370 self.post_returns
371 }
372
373 #[inline]
376 pub fn runtime_post_return(&self, index: RuntimePostReturnIndex) -> u32 {
377 assert!(index.as_u32() < self.num_runtime_post_returns);
378 self.runtime_post_returns() + index.as_u32() * u32::from(self.ptr.size())
379 }
380
381 #[inline]
383 pub fn resource_destructors(&self) -> u32 {
384 self.resource_destructors
385 }
386
387 #[inline]
390 pub fn resource_destructor(&self, index: ResourceIndex) -> u32 {
391 assert!(index.as_u32() < self.num_resources);
392 self.resource_destructors() + index.as_u32() * u32::from(self.ptr.size())
393 }
394
395 #[inline]
397 pub fn size_of_vmctx(&self) -> u32 {
398 self.size
399 }
400}