Merge pull request #1626 from alexcrichton/more-standard

Update all non-mutable slices into Rust to use `AllocCopy`
This commit is contained in:
Alex Crichton 2019-06-25 17:09:34 +02:00 committed by GitHub
commit e106ca3b61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 65 deletions

View File

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

View File

@ -47,15 +47,11 @@ pub enum NonstandardIncoming {
expr: Box<ast::IncomingBindingExpression>,
},
/// JS is passing a typed slice of data into Rust. Currently this is
/// implemented with a deallocation in the JS shim, hence a custom binding.
///
/// TODO: we should move deallocation into Rust so we can use a vanilla and
/// standard webidl binding here.
Slice {
/// A mutable slice of values going from JS to Rust, and after Rust finishes
/// the JS slice is updated with the current value of the slice.
MutableSlice {
kind: VectorKind,
val: ast::IncomingBindingExpression,
mutable: bool,
},
/// This is either a slice or `undefined` being passed into Rust.
@ -216,52 +212,11 @@ impl IncomingBuilder {
Descriptor::Option(d) => self.process_option(d)?,
Descriptor::String | Descriptor::Vector(_) => {
use wasm_webidl_bindings::ast::WebidlScalarType::*;
let kind = arg.vector_kind().ok_or_else(|| {
format_err!("unsupported argument type for calling Rust function from JS {:?}", arg)
})? ;
self.wasm.extend(&[ValType::I32; 2]);
match kind {
VectorKind::I8 => self.alloc_copy(Int8Array),
VectorKind::U8 => self.alloc_copy(Uint8Array),
VectorKind::ClampedU8 => self.alloc_copy(Uint8ClampedArray),
VectorKind::I16 => self.alloc_copy(Int16Array),
VectorKind::U16 => self.alloc_copy(Uint16Array),
VectorKind::I32 => self.alloc_copy(Int32Array),
VectorKind::U32 => self.alloc_copy(Uint32Array),
VectorKind::F32 => self.alloc_copy(Float32Array),
VectorKind::F64 => self.alloc_copy(Float64Array),
VectorKind::String => {
let expr = ast::IncomingBindingExpressionAllocUtf8Str {
alloc_func_name: self.alloc_func_name(),
expr: Box::new(self.expr_get()),
};
self.webidl.push(DomString);
self.bindings
.push(NonstandardIncoming::Standard(expr.into()));
}
VectorKind::I64 | VectorKind::U64 => {
let signed = match kind {
VectorKind::I64 => true,
_ => false,
};
self.bindings.push(NonstandardIncoming::AllocCopyInt64 {
alloc_func_name: self.alloc_func_name(),
expr: Box::new(self.expr_get()),
signed,
});
self.webidl.push(Any);
}
VectorKind::Anyref => {
self.bindings
.push(NonstandardIncoming::AllocCopyAnyrefArray {
alloc_func_name: self.alloc_func_name(),
expr: Box::new(self.expr_get()),
});
self.webidl.push(Any);
}
}
self.alloc_copy_kind(kind)
}
// Can't be passed from JS to Rust yet
@ -309,12 +264,15 @@ impl IncomingBuilder {
)
})?;
self.wasm.extend(&[ValType::I32; 2]);
self.bindings.push(NonstandardIncoming::Slice {
kind,
val: self.expr_get(),
mutable,
});
self.webidl.push(ast::WebidlScalarType::Any);
if mutable {
self.bindings.push(NonstandardIncoming::MutableSlice {
kind,
val: self.expr_get(),
});
self.webidl.push(ast::WebidlScalarType::Any);
} else {
self.alloc_copy_kind(kind)
}
}
_ => bail!(
"unsupported reference argument type for calling Rust function from JS: {:?}",
@ -445,6 +403,51 @@ impl IncomingBuilder {
"__wbindgen_malloc".to_string()
}
fn alloc_copy_kind(&mut self, kind: VectorKind) {
use wasm_webidl_bindings::ast::WebidlScalarType::*;
match kind {
VectorKind::I8 => self.alloc_copy(Int8Array),
VectorKind::U8 => self.alloc_copy(Uint8Array),
VectorKind::ClampedU8 => self.alloc_copy(Uint8ClampedArray),
VectorKind::I16 => self.alloc_copy(Int16Array),
VectorKind::U16 => self.alloc_copy(Uint16Array),
VectorKind::I32 => self.alloc_copy(Int32Array),
VectorKind::U32 => self.alloc_copy(Uint32Array),
VectorKind::F32 => self.alloc_copy(Float32Array),
VectorKind::F64 => self.alloc_copy(Float64Array),
VectorKind::String => {
let expr = ast::IncomingBindingExpressionAllocUtf8Str {
alloc_func_name: self.alloc_func_name(),
expr: Box::new(self.expr_get()),
};
self.webidl.push(DomString);
self.bindings
.push(NonstandardIncoming::Standard(expr.into()));
}
VectorKind::I64 | VectorKind::U64 => {
let signed = match kind {
VectorKind::I64 => true,
_ => false,
};
self.bindings.push(NonstandardIncoming::AllocCopyInt64 {
alloc_func_name: self.alloc_func_name(),
expr: Box::new(self.expr_get()),
signed,
});
self.webidl.push(Any);
}
VectorKind::Anyref => {
self.bindings
.push(NonstandardIncoming::AllocCopyAnyrefArray {
alloc_func_name: self.alloc_func_name(),
expr: Box::new(self.expr_get()),
});
self.webidl.push(Any);
}
}
}
fn alloc_copy(&mut self, webidl: ast::WebidlScalarType) {
let expr = ast::IncomingBindingExpressionAllocCopy {
alloc_func_name: self.alloc_func_name(),

View File

@ -94,14 +94,11 @@ macro_rules! vectors {
impl RefFromWasmAbi for [$t] {
type Abi = WasmSlice;
type Anchor = &'static [$t];
type Anchor = Box<[$t]>;
#[inline]
unsafe fn ref_from_abi(js: WasmSlice) -> &'static [$t] {
slice::from_raw_parts(
<*const $t>::from_abi(js.ptr),
js.len as usize,
)
unsafe fn ref_from_abi(js: WasmSlice) -> Box<[$t]> {
<Box<[$t]>>::from_abi(js)
}
}
@ -195,11 +192,11 @@ impl<'a> OptionIntoWasmAbi for &'a str {
impl RefFromWasmAbi for str {
type Abi = <[u8] as RefFromWasmAbi>::Abi;
type Anchor = &'static str;
type Anchor = Box<str>;
#[inline]
unsafe fn ref_from_abi(js: Self::Abi) -> Self::Anchor {
str::from_utf8_unchecked(<[u8]>::ref_from_abi(js))
mem::transmute::<Box<[u8]>, Box<str>>(<Box<[u8]>>::from_abi(js))
}
}