Skip to content

Commit 796340f

Browse files
feat(jco): enable p3 async post return test
1 parent 5ecf84e commit 796340f

File tree

21 files changed

+1623
-506
lines changed

21 files changed

+1623
-506
lines changed

Cargo.lock

Lines changed: 0 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,13 @@ wasmparser = { version = "0.240.0", default-features = false }
4040
wasmprinter = { version = "0.240.0", default-features = false }
4141
wasmtime-environ = { version = "37.0.1", features= [ "component-model", "compile" ] }
4242
wat = { version = "1.240.0", default-features = false }
43-
wit-bindgen = { version = "0.47.0", default-features = false }
44-
wit-bindgen-core = { version = "0.47.0", default-features = false }
43+
44+
#wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "799fdb6838b319f98b8d6472cb52f9301218791b", default-features = false }
45+
#wit-bindgen-core = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "799fdb6838b319f98b8d6472cb52f9301218791b", default-features = false }
46+
47+
wit-bindgen = { path = "../wit-bindgen/crates/guest-rust", default-features = false }
48+
wit-bindgen-core = { path = "../wit-bindgen/crates/core", default-features = false }
49+
4550
wit-component = { version = "0.240.0", features = ["dummy-module"] }
4651
wit-parser = { version = "0.240.0", default-features = false }
4752

crates/js-component-bindgen/src/core.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -483,26 +483,40 @@ fn valtype(ty: wasmparser::ValType) -> wasm_encoder::ValType {
483483
shared,
484484
ty: match ty {
485485
wasmparser::AbstractHeapType::Func => wasm_encoder::AbstractHeapType::Func,
486-
wasmparser::AbstractHeapType::Extern => wasm_encoder::AbstractHeapType::Extern,
486+
wasmparser::AbstractHeapType::Extern => {
487+
wasm_encoder::AbstractHeapType::Extern
488+
}
487489
wasmparser::AbstractHeapType::Any => wasm_encoder::AbstractHeapType::Any,
488490
wasmparser::AbstractHeapType::None => wasm_encoder::AbstractHeapType::None,
489-
wasmparser::AbstractHeapType::NoExtern => wasm_encoder::AbstractHeapType::NoExtern,
490-
wasmparser::AbstractHeapType::NoFunc => wasm_encoder::AbstractHeapType::NoFunc,
491+
wasmparser::AbstractHeapType::NoExtern => {
492+
wasm_encoder::AbstractHeapType::NoExtern
493+
}
494+
wasmparser::AbstractHeapType::NoFunc => {
495+
wasm_encoder::AbstractHeapType::NoFunc
496+
}
491497
wasmparser::AbstractHeapType::Eq => wasm_encoder::AbstractHeapType::Eq,
492-
wasmparser::AbstractHeapType::Struct => wasm_encoder::AbstractHeapType::Struct,
493-
wasmparser::AbstractHeapType::Array => wasm_encoder::AbstractHeapType::Array,
498+
wasmparser::AbstractHeapType::Struct => {
499+
wasm_encoder::AbstractHeapType::Struct
500+
}
501+
wasmparser::AbstractHeapType::Array => {
502+
wasm_encoder::AbstractHeapType::Array
503+
}
494504
wasmparser::AbstractHeapType::I31 => wasm_encoder::AbstractHeapType::I31,
495505
wasmparser::AbstractHeapType::Exn => wasm_encoder::AbstractHeapType::Exn,
496-
wasmparser::AbstractHeapType::NoExn => wasm_encoder::AbstractHeapType::NoExn,
506+
wasmparser::AbstractHeapType::NoExn => {
507+
wasm_encoder::AbstractHeapType::NoExn
508+
}
497509
wasmparser::AbstractHeapType::Cont => wasm_encoder::AbstractHeapType::Cont,
498-
wasmparser::AbstractHeapType::NoCont => wasm_encoder::AbstractHeapType::NoCont,
510+
wasmparser::AbstractHeapType::NoCont => {
511+
wasm_encoder::AbstractHeapType::NoCont
512+
}
499513
},
500514
},
501515
wasmparser::HeapType::Concrete(unpacked_idx) => match unpacked_idx {
502516
wasmparser::UnpackedIndex::Module(idx)
503-
| wasmparser::UnpackedIndex::RecGroup(idx) => {
504-
wasm_encoder::HeapType::Concrete(idx)
505-
}
517+
| wasmparser::UnpackedIndex::RecGroup(idx) => {
518+
wasm_encoder::HeapType::Concrete(idx)
519+
}
506520
wasmparser::UnpackedIndex::Id(core_type_id) => {
507521
wasm_encoder::HeapType::Concrete(
508522
u32::try_from(core_type_id.index()).unwrap(),
@@ -908,3 +922,5 @@ impl Translator<'_, '_> {
908922
self.func.instruction(&Call(func));
909923
}
910924
}
925+
926+

crates/js-component-bindgen/src/esm_bindgen.rs

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,14 +256,31 @@ impl EsmBindgen {
256256
js_string.contains("\"") || js_string.contains("'") || js_string.contains("`")
257257
}
258258

259+
/// Render a block of imports
260+
///
261+
/// This is normally right before the instantiation code in the generated output, e.g.:
262+
///
263+
/// ```
264+
/// const { someFn } = imports['ns:pkg/iface'];
265+
/// const { asyncOtherFn } = imports['ns:pkg/iface2'];
266+
/// const { someFn, asyncSomeFn } = imports['ns:pkg/iface3'];
267+
/// const { getDirectories } = imports['wasi:filesystem/preopens'];
268+
/// const { Descriptor, filesystemErrorCode } = imports['wasi:filesystem/types'];
269+
/// const { Error: Error$1 } = imports['wasi:io/error'];
270+
/// const { InputStream, OutputStream } = imports['wasi:io/streams'];
271+
/// let gen = (function* _initGenerator () {
272+
/// ```
273+
///
259274
pub fn render_imports(
260275
&mut self,
261276
output: &mut Source,
262277
imports_object: Option<&str>,
263278
local_names: &mut LocalNames,
264279
) {
265280
let mut iface_imports = Vec::new();
281+
266282
for (specifier, binding) in &self.imports {
283+
// Build IDL binding if the specifier uses specifal WebIDL support
267284
let idl_binding = if specifier.starts_with("webidl:") {
268285
let iface_idx = specifier.find('/').unwrap() + 1;
269286
let iface_name = if let Some(version_idx) = specifier.find('@') {
@@ -275,13 +292,19 @@ impl EsmBindgen {
275292
} else {
276293
None
277294
};
295+
278296
if imports_object.is_some() || idl_binding.is_some() {
279297
uwrite!(output, "const ");
280298
} else {
281299
uwrite!(output, "import ");
282300
}
301+
283302
match binding {
303+
// For interfaces we import the entire object as one
284304
ImportBinding::Interface(bindings) => {
305+
// If we there is no import object and it's not an IDL binding and there's only
306+
// *one* binding, then we can directly import rather than attempting to extract
307+
// individual imports
285308
if imports_object.is_none() && idl_binding.is_none() && bindings.len() == 1 {
286309
let (import_name, import) = bindings.iter().next().unwrap();
287310
if import_name == "default" {
@@ -305,8 +328,13 @@ impl EsmBindgen {
305328
continue;
306329
}
307330
}
331+
308332
uwrite!(output, "{{");
333+
309334
let mut first = true;
335+
let mut bound_external_names = Vec::new();
336+
// Generate individual imports for all the bindings that were provided,
337+
// to generate the lhs of the destructured assignment
310338
for (external_name, import) in bindings {
311339
match import {
312340
ImportBinding::Interface(iface) => {
@@ -328,7 +356,12 @@ impl EsmBindgen {
328356
} else {
329357
uwrite!(output, "{external_name} as {iface_local_name}");
330358
}
359+
bound_external_names.push((
360+
external_name.to_string(),
361+
iface_local_name.to_string(),
362+
));
331363
}
364+
332365
ImportBinding::Local(local_names) => {
333366
for local_name in local_names {
334367
if first {
@@ -344,19 +377,34 @@ impl EsmBindgen {
344377
} else {
345378
uwrite!(output, "{external_name} as {local_name}");
346379
}
380+
bound_external_names
381+
.push((external_name.to_string(), local_name.to_string()));
347382
}
348383
}
349384
};
350385
}
386+
351387
if !first {
352388
output.push_str(" ");
353389
}
390+
391+
// End the destructured assignment
354392
if let Some(imports_object) = imports_object {
355393
uwriteln!(
356394
output,
357395
"}} = {imports_object}{};",
358396
maybe_quote_member(specifier)
359397
);
398+
for (external_name, local_name) in bound_external_names {
399+
uwriteln!(
400+
output,
401+
r#"
402+
if ({local_name} === undefined) {{
403+
throw new Error("unexpectedly undefined instance import '{local_name}', was '{external_name}' available at instantiation?");
404+
}}
405+
"#,
406+
);
407+
}
360408
} else if let Some(idl_binding) = idl_binding {
361409
uwrite!(
362410
output,
@@ -373,6 +421,8 @@ impl EsmBindgen {
373421
uwriteln!(output, "}} from '{specifier}';");
374422
}
375423
}
424+
425+
// For local bindings we can use a simpler direct assignment
376426
ImportBinding::Local(binding_local_names) => {
377427
let local_name = &binding_local_names[0];
378428
if let Some(imports_object) = imports_object {
@@ -391,10 +441,12 @@ impl EsmBindgen {
391441
}
392442
}
393443

394-
// render interface import member getters
444+
// Render interface import member getters
395445
for (iface_local_name, iface_imports) in iface_imports {
396446
uwrite!(output, "const {{");
397447
let mut first = true;
448+
let mut generated_member_names = Vec::new();
449+
398450
for (member_name, binding) in iface_imports {
399451
let ImportBinding::Local(binding_local_names) = binding else {
400452
continue;
@@ -411,12 +463,26 @@ impl EsmBindgen {
411463
} else {
412464
uwrite!(output, "{member_name}: {local_name}");
413465
}
466+
generated_member_names.push((member_name, local_name));
414467
}
415468
}
416469
if !first {
417470
output.push_str(" ");
418471
}
419472
uwriteln!(output, "}} = {iface_local_name};");
473+
474+
// Ensure that the imports we destructured were defined
475+
// (if they were not, the user is likely missing an import @ instantiation time)
476+
for (member_name, local_name) in generated_member_names {
477+
uwriteln!(
478+
output,
479+
r#"
480+
if ({local_name} === undefined) {{
481+
throw new Error("unexpectedly undefined local import '{local_name}', was '{member_name}' available at instantiation?");
482+
}}
483+
"#,
484+
);
485+
}
420486
}
421487
}
422488
}

0 commit comments

Comments
 (0)