1use crate::encoding::types::{FunctionKey, ValtypeEncoder};
2use anyhow::Result;
3use indexmap::IndexSet;
4use std::collections::HashMap;
5use std::mem;
6use wasm_encoder::*;
7use wit_parser::*;
8
9pub fn encode(resolve: &Resolve, package: PackageId) -> Result<Vec<u8>> {
28 let mut component = encode_component(resolve, package)?;
29 component.raw_custom_section(&crate::base_producers().raw_custom_section());
30 Ok(component.finish())
31}
32
33pub fn encode_component(resolve: &Resolve, package: PackageId) -> Result<ComponentBuilder> {
52 let mut encoder = Encoder {
53 component: ComponentBuilder::default(),
54 resolve,
55 package,
56 };
57 encoder.run()?;
58
59 let package_metadata = PackageMetadata::extract(resolve, package);
60 encoder.component.custom_section(&CustomSection {
61 name: PackageMetadata::SECTION_NAME.into(),
62 data: package_metadata.encode()?.into(),
63 });
64
65 Ok(encoder.component)
66}
67
68pub fn encode_world(resolve: &Resolve, world_id: WorldId) -> Result<ComponentType> {
70 let mut component = InterfaceEncoder::new(resolve);
71 let world = &resolve.worlds[world_id];
72 log::trace!("encoding world {}", world.name);
73
74 for (name, import) in world.imports.iter() {
76 let name = resolve.name_world_key(name);
77 log::trace!("encoding import {name}");
78 let ty = match import {
79 WorldItem::Interface { id, .. } => {
80 component.interface = Some(*id);
81 let idx = component.encode_instance(*id)?;
82 ComponentTypeRef::Instance(idx)
83 }
84 WorldItem::Function(f) => {
85 component.interface = None;
86 let idx = component.encode_func_type(resolve, f)?;
87 ComponentTypeRef::Func(idx)
88 }
89 WorldItem::Type(t) => {
90 component.interface = None;
91 component.import_types = true;
92 component.encode_valtype(resolve, &Type::Id(*t))?;
93 component.import_types = false;
94 continue;
95 }
96 };
97 component.outer.import(&name, ty);
98 }
99 for (name, export) in world.exports.iter() {
101 let name = resolve.name_world_key(name);
102 log::trace!("encoding export {name}");
103 let ty = match export {
104 WorldItem::Interface { id, .. } => {
105 component.interface = Some(*id);
106 let idx = component.encode_instance(*id)?;
107 ComponentTypeRef::Instance(idx)
108 }
109 WorldItem::Function(f) => {
110 component.interface = None;
111 let idx = component.encode_func_type(resolve, f)?;
112 ComponentTypeRef::Func(idx)
113 }
114 WorldItem::Type(_) => unreachable!(),
115 };
116 component.outer.export(&name, ty);
117 }
118
119 Ok(component.outer)
120}
121
122struct Encoder<'a> {
123 component: ComponentBuilder,
124 resolve: &'a Resolve,
125 package: PackageId,
126}
127
128impl Encoder<'_> {
129 fn run(&mut self) -> Result<()> {
130 for (name, &id) in self.resolve.packages[self.package].interfaces.iter() {
132 let component_ty = self.encode_interface(id)?;
133 let ty = self.component.type_component(&component_ty);
134 self.component
135 .export(name.as_ref(), ComponentExportKind::Type, ty, None);
136 }
137
138 for (name, &world) in self.resolve.packages[self.package].worlds.iter() {
141 let component_ty = encode_world(self.resolve, world)?;
142
143 let world = &self.resolve.worlds[world];
144 let mut wrapper = ComponentType::new();
145 wrapper.ty().component(&component_ty);
146 let pkg = &self.resolve.packages[world.package.unwrap()];
147 wrapper.export(&pkg.name.interface_id(name), ComponentTypeRef::Component(0));
148
149 let ty = self.component.type_component(&wrapper);
150 self.component
151 .export(name.as_ref(), ComponentExportKind::Type, ty, None);
152 }
153
154 Ok(())
155 }
156
157 fn encode_interface(&mut self, id: InterfaceId) -> Result<ComponentType> {
158 let mut interfaces = IndexSet::new();
167 self.add_live_interfaces(&mut interfaces, id);
168
169 let mut used_names = IndexSet::new();
173 for id in interfaces.iter() {
174 let iface = &self.resolve.interfaces[*id];
175 if iface.package == Some(self.package) {
176 let first = used_names.insert(iface.name.as_ref().unwrap().clone());
177 assert!(first);
178 }
179 }
180
181 let mut encoder = InterfaceEncoder::new(self.resolve);
182 for interface in interfaces {
183 encoder.interface = Some(interface);
184 let iface = &self.resolve.interfaces[interface];
185 let name = self.resolve.id_of(interface).unwrap();
186 if interface == id {
187 let idx = encoder.encode_instance(interface)?;
188 log::trace!("exporting self as {idx}");
189 encoder.outer.export(&name, ComponentTypeRef::Instance(idx));
190 } else {
191 encoder.push_instance();
192 for (_, id) in iface.types.iter() {
193 encoder.encode_valtype(self.resolve, &Type::Id(*id))?;
194 }
195 let instance = encoder.pop_instance();
196 let idx = encoder.outer.type_count();
197 encoder.outer.ty().instance(&instance);
198 encoder.import_map.insert(interface, encoder.instances);
199 encoder.instances += 1;
200 encoder.outer.import(&name, ComponentTypeRef::Instance(idx));
201 }
202 }
203
204 encoder.interface = None;
205
206 Ok(encoder.outer)
207 }
208
209 fn add_live_interfaces(&self, interfaces: &mut IndexSet<InterfaceId>, id: InterfaceId) {
212 if interfaces.contains(&id) {
213 return;
214 }
215 for id in self.resolve.interface_direct_deps(id) {
216 self.add_live_interfaces(interfaces, id);
217 }
218 assert!(interfaces.insert(id));
219 }
220}
221
222struct InterfaceEncoder<'a> {
223 resolve: &'a Resolve,
224 outer: ComponentType,
225 ty: Option<InstanceType>,
226 func_type_map: HashMap<FunctionKey<'a>, u32>,
227 type_map: HashMap<TypeId, u32>,
228 saved_types: Option<(HashMap<TypeId, u32>, HashMap<FunctionKey<'a>, u32>)>,
229 import_map: HashMap<InterfaceId, u32>,
230 outer_type_map: HashMap<TypeId, u32>,
231 instances: u32,
232 import_types: bool,
233 interface: Option<InterfaceId>,
234}
235
236impl InterfaceEncoder<'_> {
237 fn new(resolve: &Resolve) -> InterfaceEncoder<'_> {
238 InterfaceEncoder {
239 resolve,
240 outer: ComponentType::new(),
241 ty: None,
242 type_map: Default::default(),
243 func_type_map: Default::default(),
244 import_map: Default::default(),
245 outer_type_map: Default::default(),
246 instances: 0,
247 saved_types: None,
248 import_types: false,
249 interface: None,
250 }
251 }
252
253 fn encode_instance(&mut self, interface: InterfaceId) -> Result<u32> {
254 self.push_instance();
255 let iface = &self.resolve.interfaces[interface];
256 let mut type_order = IndexSet::new();
257 for (_, id) in iface.types.iter() {
258 self.encode_valtype(self.resolve, &Type::Id(*id))?;
259 type_order.insert(*id);
260 }
261
262 let mut funcs = iface.functions.iter().collect::<Vec<_>>();
278 funcs.sort_by_key(|(_name, func)| match func.kind.resource() {
279 Some(id) => type_order.get_index_of(&id).unwrap(),
280 None => type_order.len(),
281 });
282
283 for (name, func) in funcs {
284 let ty = self.encode_func_type(self.resolve, func)?;
285 self.ty
286 .as_mut()
287 .unwrap()
288 .export(name, ComponentTypeRef::Func(ty));
289 }
290 let instance = self.pop_instance();
291 let idx = self.outer.type_count();
292 self.outer.ty().instance(&instance);
293 self.import_map.insert(interface, self.instances);
294 self.instances += 1;
295 Ok(idx)
296 }
297
298 fn push_instance(&mut self) {
299 assert!(self.ty.is_none());
300 assert!(self.saved_types.is_none());
301 self.saved_types = Some((
302 mem::take(&mut self.type_map),
303 mem::take(&mut self.func_type_map),
304 ));
305 self.ty = Some(InstanceType::default());
306 }
307
308 fn pop_instance(&mut self) -> InstanceType {
309 let (types, funcs) = self.saved_types.take().unwrap();
310 self.type_map = types;
311 self.func_type_map = funcs;
312 mem::take(&mut self.ty).unwrap()
313 }
314}
315
316impl<'a> ValtypeEncoder<'a> for InterfaceEncoder<'a> {
317 fn defined_type(&mut self) -> (u32, ComponentDefinedTypeEncoder<'_>) {
318 match &mut self.ty {
319 Some(ty) => (ty.type_count(), ty.ty().defined_type()),
320 None => (self.outer.type_count(), self.outer.ty().defined_type()),
321 }
322 }
323 fn define_function_type(&mut self) -> (u32, ComponentFuncTypeEncoder<'_>) {
324 match &mut self.ty {
325 Some(ty) => (ty.type_count(), ty.ty().function()),
326 None => (self.outer.type_count(), self.outer.ty().function()),
327 }
328 }
329 fn export_type(&mut self, index: u32, name: &'a str) -> Option<u32> {
330 match &mut self.ty {
331 Some(ty) => {
332 assert!(!self.import_types);
333 let ret = ty.type_count();
334 ty.export(name, ComponentTypeRef::Type(TypeBounds::Eq(index)));
335 Some(ret)
336 }
337 None => {
338 let ret = self.outer.type_count();
339 if self.import_types {
340 self.outer
341 .import(name, ComponentTypeRef::Type(TypeBounds::Eq(index)));
342 } else {
343 self.outer
344 .export(name, ComponentTypeRef::Type(TypeBounds::Eq(index)));
345 }
346 Some(ret)
347 }
348 }
349 }
350 fn export_resource(&mut self, name: &'a str) -> u32 {
351 let type_ref = ComponentTypeRef::Type(TypeBounds::SubResource);
352 match &mut self.ty {
353 Some(ty) => {
354 assert!(!self.import_types);
355 ty.export(name, type_ref);
356 ty.type_count() - 1
357 }
358 None => {
359 if self.import_types {
360 self.outer.import(name, type_ref);
361 } else {
362 self.outer.export(name, type_ref);
363 }
364 self.outer.type_count() - 1
365 }
366 }
367 }
368 fn type_map(&mut self) -> &mut HashMap<TypeId, u32> {
369 &mut self.type_map
370 }
371 fn interface(&self) -> Option<InterfaceId> {
372 self.interface
373 }
374 fn import_type(&mut self, owner: InterfaceId, id: TypeId) -> u32 {
375 let ty = &self.resolve.types[id];
376 let instance = self.import_map[&owner];
377 let outer_idx = *self.outer_type_map.entry(id).or_insert_with(|| {
378 let ret = self.outer.type_count();
379 self.outer.alias(Alias::InstanceExport {
380 instance,
381 name: ty.name.as_ref().unwrap(),
382 kind: ComponentExportKind::Type,
383 });
384 ret
385 });
386 match &mut self.ty {
387 Some(ty) => {
388 let ret = ty.type_count();
389 ty.alias(Alias::Outer {
390 count: 1,
391 index: outer_idx,
392 kind: ComponentOuterAliasKind::Type,
393 });
394 ret
395 }
396 None => outer_idx,
397 }
398 }
399 fn func_type_map(&mut self) -> &mut HashMap<FunctionKey<'a>, u32> {
400 &mut self.func_type_map
401 }
402}