Skip to content

Commit e106ca3

Browse files
authored
Merge pull request #1626 from alexcrichton/more-standard
Update all non-mutable slices into Rust to use `AllocCopy`
2 parents e16dd15 + b9c27b9 commit e106ca3

File tree

3 files changed

+65
-65
lines changed

3 files changed

+65
-65
lines changed

crates/cli-support/src/js/incoming.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ impl<'a, 'b> Incoming<'a, 'b> {
153153

154154
// Similar to `AllocCopy`, except that we deallocate in a finally
155155
// block.
156-
NonstandardIncoming::Slice { kind, val, mutable } => {
156+
NonstandardIncoming::MutableSlice { kind, val } => {
157157
let (expr, ty) = self.standard_typed(val)?;
158158
assert_eq!(ty, ast::WebidlScalarType::Any.into());
159159
let func = self.cx.pass_to_wasm_function(*kind)?;
@@ -162,7 +162,7 @@ impl<'a, 'b> Incoming<'a, 'b> {
162162
.prelude(&format!("const ptr{} = {}({});", i, func, expr));
163163
self.js
164164
.prelude(&format!("const len{} = WASM_VECTOR_LEN;", i));
165-
self.finally_free_slice(&expr, i, *kind, *mutable)?;
165+
self.finally_free_slice(&expr, i, *kind, true)?;
166166
self.js.typescript_required(kind.js_ty());
167167
return Ok(vec![format!("ptr{}", i), format!("len{}", i)]);
168168
}

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

Lines changed: 58 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,11 @@ pub enum NonstandardIncoming {
4747
expr: Box<ast::IncomingBindingExpression>,
4848
},
4949

50-
/// JS is passing a typed slice of data into Rust. Currently this is
51-
/// implemented with a deallocation in the JS shim, hence a custom binding.
52-
///
53-
/// TODO: we should move deallocation into Rust so we can use a vanilla and
54-
/// standard webidl binding here.
55-
Slice {
50+
/// A mutable slice of values going from JS to Rust, and after Rust finishes
51+
/// the JS slice is updated with the current value of the slice.
52+
MutableSlice {
5653
kind: VectorKind,
5754
val: ast::IncomingBindingExpression,
58-
mutable: bool,
5955
},
6056

6157
/// This is either a slice or `undefined` being passed into Rust.
@@ -216,52 +212,11 @@ impl IncomingBuilder {
216212
Descriptor::Option(d) => self.process_option(d)?,
217213

218214
Descriptor::String | Descriptor::Vector(_) => {
219-
use wasm_webidl_bindings::ast::WebidlScalarType::*;
220-
221215
let kind = arg.vector_kind().ok_or_else(|| {
222216
format_err!("unsupported argument type for calling Rust function from JS {:?}", arg)
223217
})? ;
224218
self.wasm.extend(&[ValType::I32; 2]);
225-
match kind {
226-
VectorKind::I8 => self.alloc_copy(Int8Array),
227-
VectorKind::U8 => self.alloc_copy(Uint8Array),
228-
VectorKind::ClampedU8 => self.alloc_copy(Uint8ClampedArray),
229-
VectorKind::I16 => self.alloc_copy(Int16Array),
230-
VectorKind::U16 => self.alloc_copy(Uint16Array),
231-
VectorKind::I32 => self.alloc_copy(Int32Array),
232-
VectorKind::U32 => self.alloc_copy(Uint32Array),
233-
VectorKind::F32 => self.alloc_copy(Float32Array),
234-
VectorKind::F64 => self.alloc_copy(Float64Array),
235-
VectorKind::String => {
236-
let expr = ast::IncomingBindingExpressionAllocUtf8Str {
237-
alloc_func_name: self.alloc_func_name(),
238-
expr: Box::new(self.expr_get()),
239-
};
240-
self.webidl.push(DomString);
241-
self.bindings
242-
.push(NonstandardIncoming::Standard(expr.into()));
243-
}
244-
VectorKind::I64 | VectorKind::U64 => {
245-
let signed = match kind {
246-
VectorKind::I64 => true,
247-
_ => false,
248-
};
249-
self.bindings.push(NonstandardIncoming::AllocCopyInt64 {
250-
alloc_func_name: self.alloc_func_name(),
251-
expr: Box::new(self.expr_get()),
252-
signed,
253-
});
254-
self.webidl.push(Any);
255-
}
256-
VectorKind::Anyref => {
257-
self.bindings
258-
.push(NonstandardIncoming::AllocCopyAnyrefArray {
259-
alloc_func_name: self.alloc_func_name(),
260-
expr: Box::new(self.expr_get()),
261-
});
262-
self.webidl.push(Any);
263-
}
264-
}
219+
self.alloc_copy_kind(kind)
265220
}
266221

267222
// Can't be passed from JS to Rust yet
@@ -309,12 +264,15 @@ impl IncomingBuilder {
309264
)
310265
})?;
311266
self.wasm.extend(&[ValType::I32; 2]);
312-
self.bindings.push(NonstandardIncoming::Slice {
313-
kind,
314-
val: self.expr_get(),
315-
mutable,
316-
});
317-
self.webidl.push(ast::WebidlScalarType::Any);
267+
if mutable {
268+
self.bindings.push(NonstandardIncoming::MutableSlice {
269+
kind,
270+
val: self.expr_get(),
271+
});
272+
self.webidl.push(ast::WebidlScalarType::Any);
273+
} else {
274+
self.alloc_copy_kind(kind)
275+
}
318276
}
319277
_ => bail!(
320278
"unsupported reference argument type for calling Rust function from JS: {:?}",
@@ -445,6 +403,51 @@ impl IncomingBuilder {
445403
"__wbindgen_malloc".to_string()
446404
}
447405

406+
fn alloc_copy_kind(&mut self, kind: VectorKind) {
407+
use wasm_webidl_bindings::ast::WebidlScalarType::*;
408+
409+
match kind {
410+
VectorKind::I8 => self.alloc_copy(Int8Array),
411+
VectorKind::U8 => self.alloc_copy(Uint8Array),
412+
VectorKind::ClampedU8 => self.alloc_copy(Uint8ClampedArray),
413+
VectorKind::I16 => self.alloc_copy(Int16Array),
414+
VectorKind::U16 => self.alloc_copy(Uint16Array),
415+
VectorKind::I32 => self.alloc_copy(Int32Array),
416+
VectorKind::U32 => self.alloc_copy(Uint32Array),
417+
VectorKind::F32 => self.alloc_copy(Float32Array),
418+
VectorKind::F64 => self.alloc_copy(Float64Array),
419+
VectorKind::String => {
420+
let expr = ast::IncomingBindingExpressionAllocUtf8Str {
421+
alloc_func_name: self.alloc_func_name(),
422+
expr: Box::new(self.expr_get()),
423+
};
424+
self.webidl.push(DomString);
425+
self.bindings
426+
.push(NonstandardIncoming::Standard(expr.into()));
427+
}
428+
VectorKind::I64 | VectorKind::U64 => {
429+
let signed = match kind {
430+
VectorKind::I64 => true,
431+
_ => false,
432+
};
433+
self.bindings.push(NonstandardIncoming::AllocCopyInt64 {
434+
alloc_func_name: self.alloc_func_name(),
435+
expr: Box::new(self.expr_get()),
436+
signed,
437+
});
438+
self.webidl.push(Any);
439+
}
440+
VectorKind::Anyref => {
441+
self.bindings
442+
.push(NonstandardIncoming::AllocCopyAnyrefArray {
443+
alloc_func_name: self.alloc_func_name(),
444+
expr: Box::new(self.expr_get()),
445+
});
446+
self.webidl.push(Any);
447+
}
448+
}
449+
}
450+
448451
fn alloc_copy(&mut self, webidl: ast::WebidlScalarType) {
449452
let expr = ast::IncomingBindingExpressionAllocCopy {
450453
alloc_func_name: self.alloc_func_name(),

src/convert/slices.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,11 @@ macro_rules! vectors {
9494

9595
impl RefFromWasmAbi for [$t] {
9696
type Abi = WasmSlice;
97-
type Anchor = &'static [$t];
97+
type Anchor = Box<[$t]>;
9898

9999
#[inline]
100-
unsafe fn ref_from_abi(js: WasmSlice) -> &'static [$t] {
101-
slice::from_raw_parts(
102-
<*const $t>::from_abi(js.ptr),
103-
js.len as usize,
104-
)
100+
unsafe fn ref_from_abi(js: WasmSlice) -> Box<[$t]> {
101+
<Box<[$t]>>::from_abi(js)
105102
}
106103
}
107104

@@ -195,11 +192,11 @@ impl<'a> OptionIntoWasmAbi for &'a str {
195192

196193
impl RefFromWasmAbi for str {
197194
type Abi = <[u8] as RefFromWasmAbi>::Abi;
198-
type Anchor = &'static str;
195+
type Anchor = Box<str>;
199196

200197
#[inline]
201198
unsafe fn ref_from_abi(js: Self::Abi) -> Self::Anchor {
202-
str::from_utf8_unchecked(<[u8]>::ref_from_abi(js))
199+
mem::transmute::<Box<[u8]>, Box<str>>(<Box<[u8]>>::from_abi(js))
203200
}
204201
}
205202

0 commit comments

Comments
 (0)