Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions crates/gen-c/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ impl C {

fn print_ty(&mut self, iface: &Interface, ty: &Type) {
match ty {
Type::Unit => self.src.h("void"),
Type::Bool => self.src.h("bool"),
Type::Char => self.src.h("uint32_t"), // TODO: better type?
Type::U8 => self.src.h("uint8_t"),
Type::S8 => self.src.h("int8_t"),
Expand Down Expand Up @@ -246,10 +248,7 @@ impl C {
}
match &ty.kind {
TypeDefKind::Type(t) => self.print_ty(iface, t),
TypeDefKind::Variant(v) => {
if v.is_bool() {
return self.src.h("bool");
}
TypeDefKind::Variant(_) => {
self.public_anonymous_types.insert(*id);
self.private_anonymous_types.remove(id);
self.print_namespace(iface);
Expand All @@ -270,6 +269,8 @@ impl C {

fn print_ty_name(&mut self, iface: &Interface, ty: &Type) {
match ty {
Type::Unit => self.src.h("unit"),
Type::Bool => self.src.h("bool"),
Type::Char => self.src.h("char32"),
Type::U8 => self.src.h("u8"),
Type::S8 => self.src.h("s8"),
Expand Down Expand Up @@ -314,8 +315,6 @@ impl C {
Some(t) => self.print_ty_name(iface, t),
None => self.src.h("void"),
}
} else if v.is_bool() {
self.src.h("bool");
} else {
unimplemented!();
}
Expand Down Expand Up @@ -728,12 +727,7 @@ impl Generator for C {
let prev = mem::take(&mut self.src.header);
self.docs(docs);
self.names.insert(&name.to_snake_case()).unwrap();
if variant.is_bool() {
self.src.h("typedef bool ");
self.print_namespace(iface);
self.src.h(&name.to_snake_case());
self.src.h("_t;\n");
} else if variant.is_enum() {
if variant.is_enum() {
self.src.h("typedef ");
self.src.h(int_repr(variant.tag));
self.src.h(" ");
Expand Down Expand Up @@ -1354,6 +1348,15 @@ impl Bindgen for FunctionBindgen<'_> {
}
}

Instruction::UnitLower => {}
Instruction::UnitLift => {
// TODO:
// results.push("None".to_string());
}
Instruction::BoolFromI32 | Instruction::I32FromBool => {
results.push(operands[0].clone());
}

Instruction::I32FromOwnedHandle { .. } | Instruction::I32FromBorrowedHandle { .. } => {
results.push(format!("({}).idx", operands[0]));
}
Expand Down
65 changes: 36 additions & 29 deletions crates/gen-js/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ enum Intrinsic {
Slab,
Promises,
WithCurrentPromise,
ThrowInvalidBool,
}

impl Intrinsic {
Expand All @@ -97,6 +98,7 @@ impl Intrinsic {
Intrinsic::Slab => "Slab",
Intrinsic::Promises => "PROMISES",
Intrinsic::WithCurrentPromise => "with_current_promise",
Intrinsic::ThrowInvalidBool => "throw_invalid_bool",
}
}
}
Expand All @@ -123,6 +125,7 @@ impl Js {

fn array_ty(&self, iface: &Interface, ty: &Type) -> Option<&'static str> {
match ty {
Type::Unit | Type::Bool => None,
Type::U8 => Some("Uint8Array"),
Type::S8 => Some("Int8Array"),
Type::U16 => Some("Uint16Array"),
Expand All @@ -145,6 +148,8 @@ impl Js {

fn print_ty(&mut self, iface: &Interface, ty: &Type) {
match ty {
Type::Unit => self.src.ts("undefined"),
Type::Bool => self.src.ts("boolean"),
Type::U8
| Type::S8
| Type::U16
Expand All @@ -166,7 +171,6 @@ impl Js {
TypeDefKind::Type(t) => self.print_ty(iface, t),
TypeDefKind::Record(r) if r.is_tuple() => self.print_tuple(iface, r),
TypeDefKind::Record(_) => panic!("anonymous record"),
TypeDefKind::Variant(v) if v.is_bool() => self.src.ts("boolean"),
TypeDefKind::Variant(v) => {
if self.is_nullable_option(iface, v) {
self.print_ty(iface, v.cases[1].ty.as_ref().unwrap());
Expand Down Expand Up @@ -415,12 +419,7 @@ impl Generator for Js {
docs: &Docs,
) {
self.docs(docs);
if variant.is_bool() {
self.src.ts(&format!(
"export type {} = boolean;\n",
name.to_camel_case(),
));
} else if self.is_nullable_option(iface, variant) {
if self.is_nullable_option(iface, variant) {
self.src
.ts(&format!("export type {} = ", name.to_camel_case()));
self.print_ty(iface, variant.cases[1].ty.as_ref().unwrap());
Expand Down Expand Up @@ -1318,6 +1317,24 @@ impl Bindgen for FunctionBindgen<'_> {
}
}

Instruction::UnitLower => {}
Instruction::UnitLift => {
results.push("undefined".to_string());
}

Instruction::BoolFromI32 => {
let tmp = self.tmp();
self.src
.js(&format!("const bool{} = {};\n", tmp, operands[0]));
let throw = self.gen.intrinsic(Intrinsic::ThrowInvalidBool);
results.push(format!(
"bool{tmp} == 0 ? false : (bool{tmp} == 1 ? true : {throw}())"
));
}
Instruction::I32FromBool => {
results.push(format!("{} ? 1 : 0", operands[0]));
}

// These instructions are used with handles when we're implementing
// imports. This means we interact with the `resources` slabs to
// translate the wasm-provided index into a JS value.
Expand Down Expand Up @@ -1450,11 +1467,7 @@ impl Bindgen for FunctionBindgen<'_> {
self.src
.js(&format!("const variant{} = {};\n", tmp, operands[0]));

if result_types.len() == 1
&& variant.is_enum()
&& name.is_some()
&& !variant.is_bool()
{
if result_types.len() == 1 && variant.is_enum() && name.is_some() {
let name = name.unwrap().to_camel_case();
self.src
.js(&format!("if (!(variant{} in {}))\n", tmp, name));
Expand All @@ -1474,8 +1487,7 @@ impl Bindgen for FunctionBindgen<'_> {
results.push(format!("variant{}_{}", tmp, i));
}

let expr_to_match = if variant.is_bool()
|| self.gen.is_nullable_option(iface, variant)
let expr_to_match = if self.gen.is_nullable_option(iface, variant)
|| (variant.is_enum() && name.is_some())
{
format!("variant{}", tmp)
Expand All @@ -1488,9 +1500,7 @@ impl Bindgen for FunctionBindgen<'_> {
for (i, (case, (block, block_results))) in
variant.cases.iter().zip(blocks).enumerate()
{
if variant.is_bool() {
self.src.js(&format!("case {}: {{\n", case.name.as_str()));
} else if self.gen.is_nullable_option(iface, variant) {
if self.gen.is_nullable_option(iface, variant) {
if case.ty.is_none() {
self.src.js("case null: {\n");
} else {
Expand Down Expand Up @@ -1519,9 +1529,7 @@ impl Bindgen for FunctionBindgen<'_> {
if use_default {
let variant_name = name.map(|s| s.to_camel_case());
let variant_name = variant_name.as_deref().unwrap_or_else(|| {
if variant.is_bool() {
"bool"
} else if variant.as_expected().is_some() {
if variant.as_expected().is_some() {
"expected"
} else if variant.as_option().is_some() {
"option"
Expand All @@ -1545,7 +1553,7 @@ impl Bindgen for FunctionBindgen<'_> {
.collect::<Vec<_>>();

let tmp = self.tmp();
if variant.is_enum() && name.is_some() && !variant.is_bool() {
if variant.is_enum() && name.is_some() {
let name = name.unwrap().to_camel_case();
self.src
.js(&format!("const tag{} = {};\n", tmp, operands[0]));
Expand All @@ -1566,11 +1574,7 @@ impl Bindgen for FunctionBindgen<'_> {
self.src.js(&format!("case {}: {{\n", i));
self.src.js(&block);

if variant.is_bool() {
assert!(block_results.is_empty());
self.src
.js(&format!("variant{} = {};\n", tmp, case.name.as_str()));
} else if variant.is_enum() && name.is_some() {
if variant.is_enum() && name.is_some() {
assert!(block_results.is_empty());
self.src.js(&format!("variant{} = tag{0};\n", tmp));
} else if self.gen.is_nullable_option(iface, variant) {
Expand All @@ -1597,9 +1601,7 @@ impl Bindgen for FunctionBindgen<'_> {
}
let variant_name = name.map(|s| s.to_camel_case());
let variant_name = variant_name.as_deref().unwrap_or_else(|| {
if variant.is_bool() {
"bool"
} else if variant.as_expected().is_some() {
if variant.as_expected().is_some() {
"expected"
} else if variant.as_option().is_some() {
"option"
Expand Down Expand Up @@ -2241,6 +2243,11 @@ impl Js {
}
}
"),
Intrinsic::ThrowInvalidBool => self.src.js("
export function throw_invalid_bool() {
throw new RangeError(\"invalid variant discriminant for bool\");
}
"),
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions crates/gen-markdown/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ impl Markdown {

fn print_ty(&mut self, iface: &Interface, ty: &Type, skip_name: bool) {
match ty {
Type::Unit => self.src.push_str("`unit`"),
Type::Bool => self.src.push_str("`bool`"),
Type::U8 => self.src.push_str("`u8`"),
Type::S8 => self.src.push_str("`s8`"),
Type::U16 => self.src.push_str("`u16`"),
Expand Down Expand Up @@ -78,9 +80,7 @@ impl Markdown {
self.src.push_str(")");
}
TypeDefKind::Variant(v) => {
if v.is_bool() {
self.src.push_str("`bool`");
} else if let Some(t) = v.as_option() {
if let Some(t) = v.as_option() {
self.src.push_str("option<");
self.print_ty(iface, t, false);
self.src.push_str(">");
Expand Down
26 changes: 26 additions & 0 deletions crates/gen-rust-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,32 @@ impl Bindgen for FunctionBindgen<'_> {
wit_bindgen_gen_rust::bitcast(casts, operands, results)
}

Instruction::UnitLower => {}
Instruction::UnitLift => {
results.push("()".to_string());
}

Instruction::I32FromBool => {
results.push(format!("match {} {{ true => 1, false => 0 }}", operands[0]));
}
Instruction::BoolFromI32 => {
if unchecked {
results.push(format!(
"core::mem::transmute::<u8, bool>({} as u8)",
operands[0],
));
} else {
results.push(format!(
"match {} {{
0 => false,
1 => true,
_ => panic!(\"invalid bool discriminant\"),
}}",
operands[0],
));
}
}

// handles in exports
Instruction::I32FromOwnedHandle { .. } => {
results.push(format!(
Expand Down
20 changes: 7 additions & 13 deletions crates/gen-rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ pub trait RustGenerator {
self.push_str(suffix);
}

Type::Unit => self.push_str("()"),
Type::Bool => self.push_str("bool"),
Type::U8 => self.push_str("u8"),
Type::U16 => self.push_str("u16"),
Type::U32 => self.push_str("u32"),
Expand Down Expand Up @@ -252,9 +254,8 @@ pub trait RustGenerator {
match &ty.kind {
TypeDefKind::List(t) => self.print_list(iface, t, mode),

// Variants can be printed natively if they're `Option`,
// `Result` , or `bool`, otherwise they must be named for now.
TypeDefKind::Variant(v) if v.is_bool() => self.push_str("bool"),
// Variants can be printed natively if they're `Option` or
// `Result`, otherwise they must be named for now.
TypeDefKind::Variant(v) => match v.as_expected() {
Some((ok, err)) => {
self.push_str("Result<");
Expand Down Expand Up @@ -463,10 +464,7 @@ pub trait RustGenerator {
for (name, mode) in self.modes_of(iface, id) {
self.rustdoc(docs);
let lt = self.lifetime_for(&info, mode);
if variant.is_bool() {
self.push_str(&format!("pub type {} = bool;\n", name));
continue;
} else if let Some(ty) = variant.as_option() {
if let Some(ty) = variant.as_option() {
self.push_str(&format!("pub type {}", name));
self.print_generics(&info, lt, true);
self.push_str("= Option<");
Expand Down Expand Up @@ -835,9 +833,7 @@ pub trait RustFunctionGenerator {
self.push_str(operand);
self.push_str("{\n");
for (case, block) in ty.cases.iter().zip(blocks) {
if ty.is_bool() {
self.push_str(case.name.as_str());
} else if ty.as_expected().is_some() {
if ty.as_expected().is_some() {
self.push_str(&case.name.to_camel_case());
self.push_str("(");
self.push_str(if case.ty.is_some() { "e" } else { "()" });
Expand Down Expand Up @@ -874,9 +870,7 @@ pub trait RustFunctionGenerator {
block: &str,
result: &mut String,
) {
if ty.is_bool() {
result.push_str(case.name.as_str());
} else if ty.as_expected().is_some() {
if ty.as_expected().is_some() {
result.push_str(&case.name.to_camel_case());
result.push_str("(");
result.push_str(block);
Expand Down
6 changes: 6 additions & 0 deletions crates/gen-spidermonkey/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2081,6 +2081,12 @@ impl abi::Bindgen for Bindgen<'_, '_> {
}
}

abi::Instruction::UnitLower { .. } => todo!(),
abi::Instruction::UnitLift { .. } => todo!(),

abi::Instruction::I32FromBool { .. } => todo!(),
abi::Instruction::BoolFromI32 { .. } => todo!(),

abi::Instruction::ReturnAsyncExport { .. } => todo!(),
abi::Instruction::ReturnAsyncImport { .. } => todo!(),
}
Expand Down
Loading