Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor interface type representation in wast #607

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 0 additions & 2 deletions crates/wasmprinter/src/lib.rs
Expand Up @@ -2370,9 +2370,7 @@ impl Printer {
match ty {
InterfaceTypeRef::Primitive(ty) => self.print_primitive_type(ty),
InterfaceTypeRef::Type(idx) => {
self.result.push_str("(type ");
self.print_idx(&state.type_names, *idx)?;
self.result.push(')');
}
}

Expand Down
46 changes: 32 additions & 14 deletions crates/wast/src/component/binary.rs
Expand Up @@ -376,23 +376,31 @@ impl Encode for TypeField<'_> {
}
}

impl Encode for Primitive {
fn encode(&self, e: &mut Vec<u8>) {
match self {
Primitive::Unit => e.push(0x7f),
Primitive::Bool => e.push(0x7e),
Primitive::S8 => e.push(0x7d),
Primitive::U8 => e.push(0x7c),
Primitive::S16 => e.push(0x7b),
Primitive::U16 => e.push(0x7a),
Primitive::S32 => e.push(0x79),
Primitive::U32 => e.push(0x78),
Primitive::S64 => e.push(0x77),
Primitive::U64 => e.push(0x76),
Primitive::Float32 => e.push(0x75),
Primitive::Float64 => e.push(0x74),
Primitive::Char => e.push(0x73),
Primitive::String => e.push(0x72),
}
}
}

impl<'a> Encode for InterType<'a> {
fn encode(&self, e: &mut Vec<u8>) {
match self {
InterType::Unit => e.push(0x7f),
InterType::Bool => e.push(0x7e),
InterType::S8 => e.push(0x7d),
InterType::U8 => e.push(0x7c),
InterType::S16 => e.push(0x7b),
InterType::U16 => e.push(0x7a),
InterType::S32 => e.push(0x79),
InterType::U32 => e.push(0x78),
InterType::S64 => e.push(0x77),
InterType::U64 => e.push(0x76),
InterType::Float32 => e.push(0x75),
InterType::Float64 => e.push(0x74),
InterType::Char => e.push(0x73),
InterType::String => e.push(0x72),
InterType::Primitive(p) => p.encode(e),
InterType::Record(r) => r.encode(e),
InterType::Variant(v) => v.encode(e),
InterType::List(l) => l.encode(e),
Expand All @@ -406,6 +414,16 @@ impl<'a> Encode for InterType<'a> {
}
}

impl<'a> Encode for InterTypeRef<'a> {
fn encode(&self, e: &mut Vec<u8>) {
match self {
InterTypeRef::Primitive(p) => p.encode(e),
InterTypeRef::Ref(i) => i.encode(e),
InterTypeRef::Inline(_) => unreachable!("should be expanded by now"),
}
}
}

impl<'a> Encode for DefType<'a> {
fn encode(&self, e: &mut Vec<u8>) {
match self {
Expand Down
8 changes: 4 additions & 4 deletions crates/wast/src/component/deftype.rs
Expand Up @@ -101,7 +101,7 @@ pub struct ComponentFunctionType<'a> {
/// name resolution and a name for the custom `name` section.
pub params: Box<[ComponentFunctionParam<'a>]>,
/// The result type of a function.
pub result: ComponentTypeUse<'a, InterType<'a>>,
pub result: InterTypeRef<'a>,
}

impl<'a> Parse<'a> for ComponentFunctionType<'a> {
Expand All @@ -125,7 +125,7 @@ impl<'a> Parse<'a> for ComponentFunctionType<'a> {
})?
} else {
// If the result is omitted, use `unit`.
ComponentTypeUse::Inline(InterType::Unit)
InterTypeRef::Primitive(Primitive::Unit)
};
Ok(Self {
params: params.into(),
Expand All @@ -140,7 +140,7 @@ pub struct ComponentFunctionParam<'a> {
/// An optionally-specified name of this parameter
pub name: Option<&'a str>,
/// The type of the parameter.
pub type_: ComponentTypeUse<'a, InterType<'a>>,
pub type_: InterTypeRef<'a>,
}

/// A type for a nested module
Expand Down Expand Up @@ -306,7 +306,7 @@ impl<'a> From<TypeField<'a>> for InstanceTypeField<'a> {
#[derive(Debug, Clone)]
pub struct ValueType<'a> {
/// The type of the value.
pub value_type: ComponentTypeUse<'a, InterType<'a>>,
pub value_type: InterTypeRef<'a>,
}

impl<'a> Parse<'a> for ValueType<'a> {
Expand Down
69 changes: 41 additions & 28 deletions crates/wast/src/component/expand.rs
Expand Up @@ -247,9 +247,9 @@ impl<'a> Expander<'a> {

fn expand_func_ty(&mut self, ty: &mut ComponentFunctionType<'a>) {
for param in ty.params.iter_mut() {
self.expand_component_type_use(&mut param.type_);
self.expand_intertype_ref(&mut param.type_);
}
self.expand_component_type_use(&mut ty.result);
self.expand_intertype_ref(&mut ty.result);
}

fn expand_module_ty(&mut self, ty: &mut ModuleType<'a>) {
Expand Down Expand Up @@ -358,68 +358,81 @@ impl<'a> Expander<'a> {
}

fn expand_value_ty(&mut self, ty: &mut ValueType<'a>) {
self.expand_component_type_use(&mut ty.value_type);
self.expand_intertype_ref(&mut ty.value_type);
}

fn expand_intertype(&mut self, ty: &mut InterType<'a>) {
match ty {
InterType::Unit
| InterType::Bool
| InterType::S8
| InterType::U8
| InterType::S16
| InterType::U16
| InterType::S32
| InterType::U32
| InterType::S64
| InterType::U64
| InterType::Float32
| InterType::Float64
| InterType::Char
| InterType::String
| InterType::Flags(_)
| InterType::Enum(_) => {}
InterType::Primitive(_) | InterType::Flags(_) | InterType::Enum(_) => {}
InterType::Record(r) => {
for field in r.fields.iter_mut() {
self.expand_component_type_use(&mut field.type_);
self.expand_intertype_ref(&mut field.type_);
}
}
InterType::Variant(v) => {
for case in v.cases.iter_mut() {
self.expand_component_type_use(&mut case.type_);
self.expand_intertype_ref(&mut case.type_);
}
}
InterType::List(t) => {
self.expand_component_type_use(&mut t.element);
self.expand_intertype_ref(&mut t.element);
}
InterType::Tuple(t) => {
for field in t.fields.iter_mut() {
self.expand_component_type_use(field);
self.expand_intertype_ref(field);
}
}
InterType::Union(u) => {
for arm in u.arms.iter_mut() {
self.expand_component_type_use(arm);
self.expand_intertype_ref(arm);
}
}
InterType::Option(t) => {
self.expand_component_type_use(&mut t.element);
self.expand_intertype_ref(&mut t.element);
}
InterType::Expected(e) => {
self.expand_component_type_use(&mut e.ok);
self.expand_component_type_use(&mut e.err);
self.expand_intertype_ref(&mut e.ok);
self.expand_intertype_ref(&mut e.err);
}
}
}

fn expand_intertype_ref(&mut self, ty: &mut InterTypeRef<'a>) {
let inline = match ty {
InterTypeRef::Primitive(_) | InterTypeRef::Ref(_) => return,
InterTypeRef::Inline(inline) => {
mem::replace(inline, InterType::Primitive(Primitive::Unit))
}
};
// If this inline type has already been defined within this context
// then reuse the previously defined type to avoid injecting too many
// types into the type index space.
if let Some(idx) = inline.key().lookup(self) {
*ty = InterTypeRef::Ref(idx);
return;
}
// And if this type isn't already defined we append it to the index
// space with a fresh and unique name.
let span = Span::from_offset(0); // FIXME(#613): don't manufacture
let id = gensym::gen(span);
self.to_prepend.push(TypeField {
span,
id: Some(id),
name: None,
def: inline.into_def(),
});
let idx = Index::Id(id);
*ty = InterTypeRef::Ref(idx);
}

fn expand_component_type_use<T>(
&mut self,
item: &mut ComponentTypeUse<'a, T>,
) -> ItemRef<'a, kw::r#type>
where
T: TypeReference<'a>,
{
let span = Span::from_offset(0); // FIXME: don't manufacture
let span = Span::from_offset(0); // FIXME(#613): don't manufacture
let dummy = ComponentTypeUse::Ref(ItemRef {
idx: Index::Num(0, span),
kind: kw::r#type(span),
Expand Down