Skip to content

Commit fe4dd0b

Browse files
authored
Merge pull request #1805 from fitzgen/wasm-interface-types-and-multi-value
Wasm interface types and multi-value
2 parents 46cbd19 + 25dd84c commit fe4dd0b

File tree

3 files changed

+23
-96
lines changed

3 files changed

+23
-96
lines changed

crates/cli-support/src/lib.rs

100644100755
+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl Bindgen {
9696
weak_refs: env::var("WASM_BINDGEN_WEAKREF").is_ok(),
9797
threads: threads_config(),
9898
anyref: anyref || wasm_interface_types,
99-
multi_value,
99+
multi_value: multi_value || wasm_interface_types,
100100
wasm_interface_types,
101101
encode_into: EncodeInto::Test,
102102
}

crates/cli-support/src/webidl/mod.rs

+18-37
Original file line numberDiff line numberDiff line change
@@ -954,7 +954,10 @@ impl<'a> Context<'a> {
954954
match op.kind {
955955
decode::OperationKind::Regular => {
956956
if op.is_static {
957-
Ok((AuxImport::ValueWithThis(class, function.name.to_string()), false))
957+
Ok((
958+
AuxImport::ValueWithThis(class, function.name.to_string()),
959+
false,
960+
))
958961
} else if structural {
959962
Ok((
960963
AuxImport::StructuralMethod(function.name.to_string()),
@@ -1361,48 +1364,26 @@ impl<'a> Context<'a> {
13611364
.bindings
13621365
.get(bind.binding)
13631366
.ok_or_else(|| format_err!("bad binding id"))?;
1364-
let mut return_via_outptr = None;
13651367
let (wasm_ty, webidl_ty, incoming, outgoing) = match binding {
1366-
ast::FunctionBinding::Export(e) => {
1367-
// This `match` is weird, see the comment at the top of
1368-
// `standard.rs` for what it's doing.
1369-
let outgoing = match e.result.bindings.get(0) {
1370-
Some(ast::OutgoingBindingExpression::As(a)) if a.idx == u32::max_value() => {
1371-
return_via_outptr = Some(vec![walrus::ValType::I32, walrus::ValType::I32]);
1372-
&e.result.bindings[1..]
1373-
}
1374-
_ => &e.result.bindings[..],
1375-
};
1376-
(
1377-
e.wasm_ty,
1378-
e.webidl_ty,
1379-
e.params.bindings.as_slice(),
1380-
outgoing,
1381-
)
1382-
}
1383-
ast::FunctionBinding::Import(e) => {
1384-
// This `match` is weird, see the comment at the top of
1385-
// `standard.rs` for what it's doing.
1386-
let incoming = match e.result.bindings.get(0) {
1387-
Some(ast::IncomingBindingExpression::Get(g)) if g.idx == u32::max_value() => {
1388-
return_via_outptr = Some(vec![walrus::ValType::I32, walrus::ValType::I32]);
1389-
&e.result.bindings[1..]
1390-
}
1391-
_ => &e.result.bindings[..],
1392-
};
1393-
(
1394-
e.wasm_ty,
1395-
e.webidl_ty,
1396-
incoming,
1397-
e.params.bindings.as_slice(),
1398-
)
1399-
}
1368+
ast::FunctionBinding::Export(e) => (
1369+
e.wasm_ty,
1370+
e.webidl_ty,
1371+
e.params.bindings.as_slice(),
1372+
&e.result.bindings[..],
1373+
),
1374+
ast::FunctionBinding::Import(e) => (
1375+
e.wasm_ty,
1376+
e.webidl_ty,
1377+
&e.result.bindings[..],
1378+
e.params.bindings.as_slice(),
1379+
),
14001380
};
14011381
let webidl_ty = standard::copy_ty(&mut self.bindings.types, webidl_ty, &std.types);
14021382
let webidl_ty = match webidl_ty {
14031383
ast::WebidlTypeRef::Id(id) => <ast::WebidlFunction as ast::WebidlTypeId>::wrap(id),
14041384
_ => bail!("invalid webidl type listed"),
14051385
};
1386+
14061387
Ok(Binding {
14071388
wasm_ty,
14081389
webidl_ty,
@@ -1416,7 +1397,7 @@ impl<'a> Context<'a> {
14161397
.cloned()
14171398
.map(NonstandardOutgoing::Standard)
14181399
.collect(),
1419-
return_via_outptr,
1400+
return_via_outptr: None,
14201401
})
14211402
}
14221403

crates/cli-support/src/webidl/standard.rs

+4-58
Original file line numberDiff line numberDiff line change
@@ -16,39 +16,6 @@
1616
//! generating any JS glue. Any JS glue currently generated is also invalid if
1717
//! the module contains the wasm bindings section and it's actually respected.
1818
19-
// NB: Returning strings is weird
20-
//
21-
// This module has what is currently a pretty gross hack for dealing with
22-
// returning strings. One of the banner features of WebIDL bindings is not
23-
// requiring any language-specific glue to use wasm files and you get all sorts
24-
// of types like integers and strings by default. Note that strings are a huge
25-
// thing here.
26-
//
27-
// Dealing with *incoming* strings is easy enough in that the binding expression
28-
// has an allocator function to call and it's filled in and passed as two
29-
// pointers. Outgoing strings are a little harder, however, for two reasons:
30-
//
31-
// * One is that we need to return two values, which requires multi-value
32-
// * Another is that someone's got to free the string at some point
33-
//
34-
// Rust/wasm-bindgen don't support multi-value, and WebIDL bindings as literally
35-
// spec'd right this red hot second don't support freeing strings that we pass
36-
// out. These both have obvious fixes (supporting multi-value and extending the
37-
// bindings spec to support freeing) but we also want something working right
38-
// this red-hot second.
39-
//
40-
// To get things working we employ a terrible hack where the first bindign
41-
// expression of the result a function may indicate "use a thing that's way off
42-
// in the ether" and that's actually a sentinel for "oh ignore everything else
43-
// and the string is returned through an out-ptr as the first argument". This
44-
// manifests in all sorts of special hacks all over the place to handle this,
45-
// and it's a real bummer.
46-
//
47-
// This is in general just an explainer for the current state of things and
48-
// also a preemptive apology for writing the code to handle this in so many
49-
// places. I, like you, look forward to actually fixing this for real as the
50-
// spec continues to evolve and we implement more in wasm-bindgen.
51-
5219
use crate::descriptor::VectorKind;
5320
use crate::webidl::{AuxExportKind, AuxImport, AuxValue, JsImport, JsImportName};
5421
use crate::webidl::{NonstandardIncoming, NonstandardOutgoing};
@@ -240,26 +207,15 @@ pub fn add_section(
240207
name
241208
)
242209
})?;
243-
let mut result = extract_outgoing(&binding.outgoing).with_context(|_| {
210+
let result = extract_outgoing(&binding.outgoing).with_context(|_| {
244211
format!(
245212
"failed to map return value for export `{}` to standard \
246213
binding expressions",
247214
name
248215
)
249216
})?;
250217

251-
// see comment at top of this module about returning strings for what
252-
// this is doing and why it's weird
253-
if binding.return_via_outptr.is_some() {
254-
result.insert(
255-
0,
256-
ast::OutgoingBindingExpressionAs {
257-
idx: u32::max_value(),
258-
ty: ast::WebidlScalarType::Long.into(),
259-
}
260-
.into(),
261-
);
262-
}
218+
assert!(binding.return_via_outptr.is_none());
263219
let binding = section.bindings.insert(ast::ExportBinding {
264220
wasm_ty: binding.wasm_ty,
265221
webidl_ty: copy_ty(
@@ -293,24 +249,14 @@ pub fn add_section(
293249
module_name, name,
294250
)
295251
})?;
296-
let mut result = extract_incoming(&binding.incoming).with_context(|_| {
252+
let result = extract_incoming(&binding.incoming).with_context(|_| {
297253
format!(
298254
"failed to map return value of import `{}::{}` to standard \
299255
binding expressions",
300256
module_name, name,
301257
)
302258
})?;
303-
// see comment at top of this module about returning strings for what
304-
// this is doing and why it's weird
305-
if binding.return_via_outptr.is_some() {
306-
result.insert(
307-
0,
308-
ast::IncomingBindingExpressionGet {
309-
idx: u32::max_value(),
310-
}
311-
.into(),
312-
);
313-
}
259+
assert!(binding.return_via_outptr.is_none());
314260
let binding = section.bindings.insert(ast::ImportBinding {
315261
wasm_ty: binding.wasm_ty,
316262
webidl_ty: copy_ty(

0 commit comments

Comments
 (0)