Skip to content

Commit e1b85f2

Browse files
author
Guy Bedford
authored
gen-host-js: Error wrapping and unwrapping for singular Result types (#409)
* gen-host-js: Error wrapping and unwrapping for singular results When an exported component function has a singular return of type result, treat this as a throwable in the JS enviroment, by throwing the error payload. Similarly, when an imported function has a singular return of type result, add a catch handler and wrap the function in a result object when handling. Further optimization work should be done to avoid unnecessary wrapping in future. * better payload check, return fixup * fixup demo * improved error payload extraction * fixup tests, intrinsic dependence * remove unnecessary tostring * pr feedback * remove unnecessary include * simpler throws check * review feedback * explicit result flattening * throws signature * fixup throws signature
1 parent 829d556 commit e1b85f2

6 files changed

Lines changed: 296 additions & 166 deletions

File tree

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

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ impl WorldGenerator for C {
123123
let linking_symbol = component_type_object::linking_symbol(name);
124124
self.include("<stdlib.h>");
125125
let snake = name.to_snake_case();
126-
self.include(&format!("\"{snake}.h\""));
127126
uwrite!(
128127
self.src.c_adapters,
129128
"
@@ -196,37 +195,43 @@ impl WorldGenerator for C {
196195
);
197196
}
198197

199-
let mut h_str = format!(
200-
"#ifndef __BINDINGS_{0}_H\n\
201-
#define __BINDINGS_{0}_H\n\
202-
#ifdef __cplusplus\n\
203-
extern \"C\" {{\n\
204-
#endif\n\n",
198+
let mut h_str = wit_bindgen_core::Source::default();
199+
200+
uwrite!(
201+
h_str,
202+
"#ifndef __BINDINGS_{0}_H
203+
#define __BINDINGS_{0}_H
204+
#ifdef __cplusplus
205+
extern \"C\" {{",
205206
name.to_shouty_snake_case(),
206207
);
208+
209+
// Deindent the extern C { declaration
210+
h_str.deindent(1);
211+
uwriteln!(h_str, "\n#endif\n");
212+
207213
self.include("<stdint.h>");
208214
self.include("<stdbool.h>");
209215

210216
for include in self.includes.iter() {
211217
uwriteln!(h_str, "#include {include}");
212218
}
213-
h_str.push_str("\n");
214219

215-
let mut c_str = format!("#include \"{snake}.h\"\n");
220+
let mut c_str = wit_bindgen_core::Source::default();
221+
uwriteln!(c_str, "#include \"{snake}.h\"");
216222
if c_str.len() > 0 {
217223
c_str.push_str("\n");
218224
}
219225
c_str.push_str(&self.src.c_fns);
220226

221227
if self.needs_string {
222-
uwrite!(
228+
uwriteln!(
223229
h_str,
224230
"
225-
typedef struct {{
226-
{ty} *ptr;
227-
size_t len;
228-
}} {snake}_string_t;
229-
",
231+
typedef struct {{\n\
232+
{ty} *ptr;\n\
233+
size_t len;\n\
234+
}} {snake}_string_t;",
230235
ty = self.char_type(),
231236
);
232237
}
@@ -237,35 +242,43 @@ impl WorldGenerator for C {
237242
h_str.push_str(&self.src.h_fns);
238243

239244
if !self.opts.no_helpers && self.src.h_helpers.len() > 0 {
240-
h_str.push_str("\n// Helper Functions\n");
245+
uwriteln!(h_str, "\n// Helper Functions");
241246
h_str.push_str(&self.src.h_helpers);
242247
h_str.push_str("\n");
243248
}
244249

245250
if !self.opts.no_helpers && self.src.c_helpers.len() > 0 {
246-
c_str.push_str("\n// Helper Functions\n");
251+
uwriteln!(c_str, "\n// Helper Functions");
247252
c_str.push_str(self.src.c_helpers.as_mut_string());
248253
}
249254

250-
c_str.push_str("\n// Component Adapters\n");
255+
uwriteln!(c_str, "\n// Component Adapters");
251256

252257
// Declare a statically-allocated return area, if needed. We only do
253258
// this for export bindings, because import bindings allocate their
254259
// return-area on the stack.
255260
if self.return_pointer_area_size > 0 {
261+
// Automatic indentation avoided due to `extern "C" {` declaration
256262
uwrite!(
257263
c_str,
258264
"
259-
__attribute__((aligned({})))
260-
static uint8_t RET_AREA[{}];
261-
",
265+
__attribute__((aligned({})))
266+
static uint8_t RET_AREA[{}];
267+
",
262268
self.return_pointer_area_align,
263269
self.return_pointer_area_size,
264270
);
265271
}
266272
c_str.push_str(&self.src.c_adapters);
267273

268-
h_str.push_str("\n#ifdef __cplusplus\n}\n#endif\n#endif\n");
274+
uwriteln!(
275+
h_str,
276+
"
277+
#ifdef __cplusplus
278+
}}
279+
#endif
280+
#endif"
281+
);
269282

270283
files.push(&format!("{snake}.c"), c_str.as_bytes());
271284
files.push(&format!("{snake}.h"), h_str.as_bytes());
@@ -717,7 +730,7 @@ impl InterfaceGenerator<'_> {
717730
// canonical ABI.
718731
uwriteln!(
719732
self.src.c_adapters,
720-
"__attribute__((export_name(\"{export_name}\")))"
733+
"\n__attribute__((export_name(\"{export_name}\")))"
721734
);
722735
let import_name = self.gen.names.tmp(&format!(
723736
"__wasm_export_{}_{}",

0 commit comments

Comments
 (0)