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 let mut imports = world.imports.iter().collect::<Vec<_>>();
88 imports.sort_by_key(|(_name, import)| match import {
89 WorldItem::Function(f) => match f.kind {
90 FunctionKind::Freestanding => 0,
91 _ => 1,
92 },
93 _ => 0,
94 });
95
96 for (name, import) in imports {
98 let name = resolve.name_world_key(name);
99 log::trace!("encoding import {name}");
100 let ty = match import {
101 WorldItem::Interface { id, .. } => {
102 component.interface = Some(*id);
103 let idx = component.encode_instance(*id)?;
104 ComponentTypeRef::Instance(idx)
105 }
106 WorldItem::Function(f) => {
107 component.interface = None;
108 let idx = component.encode_func_type(resolve, f)?;
109 ComponentTypeRef::Func(idx)
110 }
111 WorldItem::Type(t) => {
112 component.interface = None;
113 component.import_types = true;
114 component.encode_valtype(resolve, &Type::Id(*t))?;
115 component.import_types = false;
116 continue;
117 }
118 };
119 component.outer.import(&name, ty);
120 }
121 for (name, export) in world.exports.iter() {
123 let name = resolve.name_world_key(name);
124 log::trace!("encoding export {name}");
125 let ty = match export {
126 WorldItem::Interface { id, .. } => {
127 component.interface = Some(*id);
128 let idx = component.encode_instance(*id)?;
129 ComponentTypeRef::Instance(idx)
130 }
131 WorldItem::Function(f) => {
132 component.interface = None;
133 let idx = component.encode_func_type(resolve, f)?;
134 ComponentTypeRef::Func(idx)
135 }
136 WorldItem::Type(_) => unreachable!(),
137 };
138 component.outer.export(&name, ty);
139 }
140
141 Ok(component.outer)
142}
143
144struct Encoder<'a> {
145 component: ComponentBuilder,
146 resolve: &'a Resolve,
147 package: PackageId,
148}
149
150impl Encoder<'_> {
151 fn run(&mut self) -> Result<()> {
152 for (name, &id) in self.resolve.packages[self.package].interfaces.iter() {
154 let component_ty = self.encode_interface(id)?;
155 let ty = self.component.type_component(&component_ty);
156 self.component
157 .export(name.as_ref(), ComponentExportKind::Type, ty, None);
158 }
159
160 for (name, &world) in self.resolve.packages[self.package].worlds.iter() {
163 let component_ty = encode_world(self.resolve, world)?;
164
165 let world = &self.resolve.worlds[world];
166 let mut wrapper = ComponentType::new();
167 wrapper.ty().component(&component_ty);
168 let pkg = &self.resolve.packages[world.package.unwrap()];
169 wrapper.export(&pkg.name.interface_id(name), ComponentTypeRef::Component(0));
170
171 let ty = self.component.type_component(&wrapper);
172 self.component
173 .export(name.as_ref(), ComponentExportKind::Type, ty, None);
174 }
175
176 Ok(())
177 }
178
179 fn encode_interface(&mut self, id: InterfaceId) -> Result<ComponentType> {
180 let mut interfaces = IndexSet::new();
189 self.add_live_interfaces(&mut interfaces, id);
190
191 let mut used_names = IndexSet::new();
195 for id in interfaces.iter() {
196 let iface = &self.resolve.interfaces[*id];
197 if iface.package == Some(self.package) {
198 let first = used_names.insert(iface.name.as_ref().unwrap().clone());
199 assert!(first);
200 }
201 }
202
203 let mut encoder = InterfaceEncoder::new(self.resolve);
204 for interface in interfaces {
205 encoder.interface = Some(interface);
206 let iface = &self.resolve.interfaces[interface];
207 let name = self.resolve.id_of(interface).unwrap();
208 if interface == id {
209 let idx = encoder.encode_instance(interface)?;
210 log::trace!("exporting self as {idx}");
211 encoder.outer.export(&name, ComponentTypeRef::Instance(idx));
212 } else {
213 encoder.push_instance();
214 for (_, id) in iface.types.iter() {
215 encoder.encode_valtype(self.resolve, &Type::Id(*id))?;
216 }
217 let instance = encoder.pop_instance();
218 let idx = encoder.outer.type_count();
219 encoder.outer.ty().instance(&instance);
220 encoder.import_map.insert(interface, encoder.instances);
221 encoder.instances += 1;
222 encoder.outer.import(&name, ComponentTypeRef::Instance(idx));
223 }
224 }
225
226 encoder.interface = None;
227
228 Ok(encoder.outer)
229 }
230
231 fn add_live_interfaces(&self, interfaces: &mut IndexSet<InterfaceId>, id: InterfaceId) {
234 if interfaces.contains(&id) {
235 return;
236 }
237 for id in self.resolve.interface_direct_deps(id) {
238 self.add_live_interfaces(interfaces, id);
239 }
240 assert!(interfaces.insert(id));
241 }
242}
243
244struct InterfaceEncoder<'a> {
245 resolve: &'a Resolve,
246 outer: ComponentType,
247 ty: Option<InstanceType>,
248 func_type_map: HashMap<FunctionKey<'a>, u32>,
249 type_map: HashMap<TypeId, u32>,
250 saved_types: Option<(HashMap<TypeId, u32>, HashMap<FunctionKey<'a>, u32>)>,
251 import_map: HashMap<InterfaceId, u32>,
252 outer_type_map: HashMap<TypeId, u32>,
253 instances: u32,
254 import_types: bool,
255 interface: Option<InterfaceId>,
256}
257
258impl InterfaceEncoder<'_> {
259 fn new(resolve: &Resolve) -> InterfaceEncoder<'_> {
260 InterfaceEncoder {
261 resolve,
262 outer: ComponentType::new(),
263 ty: None,
264 type_map: Default::default(),
265 func_type_map: Default::default(),
266 import_map: Default::default(),
267 outer_type_map: Default::default(),
268 instances: 0,
269 saved_types: None,
270 import_types: false,
271 interface: None,
272 }
273 }
274
275 fn encode_instance(&mut self, interface: InterfaceId) -> Result<u32> {
276 self.push_instance();
277 let iface = &self.resolve.interfaces[interface];
278 let mut type_order = IndexSet::new();
279 for (_, id) in iface.types.iter() {
280 self.encode_valtype(self.resolve, &Type::Id(*id))?;
281 type_order.insert(*id);
282 }
283
284 let mut funcs = iface.functions.iter().collect::<Vec<_>>();
300 funcs.sort_by_key(|(_name, func)| match func.kind {
301 FunctionKind::Freestanding => type_order.len(),
302 FunctionKind::Method(id) | FunctionKind::Constructor(id) | FunctionKind::Static(id) => {
303 type_order.get_index_of(&id).unwrap()
304 }
305 });
306
307 for (name, func) in funcs {
308 let ty = self.encode_func_type(self.resolve, func)?;
309 self.ty
310 .as_mut()
311 .unwrap()
312 .export(name, ComponentTypeRef::Func(ty));
313 }
314 let instance = self.pop_instance();
315 let idx = self.outer.type_count();
316 self.outer.ty().instance(&instance);
317 self.import_map.insert(interface, self.instances);
318 self.instances += 1;
319 Ok(idx)
320 }
321
322 fn push_instance(&mut self) {
323 assert!(self.ty.is_none());
324 assert!(self.saved_types.is_none());
325 self.saved_types = Some((
326 mem::take(&mut self.type_map),
327 mem::take(&mut self.func_type_map),
328 ));
329 self.ty = Some(InstanceType::default());
330 }
331
332 fn pop_instance(&mut self) -> InstanceType {
333 let (types, funcs) = self.saved_types.take().unwrap();
334 self.type_map = types;
335 self.func_type_map = funcs;
336 mem::take(&mut self.ty).unwrap()
337 }
338}
339
340impl<'a> ValtypeEncoder<'a> for InterfaceEncoder<'a> {
341 fn defined_type(&mut self) -> (u32, ComponentDefinedTypeEncoder<'_>) {
342 match &mut self.ty {
343 Some(ty) => (ty.type_count(), ty.ty().defined_type()),
344 None => (self.outer.type_count(), self.outer.ty().defined_type()),
345 }
346 }
347 fn define_function_type(&mut self) -> (u32, ComponentFuncTypeEncoder<'_>) {
348 match &mut self.ty {
349 Some(ty) => (ty.type_count(), ty.ty().function()),
350 None => (self.outer.type_count(), self.outer.ty().function()),
351 }
352 }
353 fn export_type(&mut self, index: u32, name: &'a str) -> Option<u32> {
354 match &mut self.ty {
355 Some(ty) => {
356 assert!(!self.import_types);
357 let ret = ty.type_count();
358 ty.export(name, ComponentTypeRef::Type(TypeBounds::Eq(index)));
359 Some(ret)
360 }
361 None => {
362 let ret = self.outer.type_count();
363 if self.import_types {
364 self.outer
365 .import(name, ComponentTypeRef::Type(TypeBounds::Eq(index)));
366 } else {
367 self.outer
368 .export(name, ComponentTypeRef::Type(TypeBounds::Eq(index)));
369 }
370 Some(ret)
371 }
372 }
373 }
374 fn export_resource(&mut self, name: &'a str) -> u32 {
375 let type_ref = ComponentTypeRef::Type(TypeBounds::SubResource);
376 match &mut self.ty {
377 Some(ty) => {
378 assert!(!self.import_types);
379 ty.export(name, type_ref);
380 ty.type_count() - 1
381 }
382 None => {
383 if self.import_types {
384 self.outer.import(name, type_ref);
385 } else {
386 self.outer.export(name, type_ref);
387 }
388 self.outer.type_count() - 1
389 }
390 }
391 }
392 fn type_map(&mut self) -> &mut HashMap<TypeId, u32> {
393 &mut self.type_map
394 }
395 fn interface(&self) -> Option<InterfaceId> {
396 self.interface
397 }
398 fn import_type(&mut self, owner: InterfaceId, id: TypeId) -> u32 {
399 let ty = &self.resolve.types[id];
400 let instance = self.import_map[&owner];
401 let outer_idx = *self.outer_type_map.entry(id).or_insert_with(|| {
402 let ret = self.outer.type_count();
403 self.outer.alias(Alias::InstanceExport {
404 instance,
405 name: ty.name.as_ref().unwrap(),
406 kind: ComponentExportKind::Type,
407 });
408 ret
409 });
410 match &mut self.ty {
411 Some(ty) => {
412 let ret = ty.type_count();
413 ty.alias(Alias::Outer {
414 count: 1,
415 index: outer_idx,
416 kind: ComponentOuterAliasKind::Type,
417 });
418 ret
419 }
420 None => outer_idx,
421 }
422 }
423 fn func_type_map(&mut self) -> &mut HashMap<FunctionKey<'a>, u32> {
424 &mut self.func_type_map
425 }
426}