mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-04-01 18:01:06 +00:00
Get rid of the wasm interface types return pointer hacks
Now that using standard Wasm interface types implies multi-value support, we don't need these return pointer hacks anymore.
This commit is contained in:
parent
311ae1941f
commit
25dd84c503
@ -954,7 +954,10 @@ impl<'a> Context<'a> {
|
|||||||
match op.kind {
|
match op.kind {
|
||||||
decode::OperationKind::Regular => {
|
decode::OperationKind::Regular => {
|
||||||
if op.is_static {
|
if op.is_static {
|
||||||
Ok((AuxImport::ValueWithThis(class, function.name.to_string()), false))
|
Ok((
|
||||||
|
AuxImport::ValueWithThis(class, function.name.to_string()),
|
||||||
|
false,
|
||||||
|
))
|
||||||
} else if structural {
|
} else if structural {
|
||||||
Ok((
|
Ok((
|
||||||
AuxImport::StructuralMethod(function.name.to_string()),
|
AuxImport::StructuralMethod(function.name.to_string()),
|
||||||
@ -1361,48 +1364,26 @@ impl<'a> Context<'a> {
|
|||||||
.bindings
|
.bindings
|
||||||
.get(bind.binding)
|
.get(bind.binding)
|
||||||
.ok_or_else(|| format_err!("bad binding id"))?;
|
.ok_or_else(|| format_err!("bad binding id"))?;
|
||||||
let mut return_via_outptr = None;
|
|
||||||
let (wasm_ty, webidl_ty, incoming, outgoing) = match binding {
|
let (wasm_ty, webidl_ty, incoming, outgoing) = match binding {
|
||||||
ast::FunctionBinding::Export(e) => {
|
ast::FunctionBinding::Export(e) => (
|
||||||
// This `match` is weird, see the comment at the top of
|
e.wasm_ty,
|
||||||
// `standard.rs` for what it's doing.
|
e.webidl_ty,
|
||||||
let outgoing = match e.result.bindings.get(0) {
|
e.params.bindings.as_slice(),
|
||||||
Some(ast::OutgoingBindingExpression::As(a)) if a.idx == u32::max_value() => {
|
&e.result.bindings[..],
|
||||||
return_via_outptr = Some(vec![walrus::ValType::I32, walrus::ValType::I32]);
|
),
|
||||||
&e.result.bindings[1..]
|
ast::FunctionBinding::Import(e) => (
|
||||||
}
|
e.wasm_ty,
|
||||||
_ => &e.result.bindings[..],
|
e.webidl_ty,
|
||||||
};
|
&e.result.bindings[..],
|
||||||
(
|
e.params.bindings.as_slice(),
|
||||||
e.wasm_ty,
|
),
|
||||||
e.webidl_ty,
|
|
||||||
e.params.bindings.as_slice(),
|
|
||||||
outgoing,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
ast::FunctionBinding::Import(e) => {
|
|
||||||
// This `match` is weird, see the comment at the top of
|
|
||||||
// `standard.rs` for what it's doing.
|
|
||||||
let incoming = match e.result.bindings.get(0) {
|
|
||||||
Some(ast::IncomingBindingExpression::Get(g)) if g.idx == u32::max_value() => {
|
|
||||||
return_via_outptr = Some(vec![walrus::ValType::I32, walrus::ValType::I32]);
|
|
||||||
&e.result.bindings[1..]
|
|
||||||
}
|
|
||||||
_ => &e.result.bindings[..],
|
|
||||||
};
|
|
||||||
(
|
|
||||||
e.wasm_ty,
|
|
||||||
e.webidl_ty,
|
|
||||||
incoming,
|
|
||||||
e.params.bindings.as_slice(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let webidl_ty = standard::copy_ty(&mut self.bindings.types, webidl_ty, &std.types);
|
let webidl_ty = standard::copy_ty(&mut self.bindings.types, webidl_ty, &std.types);
|
||||||
let webidl_ty = match webidl_ty {
|
let webidl_ty = match webidl_ty {
|
||||||
ast::WebidlTypeRef::Id(id) => <ast::WebidlFunction as ast::WebidlTypeId>::wrap(id),
|
ast::WebidlTypeRef::Id(id) => <ast::WebidlFunction as ast::WebidlTypeId>::wrap(id),
|
||||||
_ => bail!("invalid webidl type listed"),
|
_ => bail!("invalid webidl type listed"),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Binding {
|
Ok(Binding {
|
||||||
wasm_ty,
|
wasm_ty,
|
||||||
webidl_ty,
|
webidl_ty,
|
||||||
@ -1416,7 +1397,7 @@ impl<'a> Context<'a> {
|
|||||||
.cloned()
|
.cloned()
|
||||||
.map(NonstandardOutgoing::Standard)
|
.map(NonstandardOutgoing::Standard)
|
||||||
.collect(),
|
.collect(),
|
||||||
return_via_outptr,
|
return_via_outptr: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,39 +16,6 @@
|
|||||||
//! generating any JS glue. Any JS glue currently generated is also invalid if
|
//! generating any JS glue. Any JS glue currently generated is also invalid if
|
||||||
//! the module contains the wasm bindings section and it's actually respected.
|
//! the module contains the wasm bindings section and it's actually respected.
|
||||||
|
|
||||||
// NB: Returning strings is weird
|
|
||||||
//
|
|
||||||
// This module has what is currently a pretty gross hack for dealing with
|
|
||||||
// returning strings. One of the banner features of WebIDL bindings is not
|
|
||||||
// requiring any language-specific glue to use wasm files and you get all sorts
|
|
||||||
// of types like integers and strings by default. Note that strings are a huge
|
|
||||||
// thing here.
|
|
||||||
//
|
|
||||||
// Dealing with *incoming* strings is easy enough in that the binding expression
|
|
||||||
// has an allocator function to call and it's filled in and passed as two
|
|
||||||
// pointers. Outgoing strings are a little harder, however, for two reasons:
|
|
||||||
//
|
|
||||||
// * One is that we need to return two values, which requires multi-value
|
|
||||||
// * Another is that someone's got to free the string at some point
|
|
||||||
//
|
|
||||||
// Rust/wasm-bindgen don't support multi-value, and WebIDL bindings as literally
|
|
||||||
// spec'd right this red hot second don't support freeing strings that we pass
|
|
||||||
// out. These both have obvious fixes (supporting multi-value and extending the
|
|
||||||
// bindings spec to support freeing) but we also want something working right
|
|
||||||
// this red-hot second.
|
|
||||||
//
|
|
||||||
// To get things working we employ a terrible hack where the first bindign
|
|
||||||
// expression of the result a function may indicate "use a thing that's way off
|
|
||||||
// in the ether" and that's actually a sentinel for "oh ignore everything else
|
|
||||||
// and the string is returned through an out-ptr as the first argument". This
|
|
||||||
// manifests in all sorts of special hacks all over the place to handle this,
|
|
||||||
// and it's a real bummer.
|
|
||||||
//
|
|
||||||
// This is in general just an explainer for the current state of things and
|
|
||||||
// also a preemptive apology for writing the code to handle this in so many
|
|
||||||
// places. I, like you, look forward to actually fixing this for real as the
|
|
||||||
// spec continues to evolve and we implement more in wasm-bindgen.
|
|
||||||
|
|
||||||
use crate::descriptor::VectorKind;
|
use crate::descriptor::VectorKind;
|
||||||
use crate::webidl::{AuxExportKind, AuxImport, AuxValue, JsImport, JsImportName};
|
use crate::webidl::{AuxExportKind, AuxImport, AuxValue, JsImport, JsImportName};
|
||||||
use crate::webidl::{NonstandardIncoming, NonstandardOutgoing};
|
use crate::webidl::{NonstandardIncoming, NonstandardOutgoing};
|
||||||
@ -240,7 +207,7 @@ pub fn add_section(
|
|||||||
name
|
name
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
let mut result = extract_outgoing(&binding.outgoing).with_context(|_| {
|
let result = extract_outgoing(&binding.outgoing).with_context(|_| {
|
||||||
format!(
|
format!(
|
||||||
"failed to map return value for export `{}` to standard \
|
"failed to map return value for export `{}` to standard \
|
||||||
binding expressions",
|
binding expressions",
|
||||||
@ -248,18 +215,7 @@ pub fn add_section(
|
|||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// see comment at top of this module about returning strings for what
|
assert!(binding.return_via_outptr.is_none());
|
||||||
// this is doing and why it's weird
|
|
||||||
if binding.return_via_outptr.is_some() {
|
|
||||||
result.insert(
|
|
||||||
0,
|
|
||||||
ast::OutgoingBindingExpressionAs {
|
|
||||||
idx: u32::max_value(),
|
|
||||||
ty: ast::WebidlScalarType::Long.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let binding = section.bindings.insert(ast::ExportBinding {
|
let binding = section.bindings.insert(ast::ExportBinding {
|
||||||
wasm_ty: binding.wasm_ty,
|
wasm_ty: binding.wasm_ty,
|
||||||
webidl_ty: copy_ty(
|
webidl_ty: copy_ty(
|
||||||
@ -293,24 +249,14 @@ pub fn add_section(
|
|||||||
module_name, name,
|
module_name, name,
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
let mut result = extract_incoming(&binding.incoming).with_context(|_| {
|
let result = extract_incoming(&binding.incoming).with_context(|_| {
|
||||||
format!(
|
format!(
|
||||||
"failed to map return value of import `{}::{}` to standard \
|
"failed to map return value of import `{}::{}` to standard \
|
||||||
binding expressions",
|
binding expressions",
|
||||||
module_name, name,
|
module_name, name,
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
// see comment at top of this module about returning strings for what
|
assert!(binding.return_via_outptr.is_none());
|
||||||
// this is doing and why it's weird
|
|
||||||
if binding.return_via_outptr.is_some() {
|
|
||||||
result.insert(
|
|
||||||
0,
|
|
||||||
ast::IncomingBindingExpressionGet {
|
|
||||||
idx: u32::max_value(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let binding = section.bindings.insert(ast::ImportBinding {
|
let binding = section.bindings.insert(ast::ImportBinding {
|
||||||
wasm_ty: binding.wasm_ty,
|
wasm_ty: binding.wasm_ty,
|
||||||
webidl_ty: copy_ty(
|
webidl_ty: copy_ty(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user