mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-17 06:51:24 +00:00
cli-support: Skip generating JS shims for imports when unnecessary
After this change, any import that only takes and returns ABI-safe numbers (signed integers less than 64 bits and unrestricted floating point numbers) will be a direct import, and will not have a little JS shim in the middle. We don't have a great mechanism for testing the generated bindings' contents -- as opposed to its behavior -- but I manually verified that everything here does the Right Thing and doesn't have a JS shim: ```rust \#[wasm_bindgen] extern "C" { fn trivial(); fn incoming_i32() -> i32; fn incoming_f32() -> f32; fn incoming_f64() -> f64; fn outgoing_i32(x: i32); fn outgoing_f32(y: f32); fn outgoing_f64(z: f64); fn many(x: i32, y: f32, z: f64) -> i32; } ``` Furthermore, I verified that when our support for emitting native `anyref` is enabled, then we do not have a JS shim for the following import, but if it is disabled, then we do have a JS shim: ```rust \#[wasm_bindgen] extern "C" { fn works_when_anyref_support_is_enabled(v: JsValue) -> JsValue; } ``` Fixes #1636.
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
use crate::descriptor::VectorKind;
|
||||
use crate::intrinsic::Intrinsic;
|
||||
use crate::webidl;
|
||||
use crate::webidl::{AuxEnum, AuxExport, AuxExportKind, AuxImport, AuxStruct};
|
||||
use crate::webidl::{AuxValue, Binding};
|
||||
use crate::webidl::{JsImport, JsImportName, NonstandardWebidlSection, WasmBindgenAux};
|
||||
@ -723,6 +724,15 @@ impl<'a> Context<'a> {
|
||||
self.global("function getObject(idx) { return heap[idx]; }");
|
||||
}
|
||||
|
||||
fn expose_not_defined(&mut self) {
|
||||
if !self.should_write_global("not_defined") {
|
||||
return;
|
||||
}
|
||||
self.global(
|
||||
"function notDefined(what) { return () => { throw new Error(`${what} is not defined`); }; }"
|
||||
);
|
||||
}
|
||||
|
||||
fn expose_assert_num(&mut self) {
|
||||
if !self.should_write_global("assert_num") {
|
||||
return;
|
||||
@ -1971,16 +1981,59 @@ impl<'a> Context<'a> {
|
||||
.types
|
||||
.get::<ast::WebidlFunction>(binding.webidl_ty)
|
||||
.unwrap();
|
||||
let mut builder = binding::Builder::new(self);
|
||||
builder.catch(catch)?;
|
||||
let js = builder.process(&binding, &webidl, false, &None, &mut |cx, prelude, args| {
|
||||
cx.invoke_import(&binding, import, bindings, args, variadic, prelude)
|
||||
})?;
|
||||
let js = format!("function{}", js);
|
||||
let js = match import {
|
||||
AuxImport::Value(AuxValue::Bare(js))
|
||||
if !variadic && !catch && self.import_does_not_require_glue(binding, webidl) =>
|
||||
{
|
||||
self.expose_not_defined();
|
||||
let name = self.import_name(js)?;
|
||||
format!(
|
||||
"typeof {name} == 'function' ? {name} : notDefined('{name}')",
|
||||
name = name,
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
let mut builder = binding::Builder::new(self);
|
||||
builder.catch(catch)?;
|
||||
let js = builder.process(
|
||||
&binding,
|
||||
&webidl,
|
||||
false,
|
||||
&None,
|
||||
&mut |cx, prelude, args| {
|
||||
cx.invoke_import(&binding, import, bindings, args, variadic, prelude)
|
||||
},
|
||||
)?;
|
||||
format!("function{}", js)
|
||||
}
|
||||
};
|
||||
self.wasm_import_definitions.insert(id, js);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn import_does_not_require_glue(
|
||||
&self,
|
||||
binding: &Binding,
|
||||
webidl: &ast::WebidlFunction,
|
||||
) -> bool {
|
||||
if !self.config.anyref && binding.contains_anyref(self.module) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let wasm_ty = self.module.types.get(binding.wasm_ty);
|
||||
webidl.kind == ast::WebidlFunctionKind::Static
|
||||
&& webidl::outgoing_do_not_require_glue(
|
||||
&binding.outgoing,
|
||||
wasm_ty.params(),
|
||||
&webidl.params,
|
||||
)
|
||||
&& webidl::incoming_do_not_require_glue(
|
||||
&binding.incoming,
|
||||
&webidl.result.into_iter().collect::<Vec<_>>(),
|
||||
wasm_ty.results(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Generates a JS snippet appropriate for invoking `import`.
|
||||
///
|
||||
/// This is generating code for `binding` where `bindings` has more type
|
||||
|
Reference in New Issue
Block a user