1use crate::encoding::types::{TypeEncodingMaps, 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 (key, import) in world.imports.iter() {
76 log::trace!("encoding import {}", resolve.name_world_key(key));
77 let ty = match import {
78 WorldItem::Interface { id, .. } => {
79 component.interface = Some(*id);
80 let idx = component.encode_instance(*id)?;
81 ComponentTypeRef::Instance(idx)
82 }
83 WorldItem::Function(f) => {
84 component.interface = None;
85 let idx = component.encode_func_type(resolve, f)?;
86 ComponentTypeRef::Func(idx)
87 }
88 WorldItem::Type { id, .. } => {
89 component.interface = None;
90 component.import_types = true;
91 component.encode_valtype(resolve, &Type::Id(*id))?;
92 component.import_types = false;
93 continue;
94 }
95 };
96 component
97 .outer
98 .import(component_extern_name(resolve, key, import), ty);
99 }
100 for (key, export) in world.exports.iter() {
102 log::trace!("encoding export {}", resolve.name_world_key(key));
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
117 .outer
118 .export(component_extern_name(resolve, key, export), ty);
119 }
120
121 Ok(component.outer)
122}
123
124fn component_extern_name(
125 resolve: &Resolve,
126 key: &WorldKey,
127 item: &WorldItem,
128) -> wasm_encoder::ComponentExternName<'static> {
129 ComponentExternName {
130 name: resolve.name_world_key(key).into(),
131 implements: resolve.implements_value(key, item).map(|s| s.into()),
132 }
133}
134
135struct Encoder<'a> {
136 component: ComponentBuilder,
137 resolve: &'a Resolve,
138 package: PackageId,
139}
140
141impl Encoder<'_> {
142 fn run(&mut self) -> Result<()> {
143 for (name, &id) in self.resolve.packages[self.package].interfaces.iter() {
145 let component_ty = self.encode_interface(id)?;
146 let ty = self.component.type_component(Some(name), &component_ty);
147 self.component
148 .export(name, ComponentExportKind::Type, ty, None);
149 }
150
151 for (name, &world) in self.resolve.packages[self.package].worlds.iter() {
154 let component_ty = encode_world(self.resolve, world)?;
155
156 let world = &self.resolve.worlds[world];
157 let mut wrapper = ComponentType::new();
158 wrapper.ty().component(&component_ty);
159 let pkg = &self.resolve.packages[world.package.unwrap()];
160 wrapper.export(pkg.name.interface_id(name), ComponentTypeRef::Component(0));
161
162 let ty = self.component.type_component(Some(name), &wrapper);
163 self.component
164 .export(name, ComponentExportKind::Type, ty, None);
165 }
166
167 Ok(())
168 }
169
170 fn encode_interface(&mut self, id: InterfaceId) -> Result<ComponentType> {
171 let mut interfaces = IndexSet::new();
180 self.add_live_interfaces(&mut interfaces, id);
181
182 let mut used_names = IndexSet::new();
186 for id in interfaces.iter() {
187 let iface = &self.resolve.interfaces[*id];
188 if iface.package == Some(self.package) {
189 let first = used_names.insert(iface.name.as_ref().unwrap().clone());
190 assert!(first);
191 }
192 }
193
194 let mut encoder = InterfaceEncoder::new(self.resolve);
195 for interface in interfaces {
196 encoder.interface = Some(interface);
197 let iface = &self.resolve.interfaces[interface];
198 let name = self.resolve.id_of(interface).unwrap();
199 if interface == id {
200 let idx = encoder.encode_instance(interface)?;
201 log::trace!("exporting self as {idx}");
202 encoder.outer.export(name, ComponentTypeRef::Instance(idx));
203 } else {
204 encoder.push_instance();
205 for (_, id) in iface.types.iter() {
206 encoder.encode_valtype(self.resolve, &Type::Id(*id))?;
207 }
208 let instance = encoder.pop_instance();
209 let idx = encoder.outer.type_count();
210 encoder.outer.ty().instance(&instance);
211 encoder.import_map.insert(interface, encoder.instances);
212 encoder.instances += 1;
213 encoder.outer.import(name, ComponentTypeRef::Instance(idx));
214 }
215 }
216
217 encoder.interface = None;
218
219 Ok(encoder.outer)
220 }
221
222 fn add_live_interfaces(&self, interfaces: &mut IndexSet<InterfaceId>, id: InterfaceId) {
225 if interfaces.contains(&id) {
226 return;
227 }
228 for id in self.resolve.interface_direct_deps(id) {
229 self.add_live_interfaces(interfaces, id);
230 }
231 assert!(interfaces.insert(id));
232 }
233}
234
235struct InterfaceEncoder<'a> {
236 resolve: &'a Resolve,
237 outer: ComponentType,
238 ty: Option<InstanceType>,
239 type_encoding_maps: TypeEncodingMaps<'a>,
240 saved_maps: Option<TypeEncodingMaps<'a>>,
241 import_map: HashMap<InterfaceId, u32>,
242 outer_type_map: HashMap<TypeId, u32>,
243 instances: u32,
244 import_types: bool,
245 interface: Option<InterfaceId>,
246}
247
248impl InterfaceEncoder<'_> {
249 fn new(resolve: &Resolve) -> InterfaceEncoder<'_> {
250 InterfaceEncoder {
251 resolve,
252 outer: ComponentType::new(),
253 ty: None,
254 type_encoding_maps: Default::default(),
255 import_map: Default::default(),
256 outer_type_map: Default::default(),
257 instances: 0,
258 saved_maps: None,
259 import_types: false,
260 interface: None,
261 }
262 }
263
264 fn encode_instance(&mut self, interface: InterfaceId) -> Result<u32> {
265 self.push_instance();
266 let iface = &self.resolve.interfaces[interface];
267 let mut type_order = IndexSet::new();
268 for (_, id) in iface.types.iter() {
269 self.encode_valtype(self.resolve, &Type::Id(*id))?;
270 type_order.insert(*id);
271 }
272
273 let mut funcs = iface.functions.iter().collect::<Vec<_>>();
289 funcs.sort_by_key(|(_name, func)| match func.kind.resource() {
290 Some(id) => type_order.get_index_of(&id).unwrap(),
291 None => type_order.len(),
292 });
293
294 for (name, func) in funcs {
295 let ty = self.encode_func_type(self.resolve, func)?;
296 self.ty
297 .as_mut()
298 .unwrap()
299 .export(name, ComponentTypeRef::Func(ty));
300 }
301 let instance = self.pop_instance();
302 let idx = self.outer.type_count();
303 self.outer.ty().instance(&instance);
304 self.import_map.insert(interface, self.instances);
305 self.instances += 1;
306 Ok(idx)
307 }
308
309 fn push_instance(&mut self) {
310 assert!(self.ty.is_none());
311 assert!(self.saved_maps.is_none());
312 self.saved_maps = Some(mem::take(&mut self.type_encoding_maps));
313 self.ty = Some(InstanceType::default());
314 }
315
316 fn pop_instance(&mut self) -> InstanceType {
317 let maps = self.saved_maps.take().unwrap();
318 self.type_encoding_maps = maps;
319 mem::take(&mut self.ty).unwrap()
320 }
321}
322
323impl<'a> ValtypeEncoder<'a> for InterfaceEncoder<'a> {
324 fn defined_type(&mut self) -> (u32, ComponentDefinedTypeEncoder<'_>) {
325 match &mut self.ty {
326 Some(ty) => (ty.type_count(), ty.ty().defined_type()),
327 None => (self.outer.type_count(), self.outer.ty().defined_type()),
328 }
329 }
330 fn define_function_type(&mut self) -> (u32, ComponentFuncTypeEncoder<'_>) {
331 match &mut self.ty {
332 Some(ty) => (ty.type_count(), ty.ty().function()),
333 None => (self.outer.type_count(), self.outer.ty().function()),
334 }
335 }
336 fn export_type(&mut self, index: u32, name: &'a str) -> Option<u32> {
337 match &mut self.ty {
338 Some(ty) => {
339 assert!(!self.import_types);
340 let ret = ty.type_count();
341 ty.export(name, ComponentTypeRef::Type(TypeBounds::Eq(index)));
342 Some(ret)
343 }
344 None => {
345 let ret = self.outer.type_count();
346 if self.import_types {
347 self.outer
348 .import(name, ComponentTypeRef::Type(TypeBounds::Eq(index)));
349 } else {
350 self.outer
351 .export(name, ComponentTypeRef::Type(TypeBounds::Eq(index)));
352 }
353 Some(ret)
354 }
355 }
356 }
357 fn export_resource(&mut self, name: &'a str) -> u32 {
358 let type_ref = ComponentTypeRef::Type(TypeBounds::SubResource);
359 match &mut self.ty {
360 Some(ty) => {
361 assert!(!self.import_types);
362 ty.export(name, type_ref);
363 ty.type_count() - 1
364 }
365 None => {
366 if self.import_types {
367 self.outer.import(name, type_ref);
368 } else {
369 self.outer.export(name, type_ref);
370 }
371 self.outer.type_count() - 1
372 }
373 }
374 }
375 fn type_encoding_maps(&mut self) -> &mut TypeEncodingMaps<'a> {
376 &mut self.type_encoding_maps
377 }
378 fn interface(&self) -> Option<InterfaceId> {
379 self.interface
380 }
381 fn import_type(&mut self, owner: InterfaceId, id: TypeId) -> u32 {
382 let ty = &self.resolve.types[id];
383 let instance = self.import_map[&owner];
384 let outer_idx = *self.outer_type_map.entry(id).or_insert_with(|| {
385 let ret = self.outer.type_count();
386 self.outer.alias(Alias::InstanceExport {
387 instance,
388 name: ty.name.as_ref().unwrap(),
389 kind: ComponentExportKind::Type,
390 });
391 ret
392 });
393 match &mut self.ty {
394 Some(ty) => {
395 let ret = ty.type_count();
396 ty.alias(Alias::Outer {
397 count: 1,
398 index: outer_idx,
399 kind: ComponentOuterAliasKind::Type,
400 });
401 ret
402 }
403 None => outer_idx,
404 }
405 }
406}