Skip to content

Commit 9c40084

Browse files
author
Guy Bedford
authored
gen-guest-c: define OK constant for scalar enum results (#440)
1 parent 4bd4371 commit 9c40084

5 files changed

Lines changed: 50 additions & 14 deletions

File tree

crates/gen-guest-c/src/lib.rs

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -594,9 +594,8 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
594594
fn type_enum(&mut self, id: TypeId, name: &str, enum_: &Enum, docs: &Docs) {
595595
let prev = mem::take(&mut self.src.h_defs);
596596
self.docs(docs);
597-
self.src.h_defs("\ntypedef ");
598-
self.src.h_defs(int_repr(enum_.tag()));
599-
self.src.h_defs(" ");
597+
let int_t = int_repr(enum_.tag());
598+
uwrite!(self.src.h_defs, "\ntypedef {int_t} ");
600599
self.print_typedef_target(name);
601600

602601
if enum_.cases.len() > 0 {
@@ -612,6 +611,13 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
612611
i,
613612
);
614613
}
614+
uwriteln!(
615+
self.src.h_defs,
616+
"#define {}_RESULT_{}_OK {}",
617+
self.name.to_shouty_snake_case(),
618+
name.to_shouty_snake_case(),
619+
int_max_str(enum_.tag())
620+
);
615621

616622
self.types
617623
.insert(id, mem::replace(&mut self.src.h_defs, prev));
@@ -1964,41 +1970,48 @@ impl Bindgen for FunctionBindgen<'_, '_> {
19641970
}
19651971

19661972
Instruction::ResultLift { result, ty, .. } => {
1967-
let (err, err_results) = self.blocks.pop().unwrap();
1973+
let (mut err, err_results) = self.blocks.pop().unwrap();
19681974
assert!(err_results.len() == (result.err.is_some() as usize));
1969-
let (ok, ok_results) = self.blocks.pop().unwrap();
1975+
let (mut ok, ok_results) = self.blocks.pop().unwrap();
19701976
assert!(ok_results.len() == (result.ok.is_some() as usize));
19711977

1978+
if err.len() > 0 {
1979+
err.push_str("\n");
1980+
}
1981+
if ok.len() > 0 {
1982+
ok.push_str("\n");
1983+
}
1984+
19721985
let result_tmp = self.locals.tmp("result");
19731986
let set_ok = if let Some(_) = self.gen.get_nonempty_type(result.ok.as_ref()) {
19741987
let ok_result = &ok_results[0];
1975-
format!("{result_tmp}.val.ok = {ok_result};")
1988+
format!("{result_tmp}.val.ok = {ok_result};\n")
19761989
} else {
19771990
String::new()
19781991
};
19791992
let set_err = if let Some(_) = self.gen.get_nonempty_type(result.err.as_ref()) {
19801993
let err_result = &err_results[0];
1981-
format!("{result_tmp}.val.err = {err_result};")
1994+
format!("{result_tmp}.val.err = {err_result};\n")
19821995
} else {
19831996
String::new()
19841997
};
19851998

19861999
let ty = self.gen.type_string(&Type::Id(*ty));
19872000
uwriteln!(self.src, "{ty} {result_tmp};");
19882001
let op0 = &operands[0];
1989-
uwrite!(
2002+
uwriteln!(
19902003
self.src,
19912004
"switch ({op0}) {{
19922005
case 0: {{
19932006
{result_tmp}.is_err = false;
1994-
{ok}
1995-
{set_ok}
2007+
{ok}\
2008+
{set_ok}\
19962009
break;
19972010
}}
19982011
case 1: {{
19992012
{result_tmp}.is_err = true;
2000-
{err}
2001-
{set_err}
2013+
{err}\
2014+
{set_err}\
20022015
break;
20032016
}}
20042017
}}"
@@ -2384,6 +2397,15 @@ fn int_repr(ty: Int) -> &'static str {
23842397
}
23852398
}
23862399

2400+
fn int_max_str(ty: Int) -> String {
2401+
match ty {
2402+
Int::U8 => u8::MAX.to_string(),
2403+
Int::U16 => u16::MAX.to_string(),
2404+
Int::U32 => u32::MAX.to_string(),
2405+
Int::U64 => u64::MAX.to_string(),
2406+
}
2407+
}
2408+
23872409
fn flags_repr(f: &Flags) -> Int {
23882410
match f.repr() {
23892411
FlagsRepr::U8 => Int::U8,

tests/runtime/flavorful/host.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use wit_bindgen_host_wasmtime_rust::Result as HostResult;
44
wit_bindgen_host_wasmtime_rust::generate!("../../tests/runtime/flavorful/world.wit");
55

66
#[derive(Default)]
7-
pub struct MyImports;
7+
pub struct MyImports {
8+
errored: bool
9+
}
810

911
impl imports::Imports for MyImports {
1012
fn f_list_in_record1(&mut self, ty: imports::ListInRecord1) -> Result<()> {
@@ -57,10 +59,14 @@ impl imports::Imports for MyImports {
5759
}
5860

5961
fn errno_result(&mut self) -> HostResult<(), imports::MyErrno> {
62+
if self.errored {
63+
return Ok(());
64+
}
6065
imports::MyErrno::A.to_string();
6166
format!("{:?}", imports::MyErrno::A);
6267
fn assert_error<T: std::error::Error>() {}
6368
assert_error::<imports::MyErrno>();
69+
self.errored = true;
6470
Err(imports::MyErrno::B)?
6571
}
6672

tests/runtime/flavorful/host.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@ export function fListInVariant3(x: any) {
2424
assert.strictEqual(x, 'input3');
2525
return 'output3';
2626
}
27+
let firstErr = true;
2728
export function errnoResult() {
28-
throw new Error('b');
29+
if (firstErr) {
30+
firstErr = false;
31+
throw new Error('b');
32+
}
2933
}
3034
export function listTypedefs(x: any, y: any) {
3135
assert.strictEqual(x, 'typedef1');

tests/runtime/flavorful/wasm.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ void flavorful_test_imports() {
6363

6464
assert(imports_errno_result() == IMPORTS_MY_ERRNO_B);
6565

66+
assert(imports_errno_result() == IMPORTS_RESULT_MY_ERRNO_OK);
67+
6668
{
6769
flavorful_string_t a;
6870
flavorful_string_set(&a, "typedef1");

tests/runtime/flavorful/wasm.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ impl Flavorful for Component {
4343
fn assert_error<T: std::error::Error>() {}
4444
assert_error::<MyErrno>();
4545

46+
assert!(errno_result().is_ok());
47+
4648
let (a, b) = list_typedefs("typedef1", &["typedef2"]);
4749
assert_eq!(a, b"typedef3");
4850
assert_eq!(b.len(), 1);

0 commit comments

Comments
 (0)