use crate ::component::*;
use crate ::core;
use crate ::core::EncodeOptions;
use crate ::token::{Id, NameAnnotation};
use wasm_encoder::{
CanonicalFunctionSection, ComponentAliasSection, ComponentCoreTypeEncoder,
ComponentDefinedTypeEncoder, ComponentExportSection, ComponentImportSection,
ComponentInstanceSection, ComponentNameSection, ComponentSection, ComponentSectionId,
ComponentStartSection, ComponentTypeEncoder, ComponentTypeSection, CoreTypeSection,
InstanceSection, NameMap, NestedComponentSection, RawSection,
};
pub fn encode(component: &Component<'_>, options: &EncodeOptions) -> Vec<u8> {
match &component.kind {
ComponentKind::Text(fields) => {
encode_fields(&component.id, &component.name, fields, options).finish()
}
ComponentKind::Binary(bytes) => bytes.iter().flat_map(|b| b.iter().copied()).collect(),
}
}
fn encode_fields(
// TODO: use the id and name for a future names section
component_id: &Option<Id<'_>>,
component_name: &Option<NameAnnotation<'_>>,
fields: &[ComponentField<'_>],
options: &EncodeOptions,
) -> wasm_encoder::Component {
let mut e = Encoder::default();
for field in fields {
match field {
ComponentField::CoreModule(m) => e.encode_core_module(m, options),
ComponentField::CoreInstance(i) => e.encode_core_instance(i),
ComponentField::CoreType(t) => e.encode_core_type(t),
ComponentField::CoreRec(t) => e.encode_core_rec(t),
ComponentField::Component(c) => e.encode_component(c, options),
ComponentField::Instance(i) => e.encode_instance(i),
ComponentField::Alias(a) => e.encode_alias(a),
ComponentField::Type (t) => e.encode_type(t),
ComponentField::CanonicalFunc(f) => e.encode_canonical_func(f),
ComponentField::CoreFunc(_) | ComponentField::Func(_) => {
unreachable!("should be expanded already" )
}
ComponentField::Start(s) => e.encode_start(s),
ComponentField::Import(i) => e.encode_import(i),
ComponentField::Export(ex) => e.encode_export(ex),
ComponentField::Custom(c) => e.encode_custom(c),
ComponentField::Producers(c) => e.encode_producers(c),
}
}
e.flush(None);
e.encode_names(component_id, component_name);
e.component
}
fn encode_core_type(encoder: ComponentCoreTypeEncoder, ty: &CoreTypeDef) {
match ty {
CoreTypeDef::Def(def) => {
encoder.core().subtype(&def.to_subtype());
}
CoreTypeDef::Module(t) => {
encoder.module(&t.into());
}
}
}
fn encode_type(encoder: ComponentTypeEncoder, ty: &TypeDef) {
match ty {
TypeDef::Defined(t) => {
encode_defined_type(encoder.defined_type(), t);
}
TypeDef::Func(f) => {
let mut encoder = encoder.function();
encoder.params(f.params.iter().map(|p| (p.name, &p.ty)));
if f.results.len() == 1 && f.results[0 ].name.is_none() {
encoder.result(&f.results[0 ].ty);
} else {
encoder.results(f.results.iter().map(|r| (r.name.unwrap_or("" ), &r.ty)));
}
}
TypeDef::Component(c) => {
encoder.component(&c.into());
}
TypeDef::Instance(i) => {
encoder.instance(&i.into());
}
TypeDef::Resource(i) => {
let dtor = i.dtor.as_ref().map(|i| i.idx.into());
encoder.resource(i.rep.into(), dtor);
}
}
}
fn encode_defined_type(encoder: ComponentDefinedTypeEncoder, ty: &ComponentDefinedType) {
match ty {
ComponentDefinedType::Primitive(p) => encoder.primitive((*p).into()),
ComponentDefinedType::Record(r) => {
encoder.record(r.fields.iter().map(|f| (f.name, &f.ty)));
}
ComponentDefinedType::Variant(v) => {
encoder.variant(v.cases.iter().map(|c| {
(
c.name,
c.ty.as_ref().map(Into::into),
c.refines.as_ref().map(Into::into),
)
}));
}
ComponentDefinedType::List(l) => {
encoder.list(l.element.as_ref());
}
ComponentDefinedType::Tuple(t) => {
encoder.tuple(t.fields.iter());
}
ComponentDefinedType::Flags(f) => {
encoder.flags(f.names.iter().copied());
}
ComponentDefinedType::Enum (e) => {
encoder.enum_type(e.names.iter().copied());
}
ComponentDefinedType::Option(o) => {
encoder.option(o.element.as_ref());
}
ComponentDefinedType::Result(e) => {
encoder.result(
e.ok.as_deref().map(Into::into),
e.err.as_deref().map(Into::into),
);
}
ComponentDefinedType::Own(i) => encoder.own((*i).into()),
ComponentDefinedType::Borrow(i) => encoder.borrow((*i).into()),
}
}
#[ derive(Default)]
struct Encoder<'a> {
component: wasm_encoder::Component,
current_section_id: Option<u8>,
// Core sections
// Note: module sections are written immediately
core_instances: InstanceSection,
core_types: CoreTypeSection,
// Component sections
// Note: custom, component, start sections are written immediately
instances: ComponentInstanceSection,
aliases: ComponentAliasSection,
types: ComponentTypeSection,
funcs: CanonicalFunctionSection,
imports: ComponentImportSection,
exports: ComponentExportSection,
core_func_names: Vec<Option<&'a str>>,
core_table_names: Vec<Option<&'a str>>,
core_memory_names: Vec<Option<&'a str>>,
core_global_names: Vec<Option<&'a str>>,
core_type_names: Vec<Option<&'a str>>,
core_module_names: Vec<Option<&'a str>>,
core_instance_names: Vec<Option<&'a str>>,
func_names: Vec<Option<&'a str>>,
value_names: Vec<Option<&'a str>>,
type_names: Vec<Option<&'a str>>,
component_names: Vec<Option<&'a str>>,
instance_names: Vec<Option<&'a str>>,
}
impl <'a> Encoder<' a> {
fn encode_custom(&mut self , custom: &Custom) {
// Flush any in-progress section before encoding the customs section
self .flush(None);
self .component.section(&custom.to_section());
}
fn encode_producers(&mut self , custom: &core::Producers) {
self .flush(None);
self .component.section(&custom.to_section());
}
fn encode_core_module(&mut self , module: &CoreModule<'a>, options: &EncodeOptions) {
// Flush any in-progress section before encoding the module
self .flush(None);
self .core_module_names
.push(get_name(&module.id, &module.name));
match &module.kind {
CoreModuleKind::Import { .. } => unreachable!("should be expanded already" ),
CoreModuleKind::Inline { fields } => {
// TODO: replace this with a wasm-encoder based encoding (should return `wasm_encoder::Module`)
let data = crate ::core::binary::encode(&module.id, &module.name, fields, options);
self .component.section(&RawSection {
id: ComponentSectionId::CoreModule.into(),
data: &data,
});
}
}
}
fn encode_core_instance(&mut self , instance: &CoreInstance<'a>) {
self .core_instance_names
.push(get_name(&instance.id, &instance.name));
match &instance.kind {
CoreInstanceKind::Instantiate { module, args } => {
self .core_instances.instantiate(
module.into(),
args.iter().map(|arg| (arg.name, (&arg.kind).into())),
);
}
CoreInstanceKind::BundleOfExports(exports) => {
self .core_instances.export_items(exports.iter().map(|e| {
let (kind, index) = (&e.item).into();
(e.name, kind, index)
}));
}
}
self .flush(Some(self .core_instances.id()));
}
fn encode_core_type(&mut self , ty: &CoreType<'a>) {
self .core_type_names.push(get_name(&ty.id, &ty.name));
encode_core_type(self .core_types.ty(), &ty.def);
self .flush(Some(self .core_types.id()));
}
fn encode_core_rec(&mut self , ty: &core::Rec<'a>) {
for ty in ty.types.iter() {
self .core_type_names.push(get_name(&ty.id, &ty.name));
}
self .core_types
.ty()
.core()
.rec(ty.types.iter().map(|t| t.to_subtype()));
self .flush(Some(self .core_types.id()));
}
fn encode_component(&mut self , component: &NestedComponent<'a>, options: &EncodeOptions) {
self .component_names
.push(get_name(&component.id, &component.name));
// Flush any in-progress section before encoding the component
self .flush(None);
match &component.kind {
NestedComponentKind::Import { .. } => unreachable!("should be expanded already" ),
NestedComponentKind::Inline(fields) => {
self .component
.section(&NestedComponentSection(&encode_fields(
&component.id,
&component.name,
fields,
options,
)));
}
}
}
fn encode_instance(&mut self , instance: &Instance<'a>) {
self .instance_names
.push(get_name(&instance.id, &instance.name));
match &instance.kind {
InstanceKind::Import { .. } => unreachable!("should be expanded already" ),
InstanceKind::Instantiate { component, args } => {
self .instances.instantiate(
component.into(),
args.iter().map(|arg| {
let (kind, index) = (&arg.kind).into();
(arg.name, kind, index)
}),
);
}
InstanceKind::BundleOfExports(exports) => {
self .instances.export_items(exports.iter().map(|e| {
let (kind, index) = (&e.kind).into();
(e.name.0 , kind, index)
}));
}
}
self .flush(Some(self .instances.id()));
}
fn encode_alias(&mut self , alias: &Alias<'a>) {
let name = get_name(&alias.id, &alias.name);
self .aliases.alias((&alias.target).into());
match &alias.target {
AliasTarget::Export { kind, .. } => {
self .names_for_component_export_alias(*kind).push(name);
}
AliasTarget::CoreExport { kind, .. } => {
self .names_for_core_export_alias(*kind).push(name);
}
AliasTarget::Outer { kind, .. } => {
self .names_for_component_outer_alias(*kind).push(name);
}
}
self .flush(Some(self .aliases.id()));
}
fn encode_start(&mut self , start: &Start) {
// Flush any in-progress section before encoding the start section
self .flush(None);
self .component.section(&ComponentStartSection {
function_index: start.func.into(),
args: start.args.iter().map(|a| a.idx.into()).collect::<Vec<_>>(),
results: start.results.len() as u32,
});
}
fn encode_type(&mut self , ty: &Type <'a>) {
self .type_names.push(get_name(&ty.id, &ty.name));
encode_type(self .types.ty(), &ty.def);
self .flush(Some(self .types.id()));
}
fn encode_canonical_func(&mut self , func: &CanonicalFunc<'a>) {
let name = get_name(&func.id, &func.name);
match &func.kind {
CanonicalFuncKind::Lift { ty, info } => {
self .func_names.push(name);
self .funcs.lift(
info.func.idx.into(),
ty.into(),
info.opts.iter().map(Into::into),
);
}
CanonicalFuncKind::Lower(info) => {
self .core_func_names.push(name);
self .funcs
.lower(info.func.idx.into(), info.opts.iter().map(Into::into));
}
CanonicalFuncKind::ResourceNew(info) => {
self .core_func_names.push(name);
self .funcs.resource_new(info.ty.into());
}
CanonicalFuncKind::ResourceDrop(info) => {
self .core_func_names.push(name);
self .funcs.resource_drop(info.ty.into());
}
CanonicalFuncKind::ResourceRep(info) => {
self .core_func_names.push(name);
self .funcs.resource_rep(info.ty.into());
}
CanonicalFuncKind::ThreadSpawn(info) => {
self .core_func_names.push(name);
self .funcs.thread_spawn(info.ty.into());
}
CanonicalFuncKind::ThreadHwConcurrency(_info) => {
self .core_func_names.push(name);
self .funcs.thread_hw_concurrency();
}
}
self .flush(Some(self .funcs.id()));
}
fn encode_import(&mut self , import: &ComponentImport<'a>) {
let name = get_name(&import.item.id, &import.item.name);
self .names_for_item_kind(&import.item.kind).push(name);
self .imports
.import(import.name.0 , (&import.item.kind).into());
self .flush(Some(self .imports.id()));
}
fn encode_export(&mut self , export: &ComponentExport<'a>) {
let name = get_name(&export.id, &export.debug_name);
let (kind, index) = (&export.kind).into();
self .exports.export(
export.name.0 ,
kind,
index,
export.ty.as_ref().map(|ty| (&ty.0 .kind).into()),
);
match &export.kind {
ComponentExportKind::CoreModule(_) => self .core_module_names.push(name),
ComponentExportKind::Func(_) => self .func_names.push(name),
ComponentExportKind::Instance(_) => self .instance_names.push(name),
ComponentExportKind::Value(_) => self .value_names.push(name),
ComponentExportKind::Component(_) => self .component_names.push(name),
ComponentExportKind::Type (_) => self .type_names.push(name),
}
self .flush(Some(self .exports.id()));
}
fn flush(&mut self , section_id: Option<u8>) {
if self .current_section_id == section_id {
return ;
}
if let Some(id) = self .current_section_id {
match id {
// 0 => custom sections are written immediately
// 1 => core modules sections are written immediately
2 => {
assert_eq!(id, self .core_instances.id());
self .component.section(&self .core_instances);
self .core_instances = Default::default();
}
3 => {
assert_eq!(id, self .core_types.id());
self .component.section(&self .core_types);
self .core_types = Default::default();
}
// 4 => components sections are written immediately
5 => {
assert_eq!(id, self .instances.id());
self .component.section(&self .instances);
self .instances = Default::default();
}
6 => {
assert_eq!(id, self .aliases.id());
self .component.section(&self .aliases);
self .aliases = Default::default();
}
7 => {
assert_eq!(id, self .types.id());
self .component.section(&self .types);
self .types = Default::default();
}
8 => {
assert_eq!(id, self .funcs.id());
self .component.section(&self .funcs);
self .funcs = Default::default();
}
// 9 => start sections are written immediately
10 => {
assert_eq!(id, self .imports.id());
self .component.section(&self .imports);
self .imports = Default::default();
}
11 => {
assert_eq!(id, self .exports.id());
self .component.section(&self .exports);
self .exports = Default::default();
}
_ => unreachable!("unknown incremental component section id: {}" , id),
}
}
self .current_section_id = section_id
}
fn encode_names(
&mut self ,
component_id: &Option<Id<'_>>,
component_name: &Option<NameAnnotation<'_>>,
) {
let mut names = ComponentNameSection::new();
if let Some(name) = get_name(component_id, component_name) {
names.component(name);
}
let mut funcs = |list: &[Option<&str>], append: fn (&mut ComponentNameSection, &NameMap)| {
let mut map = NameMap::new();
for (i, entry) in list.iter().enumerate() {
if let Some(name) = entry {
map.append(i as u32, name);
}
}
if !map.is_empty() {
append(&mut names, &map);
}
};
funcs(&self .core_func_names, ComponentNameSection::core_funcs);
funcs(&self .core_table_names, ComponentNameSection::core_tables);
funcs(&self .core_memory_names, ComponentNameSection::core_memories);
funcs(&self .core_global_names, ComponentNameSection::core_globals);
funcs(&self .core_type_names, ComponentNameSection::core_types);
funcs(&self .core_module_names, ComponentNameSection::core_modules);
funcs(
&self .core_instance_names,
ComponentNameSection::core_instances,
);
funcs(&self .func_names, ComponentNameSection::funcs);
funcs(&self .value_names, ComponentNameSection::values);
funcs(&self .type_names, ComponentNameSection::types);
funcs(&self .component_names, ComponentNameSection::components);
funcs(&self .instance_names, ComponentNameSection::instances);
if !names.is_empty() {
self .component.section(&names);
}
}
fn names_for_component_export_alias(
&mut self ,
kind: ComponentExportAliasKind,
) -> &mut Vec<Option<&'a str>> {
match kind {
ComponentExportAliasKind::Func => &mut self .func_names,
ComponentExportAliasKind::CoreModule => &mut self .core_module_names,
ComponentExportAliasKind::Value => &mut self .value_names,
ComponentExportAliasKind::Type => &mut self .type_names,
ComponentExportAliasKind::Component => &mut self .component_names,
ComponentExportAliasKind::Instance => &mut self .instance_names,
}
}
fn names_for_component_outer_alias(
&mut self ,
kind: ComponentOuterAliasKind,
) -> &mut Vec<Option<&'a str>> {
match kind {
ComponentOuterAliasKind::CoreModule => &mut self .core_module_names,
ComponentOuterAliasKind::CoreType => &mut self .core_type_names,
ComponentOuterAliasKind::Component => &mut self .component_names,
ComponentOuterAliasKind::Type => &mut self .type_names,
}
}
fn names_for_core_export_alias(&mut self , kind: core::ExportKind) -> &mut Vec<Option<&'a str>> {
match kind {
core::ExportKind::Func => &mut self .core_func_names,
core::ExportKind::Global => &mut self .core_global_names,
core::ExportKind::Table => &mut self .core_table_names,
core::ExportKind::Memory => &mut self .core_memory_names,
core::ExportKind::Tag => unimplemented!(),
}
}
fn names_for_item_kind(&mut self , kind: &ItemSigKind) -> &mut Vec<Option<&'a str>> {
match kind {
ItemSigKind::CoreModule(_) => &mut self .core_module_names,
ItemSigKind::Func(_) => &mut self .func_names,
ItemSigKind::Component(_) => &mut self .component_names,
ItemSigKind::Instance(_) => &mut self .instance_names,
ItemSigKind::Value(_) => &mut self .value_names,
ItemSigKind::Type (_) => &mut self .type_names,
}
}
}
fn get_name<'a>(id: &Option<Id<' a>>, name: &Option<NameAnnotation<'a>>) -> Option<&' a str> {
name.as_ref().map(|n| n.name).or_else(|| {
id.and_then(|id| {
if id.is_gensym() {
None
} else {
Some(id.name())
}
})
})
}
impl Custom<'_> {
fn to_section(&self ) -> wasm_encoder::CustomSection<'_> {
let mut ret = Vec::new();
for list in self .data.iter() {
ret.extend_from_slice(list);
}
wasm_encoder::CustomSection {
name: self .name.into(),
data: ret.into(),
}
}
}
impl From<&CoreInstantiationArgKind<'_>> for wasm_encoder::ModuleArg {
fn from(kind: &CoreInstantiationArgKind) -> Self {
match kind {
CoreInstantiationArgKind::Instance(i) => {
wasm_encoder::ModuleArg::Instance(i.idx.into())
}
CoreInstantiationArgKind::BundleOfExports(..) => {
unreachable!("should be expanded already" )
}
}
}
}
impl From<&CoreItemRef<'_, core::ExportKind>> for (wasm_encoder::ExportKind, u32) {
fn from(item: &CoreItemRef<'_, core::ExportKind>) -> Self {
match &item.kind {
core::ExportKind::Func => (wasm_encoder::ExportKind::Func, item.idx.into()),
core::ExportKind::Table => (wasm_encoder::ExportKind::Table, item.idx.into()),
core::ExportKind::Memory => (wasm_encoder::ExportKind::Memory, item.idx.into()),
core::ExportKind::Global => (wasm_encoder::ExportKind::Global, item.idx.into()),
core::ExportKind::Tag => (wasm_encoder::ExportKind::Tag, item.idx.into()),
}
}
}
impl <T> From<&ItemRef<'_, T>> for u32 {
fn from(i: &ItemRef<'_, T>) -> Self {
assert!(i.export_names.is_empty());
i.idx.into()
}
}
impl <T> From<&CoreTypeUse<'_, T>> for u32 {
fn from(u: &CoreTypeUse<'_, T>) -> Self {
match u {
CoreTypeUse::Inline(_) => unreachable!("should be expanded already" ),
CoreTypeUse::Ref (r) => r.idx.into(),
}
}
}
impl <T> From<&ComponentTypeUse<'_, T>> for u32 {
fn from(u: &ComponentTypeUse<'_, T>) -> Self {
match u {
ComponentTypeUse::Inline(_) => unreachable!("should be expanded already" ),
ComponentTypeUse::Ref (r) => r.idx.into(),
}
}
}
impl From<&ComponentValType<'_>> for wasm_encoder::ComponentValType {
fn from(r: &ComponentValType) -> Self {
match r {
ComponentValType::Inline(ComponentDefinedType::Primitive(p)) => {
Self ::Primitive((*p).into())
}
ComponentValType::Ref (i) => Self ::Type (u32::from(*i)),
ComponentValType::Inline(_) => unreachable!("should be expanded by now" ),
}
}
}
impl From<PrimitiveValType> for wasm_encoder::PrimitiveValType {
fn from(p: PrimitiveValType) -> Self {
match p {
PrimitiveValType::Bool => Self ::Bool,
PrimitiveValType::S8 => Self ::S8,
PrimitiveValType::U8 => Self ::U8,
PrimitiveValType::S16 => Self ::S16,
PrimitiveValType::U16 => Self ::U16,
PrimitiveValType::S32 => Self ::S32,
PrimitiveValType::U32 => Self ::U32,
PrimitiveValType::S64 => Self ::S64,
PrimitiveValType::U64 => Self ::U64,
PrimitiveValType::F32 => Self ::F32,
PrimitiveValType::F64 => Self ::F64,
PrimitiveValType::Char => Self ::Char,
PrimitiveValType::String => Self ::String,
}
}
}
impl From<&Refinement<'_>> for u32 {
fn from(r: &Refinement) -> Self {
match r {
Refinement::Index(..) => unreachable!("should be resolved by now" ),
Refinement::Resolved(i) => *i,
}
}
}
impl From<&ItemSigKind<'_>> for wasm_encoder::ComponentTypeRef {
fn from(k: &ItemSigKind) -> Self {
match k {
ItemSigKind::Component(c) => Self ::Component(c.into()),
ItemSigKind::CoreModule(m) => Self ::Module(m.into()),
ItemSigKind::Instance(i) => Self ::Instance(i.into()),
ItemSigKind::Value(v) => Self ::Value((&v.0 ).into()),
ItemSigKind::Func(f) => Self ::Func(f.into()),
ItemSigKind::Type (TypeBounds::Eq(t)) => {
Self ::Type (wasm_encoder::TypeBounds::Eq((*t).into()))
}
ItemSigKind::Type (TypeBounds::SubResource) => {
Self ::Type (wasm_encoder::TypeBounds::SubResource)
}
}
}
}
impl From<&ComponentType<'_>> for wasm_encoder::ComponentType {
fn from(ty: &ComponentType) -> Self {
let mut encoded = wasm_encoder::ComponentType::new();
for decl in &ty.decls {
match decl {
ComponentTypeDecl::CoreType(t) => {
encode_core_type(encoded.core_type(), &t.def);
}
ComponentTypeDecl::Type (t) => {
encode_type(encoded.ty(), &t.def);
}
ComponentTypeDecl::Alias(a) => {
encoded.alias((&a.target).into());
}
ComponentTypeDecl::Import(i) => {
encoded.import(i.name.0 , (&i.item.kind).into());
}
ComponentTypeDecl::Export(e) => {
encoded.export(e.name.0 , (&e.item.kind).into());
}
}
}
encoded
}
}
impl From<&InstanceType<'_>> for wasm_encoder::InstanceType {
fn from(ty: &InstanceType) -> Self {
let mut encoded = wasm_encoder::InstanceType::new();
for decl in &ty.decls {
match decl {
InstanceTypeDecl::CoreType(t) => {
encode_core_type(encoded.core_type(), &t.def);
}
InstanceTypeDecl::Type (t) => {
encode_type(encoded.ty(), &t.def);
}
InstanceTypeDecl::Alias(a) => {
encoded.alias((&a.target).into());
}
InstanceTypeDecl::Export(e) => {
encoded.export(e.name.0 , (&e.item.kind).into());
}
}
}
encoded
}
}
impl From<&ModuleType<'_>> for wasm_encoder::ModuleType {
fn from(ty: &ModuleType) -> Self {
let mut encoded = wasm_encoder::ModuleType::new();
for decl in &ty.decls {
match decl {
ModuleTypeDecl::Type (t) => {
encoded.ty().subtype(&t.to_subtype());
}
ModuleTypeDecl::Rec(rec) => {
encoded.ty().rec(rec.types.iter().map(|t| t.to_subtype()));
}
ModuleTypeDecl::Alias(a) => match &a.target {
AliasTarget::Outer {
outer,
index,
kind: ComponentOuterAliasKind::CoreType,
} => {
encoded.alias_outer_core_type(u32::from(*outer), u32::from(*index));
}
_ => unreachable!("only outer type aliases are supported" ),
},
ModuleTypeDecl::Import(i) => {
encoded.import(i.module, i.field, i.item.to_entity_type());
}
ModuleTypeDecl::Export(name, item) => {
encoded.export(name, item.to_entity_type());
}
}
}
encoded
}
}
impl From<&InstantiationArgKind<'_>> for (wasm_encoder::ComponentExportKind, u32) {
fn from(kind: &InstantiationArgKind) -> Self {
match kind {
InstantiationArgKind::Item(i) => i.into(),
InstantiationArgKind::BundleOfExports(..) => unreachable!("should be expanded already" ),
}
}
}
impl From<&ComponentExportKind<'_>> for (wasm_encoder::ComponentExportKind, u32) {
fn from(kind: &ComponentExportKind) -> Self {
match kind {
ComponentExportKind::CoreModule(m) => {
(wasm_encoder::ComponentExportKind::Module, m.idx.into())
}
ComponentExportKind::Func(f) => (wasm_encoder::ComponentExportKind::Func, f.idx.into()),
ComponentExportKind::Value(v) => {
(wasm_encoder::ComponentExportKind::Value, v.idx.into())
}
ComponentExportKind::Type (t) => (wasm_encoder::ComponentExportKind::Type , t.idx.into()),
ComponentExportKind::Component(c) => {
(wasm_encoder::ComponentExportKind::Component, c.idx.into())
}
ComponentExportKind::Instance(i) => {
(wasm_encoder::ComponentExportKind::Instance, i.idx.into())
}
}
}
}
impl From<ComponentOuterAliasKind> for wasm_encoder::ComponentOuterAliasKind {
fn from(kind: ComponentOuterAliasKind) -> Self {
match kind {
ComponentOuterAliasKind::CoreModule => Self ::CoreModule,
ComponentOuterAliasKind::CoreType => Self ::CoreType,
ComponentOuterAliasKind::Type => Self ::Type ,
ComponentOuterAliasKind::Component => Self ::Component,
}
}
}
impl From<ComponentExportAliasKind> for wasm_encoder::ComponentExportKind {
fn from(kind: ComponentExportAliasKind) -> Self {
match kind {
ComponentExportAliasKind::CoreModule => Self ::Module,
ComponentExportAliasKind::Func => Self ::Func,
ComponentExportAliasKind::Value => Self ::Value,
ComponentExportAliasKind::Type => Self ::Type ,
ComponentExportAliasKind::Component => Self ::Component,
ComponentExportAliasKind::Instance => Self ::Instance,
}
}
}
impl From<&CanonOpt<'_>> for wasm_encoder::CanonicalOption {
fn from(opt: &CanonOpt) -> Self {
match opt {
CanonOpt::StringUtf8 => Self ::UTF8,
CanonOpt::StringUtf16 => Self ::UTF16,
CanonOpt::StringLatin1Utf16 => Self ::CompactUTF16,
CanonOpt::Memory(m) => Self ::Memory(m.idx.into()),
CanonOpt::Realloc(f) => Self ::Realloc(f.idx.into()),
CanonOpt::PostReturn(f) => Self ::PostReturn(f.idx.into()),
}
}
}
impl <'a> From<&AliasTarget<' a>> for wasm_encoder::Alias<'a> {
fn from(target: &AliasTarget<'a>) -> Self {
match target {
AliasTarget::Export {
instance,
name,
kind,
} => wasm_encoder::Alias::InstanceExport {
instance: (*instance).into(),
kind: (*kind).into(),
name,
},
AliasTarget::CoreExport {
instance,
name,
kind,
} => wasm_encoder::Alias::CoreInstanceExport {
instance: (*instance).into(),
kind: (*kind).into(),
name,
},
AliasTarget::Outer { outer, index, kind } => wasm_encoder::Alias::Outer {
count: (*outer).into(),
kind: (*kind).into(),
index: (*index).into(),
},
}
}
}
Messung V0.5 in Prozent C=94 H=99 G=96
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-06-18)
¤
*© Formatika GbR, Deutschland