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

View File

@ -47,15 +47,11 @@ pub enum NonstandardIncoming {
expr: Box<ast::IncomingBindingExpression>, expr: Box<ast::IncomingBindingExpression>,
}, },
/// JS is passing a typed slice of data into Rust. Currently this is /// A mutable slice of values going from JS to Rust, and after Rust finishes
/// implemented with a deallocation in the JS shim, hence a custom binding. /// the JS slice is updated with the current value of the slice.
/// MutableSlice {
/// TODO: we should move deallocation into Rust so we can use a vanilla and
/// standard webidl binding here.
Slice {
kind: VectorKind, kind: VectorKind,
val: ast::IncomingBindingExpression, val: ast::IncomingBindingExpression,
mutable: bool,
}, },
/// This is either a slice or `undefined` being passed into Rust. /// 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::Option(d) => self.process_option(d)?,
Descriptor::String | Descriptor::Vector(_) => { Descriptor::String | Descriptor::Vector(_) => {
use wasm_webidl_bindings::ast::WebidlScalarType::*;
let kind = arg.vector_kind().ok_or_else(|| { let kind = arg.vector_kind().ok_or_else(|| {
format_err!("unsupported argument type for calling Rust function from JS {:?}", arg) format_err!("unsupported argument type for calling Rust function from JS {:?}", arg)
})? ; })? ;
self.wasm.extend(&[ValType::I32; 2]); self.wasm.extend(&[ValType::I32; 2]);
match kind { self.alloc_copy_kind(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);
}
}
} }
// Can't be passed from JS to Rust yet // Can't be passed from JS to Rust yet
@ -309,12 +264,15 @@ impl IncomingBuilder {
) )
})?; })?;
self.wasm.extend(&[ValType::I32; 2]); self.wasm.extend(&[ValType::I32; 2]);
self.bindings.push(NonstandardIncoming::Slice { if mutable {
kind, self.bindings.push(NonstandardIncoming::MutableSlice {
val: self.expr_get(), kind,
mutable, val: self.expr_get(),
}); });
self.webidl.push(ast::WebidlScalarType::Any); self.webidl.push(ast::WebidlScalarType::Any);
} else {
self.alloc_copy_kind(kind)
}
} }
_ => bail!( _ => bail!(
"unsupported reference argument type for calling Rust function from JS: {:?}", "unsupported reference argument type for calling Rust function from JS: {:?}",
@ -445,6 +403,51 @@ impl IncomingBuilder {
"__wbindgen_malloc".to_string() "__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) { fn alloc_copy(&mut self, webidl: ast::WebidlScalarType) {
let expr = ast::IncomingBindingExpressionAllocCopy { let expr = ast::IncomingBindingExpressionAllocCopy {
alloc_func_name: self.alloc_func_name(), alloc_func_name: self.alloc_func_name(),

View File

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