mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-12-25 11:02:11 +03:00
Work with #![no_std]
contexts
This commit adds support for both `#![no_std]` in the wasm-bindgen runtime support (disabled by default with an on-by-default `std` feature). This also adds support to work and compile in the context of `#![no_std]` crates. Closes #146
This commit is contained in:
parent
792a8e132e
commit
748184ae66
@ -16,6 +16,10 @@ Easy support for interacting between JS and Rust.
|
||||
test = false
|
||||
doctest = false
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = []
|
||||
|
||||
[dependencies]
|
||||
wasm-bindgen-macro = { path = "crates/macro", version = "=0.2.4" }
|
||||
|
||||
|
@ -116,13 +116,22 @@ impl ToTokens for ast::Struct {
|
||||
}
|
||||
}
|
||||
|
||||
::wasm_bindgen::__wbindgen_if_not_std! {
|
||||
compile_error! {
|
||||
"exporting a class to JS requires the `std` feature to \
|
||||
be enabled in the `wasm-bindgen` crate"
|
||||
}
|
||||
}
|
||||
|
||||
impl ::wasm_bindgen::convert::IntoWasmAbi for #name {
|
||||
type Abi = u32;
|
||||
|
||||
fn into_abi(self, _extra: &mut ::wasm_bindgen::convert::Stack)
|
||||
-> u32
|
||||
{
|
||||
Box::into_raw(Box::new(::wasm_bindgen::__rt::WasmRefCell::new(self))) as u32
|
||||
use wasm_bindgen::__rt::std::boxed::Box;
|
||||
use wasm_bindgen::__rt::WasmRefCell;
|
||||
Box::into_raw(Box::new(WasmRefCell::new(self))) as u32
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,14 +141,49 @@ impl ToTokens for ast::Struct {
|
||||
unsafe fn from_abi(js: u32, _extra: &mut ::wasm_bindgen::convert::Stack)
|
||||
-> Self
|
||||
{
|
||||
let ptr = js as *mut ::wasm_bindgen::__rt::WasmRefCell<#name>;
|
||||
::wasm_bindgen::__rt::assert_not_null(ptr);
|
||||
use wasm_bindgen::__rt::std::boxed::Box;
|
||||
use wasm_bindgen::__rt::{assert_not_null, WasmRefCell};
|
||||
|
||||
let ptr = js as *mut WasmRefCell<#name>;
|
||||
assert_not_null(ptr);
|
||||
let js = Box::from_raw(ptr);
|
||||
js.borrow_mut(); // make sure no one's borrowing
|
||||
js.into_inner()
|
||||
}
|
||||
}
|
||||
|
||||
impl ::wasm_bindgen::__rt::core::convert::From<#name> for
|
||||
::wasm_bindgen::JsValue
|
||||
{
|
||||
fn from(value: #name) -> Self {
|
||||
let ptr = ::wasm_bindgen::convert::IntoWasmAbi::into_abi(
|
||||
value,
|
||||
unsafe { &mut ::wasm_bindgen::convert::GlobalStack::new() },
|
||||
);
|
||||
|
||||
#[wasm_import_module = "__wbindgen_placeholder__"]
|
||||
extern {
|
||||
fn #new_fn(ptr: u32) -> u32;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
<::wasm_bindgen::JsValue as ::wasm_bindgen::convert::FromWasmAbi>
|
||||
::from_abi(
|
||||
#new_fn(ptr),
|
||||
&mut ::wasm_bindgen::convert::GlobalStack::new(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn #free_fn(ptr: u32) {
|
||||
<#name as ::wasm_bindgen::convert::FromWasmAbi>::from_abi(
|
||||
ptr,
|
||||
&mut ::wasm_bindgen::convert::GlobalStack::new(),
|
||||
);
|
||||
}
|
||||
|
||||
impl ::wasm_bindgen::convert::RefFromWasmAbi for #name {
|
||||
type Abi = u32;
|
||||
type Anchor = ::wasm_bindgen::__rt::Ref<'static, #name>;
|
||||
@ -167,36 +211,6 @@ impl ToTokens for ast::Struct {
|
||||
(*js).borrow_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::convert::From<#name> for ::wasm_bindgen::JsValue {
|
||||
fn from(value: #name) -> Self {
|
||||
let ptr = ::wasm_bindgen::convert::IntoWasmAbi::into_abi(
|
||||
value,
|
||||
unsafe { &mut ::wasm_bindgen::convert::GlobalStack::new() },
|
||||
);
|
||||
|
||||
#[wasm_import_module = "__wbindgen_placeholder__"]
|
||||
extern {
|
||||
fn #new_fn(ptr: u32) -> u32;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
<::wasm_bindgen::JsValue as ::wasm_bindgen::convert::FromWasmAbi>
|
||||
::from_abi(
|
||||
#new_fn(ptr),
|
||||
&mut ::wasm_bindgen::convert::GlobalStack::new(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn #free_fn(ptr: u32) {
|
||||
<#name as ::wasm_bindgen::convert::FromWasmAbi>::from_abi(
|
||||
ptr,
|
||||
&mut ::wasm_bindgen::convert::GlobalStack::new(),
|
||||
);
|
||||
}
|
||||
}).to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
@ -419,7 +433,7 @@ impl ToTokens for ast::ImportType {
|
||||
impl ::wasm_bindgen::convert::RefFromWasmAbi for #name {
|
||||
type Abi = <::wasm_bindgen::JsValue as
|
||||
::wasm_bindgen::convert::RefFromWasmAbi>::Abi;
|
||||
type Anchor = ::std::mem::ManuallyDrop<#name>;
|
||||
type Anchor = ::wasm_bindgen::__rt::core::mem::ManuallyDrop<#name>;
|
||||
|
||||
unsafe fn ref_from_abi(
|
||||
js: Self::Abi,
|
||||
@ -427,8 +441,8 @@ impl ToTokens for ast::ImportType {
|
||||
) -> Self::Anchor {
|
||||
let tmp = <::wasm_bindgen::JsValue as ::wasm_bindgen::convert::RefFromWasmAbi>
|
||||
::ref_from_abi(js, extra);
|
||||
::std::mem::ManuallyDrop::new(#name {
|
||||
obj: ::std::mem::ManuallyDrop::into_inner(tmp),
|
||||
::wasm_bindgen::__rt::core::mem::ManuallyDrop::new(#name {
|
||||
obj: ::wasm_bindgen::__rt::core::mem::ManuallyDrop::into_inner(tmp),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -702,7 +716,7 @@ impl ToTokens for ast::ImportStatic {
|
||||
}
|
||||
}
|
||||
::wasm_bindgen::JsStatic {
|
||||
__inner: ::std::cell::UnsafeCell::new(None),
|
||||
__inner: ::wasm_bindgen::__rt::core::cell::UnsafeCell::new(None),
|
||||
__init: init,
|
||||
}
|
||||
};
|
||||
|
@ -119,9 +119,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
||||
self.finally(&format!("\
|
||||
wasm.__wbindgen_free(ptr{i}, len{i} * {size});\n\
|
||||
", i = i, size = kind.size()));
|
||||
self.cx.required_internal_exports.insert(
|
||||
"__wbindgen_free",
|
||||
);
|
||||
self.cx.require_internal_export("__wbindgen_free");
|
||||
}
|
||||
self.rust_arguments.push(format!("ptr{}", i));
|
||||
return
|
||||
@ -216,7 +214,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
||||
self.ret_ty = ty.js_ty().to_string();
|
||||
let f = self.cx.expose_get_vector_from_wasm(ty);
|
||||
self.cx.expose_get_global_argument();
|
||||
self.cx.required_internal_exports.insert("__wbindgen_free");
|
||||
self.cx.require_internal_export("__wbindgen_free");
|
||||
self.ret_expr = format!("\
|
||||
const ret = RET;\n\
|
||||
const len = getGlobalArgument(0);\n\
|
||||
|
@ -62,6 +62,22 @@ impl<'a> Context<'a> {
|
||||
self.global(&global);
|
||||
}
|
||||
|
||||
fn require_internal_export(&mut self, name: &'static str) {
|
||||
if !self.required_internal_exports.insert(name) {
|
||||
return
|
||||
}
|
||||
if let Some(s) = self.module.export_section() {
|
||||
if s.entries().iter().any(|e| e.field() == name) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
panic!("\n\nthe exported function `{}` is required to generate bindings \
|
||||
but it was not found in the wasm file, perhaps the `std` feature \
|
||||
of the `wasm-bindgen` crate needs to be enabled?\n\n",
|
||||
name);
|
||||
}
|
||||
|
||||
pub fn finalize(&mut self, module_name: &str) -> (String, String) {
|
||||
self.unexport_unused_internal_exports();
|
||||
self.gc();
|
||||
@ -642,7 +658,7 @@ impl<'a> Context<'a> {
|
||||
if !self.exposed_globals.insert("pass_string_to_wasm") {
|
||||
return;
|
||||
}
|
||||
self.required_internal_exports.insert("__wbindgen_malloc");
|
||||
self.require_internal_export("__wbindgen_malloc");
|
||||
self.expose_text_encoder();
|
||||
self.expose_uint8_memory();
|
||||
let debug = if self.config.debug {
|
||||
@ -668,7 +684,7 @@ impl<'a> Context<'a> {
|
||||
if !self.exposed_globals.insert("pass_array8_to_wasm") {
|
||||
return;
|
||||
}
|
||||
self.required_internal_exports.insert("__wbindgen_malloc");
|
||||
self.require_internal_export("__wbindgen_malloc");
|
||||
self.expose_uint8_memory();
|
||||
self.global(&format!("
|
||||
function passArray8ToWasm(arg) {{
|
||||
@ -683,7 +699,7 @@ impl<'a> Context<'a> {
|
||||
if !self.exposed_globals.insert("pass_array16_to_wasm") {
|
||||
return;
|
||||
}
|
||||
self.required_internal_exports.insert("__wbindgen_malloc");
|
||||
self.require_internal_export("__wbindgen_malloc");
|
||||
self.expose_uint16_memory();
|
||||
self.global(&format!("
|
||||
function passArray16ToWasm(arg) {{
|
||||
@ -698,7 +714,7 @@ impl<'a> Context<'a> {
|
||||
if !self.exposed_globals.insert("pass_array32_to_wasm") {
|
||||
return;
|
||||
}
|
||||
self.required_internal_exports.insert("__wbindgen_malloc");
|
||||
self.require_internal_export("__wbindgen_malloc");
|
||||
self.expose_uint32_memory();
|
||||
self.global(&format!("
|
||||
function passArray32ToWasm(arg) {{
|
||||
@ -713,7 +729,7 @@ impl<'a> Context<'a> {
|
||||
if !self.exposed_globals.insert("pass_array_f32_to_wasm") {
|
||||
return;
|
||||
}
|
||||
self.required_internal_exports.insert("__wbindgen_malloc");
|
||||
self.require_internal_export("__wbindgen_malloc");
|
||||
self.global(&format!("
|
||||
function passArrayF32ToWasm(arg) {{
|
||||
const ptr = wasm.__wbindgen_malloc(arg.length * 4);
|
||||
@ -727,7 +743,7 @@ impl<'a> Context<'a> {
|
||||
if !self.exposed_globals.insert("pass_array_f64_to_wasm") {
|
||||
return;
|
||||
}
|
||||
self.required_internal_exports.insert("__wbindgen_malloc");
|
||||
self.require_internal_export("__wbindgen_malloc");
|
||||
self.global(&format!("
|
||||
function passArrayF64ToWasm(arg) {{
|
||||
const ptr = wasm.__wbindgen_malloc(arg.length * 8);
|
||||
@ -1172,7 +1188,7 @@ impl<'a> Context<'a> {
|
||||
if !self.exposed_globals.insert("global_argument_ptr") {
|
||||
return;
|
||||
}
|
||||
self.required_internal_exports.insert("__wbindgen_global_argument_ptr");
|
||||
self.require_internal_export("__wbindgen_global_argument_ptr");
|
||||
self.global("
|
||||
let cachedGlobalArgumentPtr = null;
|
||||
function globalArgumentPtr() {
|
||||
|
@ -91,9 +91,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
self.prelude(&format!("\
|
||||
wasm.__wbindgen_free(arg{0}, len{0} * {size});\
|
||||
", i, size = ty.size()));
|
||||
self.cx.required_internal_exports.insert(
|
||||
"__wbindgen_free"
|
||||
);
|
||||
self.cx.require_internal_export("__wbindgen_free");
|
||||
}
|
||||
self.js_arguments.push(format!("v{}", i));
|
||||
return
|
||||
|
@ -7,6 +7,7 @@
|
||||
use std::cell::UnsafeCell;
|
||||
use std::marker::Unsize;
|
||||
use std::mem::{self, ManuallyDrop};
|
||||
use std::prelude::v1::*;
|
||||
|
||||
use JsValue;
|
||||
use convert::*;
|
||||
|
@ -1,14 +1,17 @@
|
||||
//! This is mostly an internal module, no stability guarantees are provied. Use
|
||||
//! at your own risk.
|
||||
|
||||
use std::mem::{self, ManuallyDrop};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::slice;
|
||||
use std::str;
|
||||
use core::mem::{self, ManuallyDrop};
|
||||
use core::ops::{Deref, DerefMut};
|
||||
use core::slice;
|
||||
use core::str;
|
||||
|
||||
use {JsValue, throw};
|
||||
use describe::*;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use std::prelude::v1::*;
|
||||
|
||||
#[derive(PartialEq, Eq, Copy, Clone)]
|
||||
pub struct Descriptor {
|
||||
#[doc(hidden)]
|
||||
@ -132,6 +135,7 @@ impl<T> FromWasmAbi for *mut T {
|
||||
|
||||
macro_rules! vectors {
|
||||
($($t:ident)*) => ($(
|
||||
#[cfg(feature = "std")]
|
||||
impl IntoWasmAbi for Box<[$t]> {
|
||||
type Abi = u32;
|
||||
|
||||
@ -144,6 +148,7 @@ macro_rules! vectors {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl FromWasmAbi for Box<[$t]> {
|
||||
type Abi = u32;
|
||||
|
||||
@ -183,34 +188,36 @@ vectors! {
|
||||
u8 i8 u16 i16 u32 i32 f32 f64
|
||||
}
|
||||
|
||||
impl<T> IntoWasmAbi for Vec<T> where Box<[T]>: IntoWasmAbi {
|
||||
type Abi = <Box<[T]> as IntoWasmAbi>::Abi;
|
||||
fn into_abi(self, extra: &mut Stack) -> Self::Abi {
|
||||
self.into_boxed_slice().into_abi(extra)
|
||||
if_std! {
|
||||
impl<T> IntoWasmAbi for Vec<T> where Box<[T]>: IntoWasmAbi {
|
||||
type Abi = <Box<[T]> as IntoWasmAbi>::Abi;
|
||||
fn into_abi(self, extra: &mut Stack) -> Self::Abi {
|
||||
self.into_boxed_slice().into_abi(extra)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FromWasmAbi for Vec<T> where Box<[T]>: FromWasmAbi {
|
||||
type Abi = <Box<[T]> as FromWasmAbi>::Abi;
|
||||
impl<T> FromWasmAbi for Vec<T> where Box<[T]>: FromWasmAbi {
|
||||
type Abi = <Box<[T]> as FromWasmAbi>::Abi;
|
||||
|
||||
unsafe fn from_abi(js: Self::Abi, extra: &mut Stack) -> Self {
|
||||
<Box<[T]>>::from_abi(js, extra).into()
|
||||
unsafe fn from_abi(js: Self::Abi, extra: &mut Stack) -> Self {
|
||||
<Box<[T]>>::from_abi(js, extra).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoWasmAbi for String {
|
||||
type Abi = u32;
|
||||
impl IntoWasmAbi for String {
|
||||
type Abi = u32;
|
||||
|
||||
fn into_abi(self, extra: &mut Stack) -> u32 {
|
||||
self.into_bytes().into_abi(extra)
|
||||
fn into_abi(self, extra: &mut Stack) -> u32 {
|
||||
self.into_bytes().into_abi(extra)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromWasmAbi for String {
|
||||
type Abi = u32;
|
||||
impl FromWasmAbi for String {
|
||||
type Abi = u32;
|
||||
|
||||
unsafe fn from_abi(js: u32, extra: &mut Stack) -> Self {
|
||||
String::from_utf8_unchecked(<Vec<u8>>::from_abi(js, extra))
|
||||
unsafe fn from_abi(js: u32, extra: &mut Stack) -> Self {
|
||||
String::from_utf8_unchecked(<Vec<u8>>::from_abi(js, extra))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -265,25 +272,27 @@ impl RefFromWasmAbi for JsValue {
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoWasmAbi for Box<[JsValue]> {
|
||||
type Abi = u32;
|
||||
if_std! {
|
||||
impl IntoWasmAbi for Box<[JsValue]> {
|
||||
type Abi = u32;
|
||||
|
||||
fn into_abi(self, extra: &mut Stack) -> u32 {
|
||||
let ptr = self.as_ptr();
|
||||
let len = self.len();
|
||||
mem::forget(self);
|
||||
extra.push(len as u32);
|
||||
ptr.into_abi(extra)
|
||||
fn into_abi(self, extra: &mut Stack) -> u32 {
|
||||
let ptr = self.as_ptr();
|
||||
let len = self.len();
|
||||
mem::forget(self);
|
||||
extra.push(len as u32);
|
||||
ptr.into_abi(extra)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromWasmAbi for Box<[JsValue]> {
|
||||
type Abi = u32;
|
||||
impl FromWasmAbi for Box<[JsValue]> {
|
||||
type Abi = u32;
|
||||
|
||||
unsafe fn from_abi(js: u32, extra: &mut Stack) -> Self {
|
||||
let ptr = <*mut JsValue>::from_abi(js, extra);
|
||||
let len = extra.pop() as usize;
|
||||
Vec::from_raw_parts(ptr, len, len).into_boxed_slice()
|
||||
unsafe fn from_abi(js: u32, extra: &mut Stack) -> Self {
|
||||
let ptr = <*mut JsValue>::from_abi(js, extra);
|
||||
let len = extra.pop() as usize;
|
||||
Vec::from_raw_parts(ptr, len, len).into_boxed_slice()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,6 @@ simple! {
|
||||
f64 => F64
|
||||
bool => BOOLEAN
|
||||
str => STRING
|
||||
String => STRING
|
||||
JsValue => ANYREF
|
||||
}
|
||||
|
||||
@ -105,16 +104,24 @@ impl<'a, T: WasmDescribe + ?Sized> WasmDescribe for &'a mut T {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: WasmDescribe> WasmDescribe for Box<[T]> {
|
||||
fn describe() {
|
||||
inform(VECTOR);
|
||||
T::describe();
|
||||
}
|
||||
}
|
||||
if_std! {
|
||||
use std::prelude::v1::*;
|
||||
|
||||
impl<T> WasmDescribe for Vec<T> where Box<[T]>: WasmDescribe {
|
||||
fn describe() {
|
||||
<Box<[T]>>::describe();
|
||||
impl WasmDescribe for String {
|
||||
fn describe() { inform(STRING) }
|
||||
}
|
||||
|
||||
impl<T: WasmDescribe> WasmDescribe for Box<[T]> {
|
||||
fn describe() {
|
||||
inform(VECTOR);
|
||||
T::describe();
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> WasmDescribe for Vec<T> where Box<[T]>: WasmDescribe {
|
||||
fn describe() {
|
||||
<Box<[T]>>::describe();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
86
src/lib.rs
86
src/lib.rs
@ -6,15 +6,22 @@
|
||||
//! interface.
|
||||
|
||||
#![feature(use_extern_macros, wasm_import_module, try_reserve, unsize)]
|
||||
#![no_std]
|
||||
|
||||
extern crate wasm_bindgen_macro;
|
||||
|
||||
use std::cell::UnsafeCell;
|
||||
use std::ops::Deref;
|
||||
use std::ptr;
|
||||
use core::cell::UnsafeCell;
|
||||
use core::ops::Deref;
|
||||
use core::ptr;
|
||||
|
||||
use convert::FromWasmAbi;
|
||||
|
||||
macro_rules! if_std {
|
||||
($($i:item)*) => ($(
|
||||
#[cfg(feature = "std")] $i
|
||||
)*)
|
||||
}
|
||||
|
||||
/// A module which is typically glob imported from:
|
||||
///
|
||||
/// ```
|
||||
@ -23,13 +30,21 @@ use convert::FromWasmAbi;
|
||||
pub mod prelude {
|
||||
pub use wasm_bindgen_macro::wasm_bindgen;
|
||||
pub use JsValue;
|
||||
pub use closure::Closure;
|
||||
|
||||
if_std! {
|
||||
pub use closure::Closure;
|
||||
}
|
||||
}
|
||||
|
||||
pub mod convert;
|
||||
pub mod closure;
|
||||
pub mod describe;
|
||||
|
||||
if_std! {
|
||||
extern crate std;
|
||||
use std::prelude::v1::*;
|
||||
pub mod closure;
|
||||
}
|
||||
|
||||
/// Representation of an object owned by JS.
|
||||
///
|
||||
/// A `JsValue` doesn't actually live in Rust right now but actually in a table
|
||||
@ -136,6 +151,7 @@ impl JsValue {
|
||||
///
|
||||
/// If this JS value is not an instance of a string or if it's not valid
|
||||
/// utf-8 then this returns `None`.
|
||||
#[cfg(feature = "std")]
|
||||
pub fn as_string(&self) -> Option<String> {
|
||||
unsafe {
|
||||
let mut len = 0;
|
||||
@ -192,9 +208,11 @@ impl<'a> From<&'a str> for JsValue {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a String> for JsValue {
|
||||
fn from(s: &'a String) -> JsValue {
|
||||
JsValue::from_str(s)
|
||||
if_std! {
|
||||
impl<'a> From<&'a String> for JsValue {
|
||||
fn from(s: &'a String) -> JsValue {
|
||||
JsValue::from_str(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -321,9 +339,23 @@ pub fn throw(s: &str) -> ! {
|
||||
|
||||
#[doc(hidden)]
|
||||
pub mod __rt {
|
||||
use std::cell::{Cell, UnsafeCell};
|
||||
use std::mem;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use core::cell::{Cell, UnsafeCell};
|
||||
use core::ops::{Deref, DerefMut};
|
||||
pub extern crate core;
|
||||
#[cfg(feature = "std")]
|
||||
pub extern crate std;
|
||||
|
||||
#[macro_export]
|
||||
#[cfg(feature = "std")]
|
||||
macro_rules! __wbindgen_if_not_std {
|
||||
($($i:item)*) => ()
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
#[cfg(not(feature = "std"))]
|
||||
macro_rules! __wbindgen_if_not_std {
|
||||
($($i:item)*) => ($($i)*)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn assert_not_null<T>(s: *mut T) {
|
||||
@ -457,20 +489,26 @@ pub mod __rt {
|
||||
unsafe aliasing in rust");
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn __wbindgen_malloc(size: usize) -> *mut u8 {
|
||||
let mut ret = Vec::new();
|
||||
if ret.try_reserve_exact(size).is_err() {
|
||||
super::throw("invalid malloc request");
|
||||
}
|
||||
let ptr = ret.as_mut_ptr();
|
||||
mem::forget(ret);
|
||||
return ptr
|
||||
}
|
||||
if_std! {
|
||||
use std::prelude::v1::*;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn __wbindgen_free(ptr: *mut u8, size: usize) {
|
||||
drop(Vec::<u8>::from_raw_parts(ptr, 0, size));
|
||||
#[no_mangle]
|
||||
pub extern fn __wbindgen_malloc(size: usize) -> *mut u8 {
|
||||
use core::mem;
|
||||
|
||||
let mut ret = Vec::new();
|
||||
if ret.try_reserve_exact(size).is_err() {
|
||||
super::throw("invalid malloc request");
|
||||
}
|
||||
let ptr = ret.as_mut_ptr();
|
||||
mem::forget(ret);
|
||||
return ptr
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn __wbindgen_free(ptr: *mut u8, size: usize) {
|
||||
drop(Vec::<u8>::from_raw_parts(ptr, 0, size));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn link_this_library() {}
|
||||
|
@ -15,6 +15,7 @@ struct Project {
|
||||
files: Vec<(String, String)>,
|
||||
debug: bool,
|
||||
node: bool,
|
||||
no_std: bool,
|
||||
}
|
||||
|
||||
fn project() -> Project {
|
||||
@ -25,6 +26,7 @@ fn project() -> Project {
|
||||
Project {
|
||||
debug: true,
|
||||
node: false,
|
||||
no_std: false,
|
||||
files: vec![
|
||||
("Cargo.toml".to_string(), format!(r#"
|
||||
[package]
|
||||
@ -40,8 +42,7 @@ fn project() -> Project {
|
||||
# XXX: It is important that `[dependencies]` is the last section
|
||||
# here, so that `add_local_dependency` functions correctly!
|
||||
[dependencies]
|
||||
wasm-bindgen = {{ path = '{}' }}
|
||||
"#, IDX.with(|x| *x), dir.display())),
|
||||
"#, IDX.with(|x| *x))),
|
||||
|
||||
("Cargo.lock".to_string(), lockfile),
|
||||
|
||||
@ -138,6 +139,11 @@ impl Project {
|
||||
self
|
||||
}
|
||||
|
||||
fn no_std(&mut self, no_std: bool) -> &mut Project {
|
||||
self.no_std = no_std;
|
||||
self
|
||||
}
|
||||
|
||||
fn add_local_dependency(&mut self, name: &str, path: &str) -> &mut Project {
|
||||
{
|
||||
let cargo_toml = self.files
|
||||
@ -145,14 +151,28 @@ impl Project {
|
||||
.find(|f| f.0 == "Cargo.toml")
|
||||
.expect("should have Cargo.toml file!");
|
||||
cargo_toml.1.push_str(name);
|
||||
cargo_toml.1.push_str(" = { path = \"");
|
||||
cargo_toml.1.push_str(" = { path = '");
|
||||
cargo_toml.1.push_str(path);
|
||||
cargo_toml.1.push_str("\" }");
|
||||
cargo_toml.1.push_str("' }\n");
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn test(&mut self) {
|
||||
{
|
||||
let cargo_toml = self.files
|
||||
.iter_mut()
|
||||
.find(|f| f.0 == "Cargo.toml")
|
||||
.expect("should have Cargo.toml file!");
|
||||
cargo_toml.1.push_str("wasm-bindgen = { path = '");
|
||||
cargo_toml.1.push_str(env!("CARGO_MANIFEST_DIR"));
|
||||
if self.no_std {
|
||||
cargo_toml.1.push_str("', default-features = false");
|
||||
} else {
|
||||
cargo_toml.1.push_str("'");
|
||||
}
|
||||
cargo_toml.1.push_str(" }\n");
|
||||
}
|
||||
let root = root();
|
||||
drop(fs::remove_dir_all(&root));
|
||||
for &(ref file, ref contents) in self.files.iter() {
|
||||
|
@ -201,3 +201,89 @@ fn other_exports() {
|
||||
"#)
|
||||
.test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_std() {
|
||||
project()
|
||||
.no_std(true)
|
||||
.file("src/lib.rs", r#"
|
||||
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
|
||||
#![no_std]
|
||||
#![allow(dead_code)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
extern crate std as _some_other_name;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
fn test(a: &str);
|
||||
|
||||
type Js;
|
||||
#[wasm_bindgen(constructor)]
|
||||
fn new() -> Js;
|
||||
#[wasm_bindgen(method)]
|
||||
fn init(this: &Js);
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn foo(_a: u32) {}
|
||||
"#)
|
||||
.file("test.ts", r#"
|
||||
import * as wasm from "./out_bg";
|
||||
|
||||
export function test() {
|
||||
// mostly just testing the project compiles here
|
||||
wasm.foo(1);
|
||||
}
|
||||
"#)
|
||||
.test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_std_class() {
|
||||
project()
|
||||
.file("src/lib.rs", r#"
|
||||
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
|
||||
#![no_std]
|
||||
#![allow(dead_code)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
extern crate std as _some_other_name;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
fn test(a: &str);
|
||||
|
||||
type Js;
|
||||
#[wasm_bindgen(constructor)]
|
||||
fn new() -> Js;
|
||||
#[wasm_bindgen(method, structural)]
|
||||
fn init(this: &Js);
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn foo(_a: u32) {}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct A {}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl A {
|
||||
pub fn foo(&self) {}
|
||||
pub fn bar(&mut self) {}
|
||||
}
|
||||
"#)
|
||||
.file("test.ts", r#"
|
||||
import * as wasm from "./out_bg";
|
||||
|
||||
export function test() {
|
||||
// mostly just testing the project compiles here
|
||||
wasm.foo(1);
|
||||
}
|
||||
"#)
|
||||
.test();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user