mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-12-25 19:11:45 +03:00
Merge remote-tracking branch 'origin/master' into webidl_partial_mixins
This commit is contained in:
commit
0c908bb951
@ -42,6 +42,7 @@ pub enum ImportKind {
|
||||
Static(ImportStatic),
|
||||
Type(ImportType),
|
||||
Enum(ImportEnum),
|
||||
Const(Const),
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
|
||||
@ -174,6 +175,24 @@ pub struct TypeAlias {
|
||||
pub src: syn::Type,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
|
||||
pub struct Const {
|
||||
pub vis: syn::Visibility,
|
||||
pub name: Ident,
|
||||
pub interface_name: Ident,
|
||||
pub ty: syn::Type,
|
||||
pub value: ConstValue,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
|
||||
/// same as webidl::ast::ConstValue
|
||||
pub enum ConstValue {
|
||||
BooleanLiteral(bool),
|
||||
FloatLiteral(f64),
|
||||
IntegerLiteral(i64),
|
||||
Null,
|
||||
}
|
||||
|
||||
impl Program {
|
||||
pub(crate) fn shared(&self) -> shared::Program {
|
||||
shared::Program {
|
||||
@ -293,6 +312,7 @@ impl ImportKind {
|
||||
ImportKind::Static(_) => false,
|
||||
ImportKind::Type(_) => false,
|
||||
ImportKind::Enum(_) => false,
|
||||
ImportKind::Const(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,6 +322,7 @@ impl ImportKind {
|
||||
ImportKind::Static(ref f) => shared::ImportKind::Static(f.shared()),
|
||||
ImportKind::Type(ref f) => shared::ImportKind::Type(f.shared()),
|
||||
ImportKind::Enum(ref f) => shared::ImportKind::Enum(f.shared()),
|
||||
ImportKind::Const(ref f) => shared::ImportKind::Const(f.shared()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -404,3 +425,9 @@ impl StructField {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Const {
|
||||
fn shared(&self) -> shared::Const {
|
||||
shared::Const {}
|
||||
}
|
||||
}
|
||||
|
@ -501,6 +501,7 @@ impl ToTokens for ast::ImportKind {
|
||||
ast::ImportKind::Static(ref s) => s.to_tokens(tokens),
|
||||
ast::ImportKind::Type(ref t) => t.to_tokens(tokens),
|
||||
ast::ImportKind::Enum(ref e) => e.to_tokens(tokens),
|
||||
ast::ImportKind::Const(ref c) => c.to_tokens(tokens),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -842,6 +843,7 @@ impl<'a> ToTokens for DescribeImport<'a> {
|
||||
ast::ImportKind::Static(_) => return,
|
||||
ast::ImportKind::Type(_) => return,
|
||||
ast::ImportKind::Enum(_) => return,
|
||||
ast::ImportKind::Const(_) => return,
|
||||
};
|
||||
let describe_name = format!("__wbindgen_describe_{}", f.shim);
|
||||
let describe_name = Ident::new(&describe_name, Span::call_site());
|
||||
@ -958,3 +960,41 @@ impl ToTokens for ast::TypeAlias {
|
||||
}).to_tokens(into);
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for ast::Const {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
use ast::ConstValue::*;
|
||||
|
||||
let vis = &self.vis;
|
||||
let name = &self.name;
|
||||
let interface_name = &self.interface_name;
|
||||
let ty = &self.ty;
|
||||
|
||||
let value: TokenStream = match self.value {
|
||||
BooleanLiteral(false) => quote!(false),
|
||||
BooleanLiteral(true) => quote!(true),
|
||||
// the actual type is unknown because of typedefs
|
||||
// so we cannot use std::fxx::INFINITY
|
||||
// but we can use type inference
|
||||
FloatLiteral(f) if f.is_infinite() && f.is_sign_positive() => quote!(1.0 / 0.0),
|
||||
FloatLiteral(f) if f.is_infinite() && f.is_sign_negative() => quote!(-1.0 / 0.0),
|
||||
FloatLiteral(f) if f.is_nan() => quote!(0.0 / 0.0),
|
||||
// again no suffix
|
||||
// panics on +-inf, nan
|
||||
FloatLiteral(f) => {
|
||||
let f = Literal::f64_unsuffixed(f);
|
||||
quote!(#f)
|
||||
},
|
||||
IntegerLiteral(i) => {
|
||||
let i = Literal::i64_unsuffixed(i);
|
||||
quote!(#i)
|
||||
},
|
||||
Null => unimplemented!(),
|
||||
};
|
||||
(quote! {
|
||||
impl #interface_name {
|
||||
#vis const #name: #ty = #value;
|
||||
}
|
||||
}).to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
|
@ -106,6 +106,7 @@ impl ImportedTypes for ast::ImportKind {
|
||||
ast::ImportKind::Function(fun) => fun.imported_types(f),
|
||||
ast::ImportKind::Type(ty) => ty.imported_types(f),
|
||||
ast::ImportKind::Enum(enm) => enm.imported_types(f),
|
||||
ast::ImportKind::Const(c) => c.imported_types(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -229,6 +230,15 @@ impl ImportedTypes for ast::TypeAlias {
|
||||
}
|
||||
}
|
||||
|
||||
impl ImportedTypes for ast::Const {
|
||||
fn imported_types<F>(&self, f: &mut F)
|
||||
where
|
||||
F: FnMut(&Ident, ImportedTypeKind),
|
||||
{
|
||||
self.ty.imported_types(f);
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove any methods, statics, &c, that reference types that are *not*
|
||||
/// defined.
|
||||
pub trait RemoveUndefinedImports {
|
||||
|
@ -19,5 +19,5 @@ serde_derive = "1.0"
|
||||
serde_json = "1.0"
|
||||
tempfile = "3.0"
|
||||
wasm-bindgen-shared = { path = "../shared", version = '=0.2.11' }
|
||||
wasm-gc-api = "0.1"
|
||||
wasm-gc-api = "0.1.8"
|
||||
wasmi = "0.3"
|
||||
|
@ -1580,6 +1580,7 @@ impl<'a> Context<'a> {
|
||||
let wasm_bytes = parity_wasm::serialize(module)?;
|
||||
let bytes = wasm_gc::Config::new()
|
||||
.demangle(self.config.demangle)
|
||||
.keep_debug(self.config.keep_debug || self.config.debug)
|
||||
.gc(&wasm_bytes)?;
|
||||
*self.module = deserialize_buffer(&bytes)?;
|
||||
Ok(())
|
||||
@ -1757,6 +1758,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
}
|
||||
shared::ImportKind::Type(_) => {}
|
||||
shared::ImportKind::Enum(_) => {}
|
||||
shared::ImportKind::Const(_) => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ pub struct Bindgen {
|
||||
debug: bool,
|
||||
typescript: bool,
|
||||
demangle: bool,
|
||||
keep_debug: bool,
|
||||
}
|
||||
|
||||
impl Bindgen {
|
||||
@ -45,6 +46,7 @@ impl Bindgen {
|
||||
debug: false,
|
||||
typescript: false,
|
||||
demangle: true,
|
||||
keep_debug: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,6 +95,11 @@ impl Bindgen {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn keep_debug(&mut self, keep_debug: bool) -> &mut Bindgen {
|
||||
self.keep_debug = keep_debug;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn generate<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
|
||||
self._generate(path.as_ref())
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ Options:
|
||||
--no-typescript Don't emit a *.d.ts file
|
||||
--debug Include otherwise-extraneous debug checks in output
|
||||
--no-demangle Don't demangle Rust symbol names
|
||||
--keep-debug Keep debug sections in wasm files
|
||||
-V --version Print the version number of wasm-bindgen
|
||||
";
|
||||
|
||||
@ -47,6 +48,7 @@ struct Args {
|
||||
flag_version: bool,
|
||||
flag_no_demangle: bool,
|
||||
flag_no_modules_global: Option<String>,
|
||||
flag_keep_debug: bool,
|
||||
arg_input: Option<PathBuf>,
|
||||
}
|
||||
|
||||
@ -85,6 +87,7 @@ fn rmain(args: &Args) -> Result<(), Error> {
|
||||
.no_modules(args.flag_no_modules)
|
||||
.debug(args.flag_debug)
|
||||
.demangle(!args.flag_no_demangle)
|
||||
.keep_debug(args.flag_keep_debug)
|
||||
.typescript(typescript);
|
||||
if let Some(ref name) = args.flag_no_modules_global {
|
||||
b.no_modules_global(name);
|
||||
|
@ -34,6 +34,7 @@ pub enum ImportKind {
|
||||
Static(ImportStatic),
|
||||
Type(ImportType),
|
||||
Enum(ImportEnum),
|
||||
Const(Const)
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
@ -124,6 +125,9 @@ pub struct StructField {
|
||||
pub comments: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Const {}
|
||||
|
||||
pub fn new_function(struct_name: &str) -> String {
|
||||
let mut name = format!("__wbg_");
|
||||
name.extend(struct_name.chars().flat_map(|s| s.to_lowercase()));
|
||||
|
33
crates/web-sys/tests/all/headers.rs
Normal file
33
crates/web-sys/tests/all/headers.rs
Normal file
@ -0,0 +1,33 @@
|
||||
use super::websys_project;
|
||||
|
||||
#[test]
|
||||
fn headers() {
|
||||
websys_project()
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(proc_macro, wasm_custom_section)]
|
||||
extern crate wasm_bindgen;
|
||||
use wasm_bindgen::prelude::*;
|
||||
extern crate web_sys;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn test_headers(_headers: &web_sys::Headers) {
|
||||
// empty for now...
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"test.js",
|
||||
r#"
|
||||
import * as assert from "assert";
|
||||
import * as wasm from "./out";
|
||||
|
||||
export function test() {
|
||||
let headers = new Headers({'Content-Type': 'text/plain'});
|
||||
wasm.test_headers(headers);
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
@ -2,6 +2,7 @@ extern crate wasm_bindgen_test_project_builder as project_builder;
|
||||
use project_builder::{project, Project};
|
||||
|
||||
mod event;
|
||||
mod headers;
|
||||
mod response;
|
||||
|
||||
fn websys_project() -> Project {
|
||||
|
@ -30,11 +30,11 @@ use std::path::Path;
|
||||
use backend::defined::{ImportedTypeDefinitions, RemoveUndefinedImports};
|
||||
use backend::util::{ident_ty, rust_ident, wrap_import_function};
|
||||
use failure::ResultExt;
|
||||
use heck::CamelCase;
|
||||
use heck::{CamelCase, ShoutySnakeCase};
|
||||
use quote::ToTokens;
|
||||
|
||||
use first_pass::{FirstPass, FirstPassRecord};
|
||||
use util::{public, TypePosition};
|
||||
use util::{public, webidl_const_ty_to_syn_ty, webidl_const_v_to_backend_const_v, TypePosition};
|
||||
|
||||
/// Either `Ok(t)` or `Err(failure::Error)`.
|
||||
pub type Result<T> = ::std::result::Result<T, failure::Error>;
|
||||
@ -250,7 +250,7 @@ impl WebidlParse<()> for webidl::ast::NonPartialInterface {
|
||||
js_namespace: None,
|
||||
kind: backend::ast::ImportKind::Type(backend::ast::ImportType {
|
||||
vis: public(),
|
||||
name: rust_ident(&self.name),
|
||||
name: rust_ident(self.name.to_camel_case().as_str()),
|
||||
attrs: Vec::new(),
|
||||
}),
|
||||
});
|
||||
@ -343,7 +343,8 @@ impl<'a> WebidlParse<&'a webidl::ast::NonPartialInterface> for webidl::ast::Exte
|
||||
match self {
|
||||
webidl::ast::ExtendedAttribute::ArgumentList(
|
||||
webidl::ast::ArgumentListExtendedAttribute { arguments, name },
|
||||
) if name == "Constructor" =>
|
||||
)
|
||||
if name == "Constructor" =>
|
||||
{
|
||||
add_constructor(arguments, &interface.name)
|
||||
}
|
||||
@ -358,7 +359,8 @@ impl<'a> WebidlParse<&'a webidl::ast::NonPartialInterface> for webidl::ast::Exte
|
||||
rhs_arguments,
|
||||
rhs_name,
|
||||
},
|
||||
) if lhs_name == "NamedConstructor" =>
|
||||
)
|
||||
if lhs_name == "NamedConstructor" =>
|
||||
{
|
||||
add_constructor(rhs_arguments, rhs_name)
|
||||
}
|
||||
@ -389,9 +391,11 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::InterfaceMember {
|
||||
webidl::ast::InterfaceMember::Operation(op) => {
|
||||
op.webidl_parse(program, first_pass, self_name)
|
||||
}
|
||||
webidl::ast::InterfaceMember::Const(cnst) => {
|
||||
cnst.webidl_parse(program, first_pass, self_name)
|
||||
}
|
||||
// TODO
|
||||
webidl::ast::InterfaceMember::Const(_)
|
||||
| webidl::ast::InterfaceMember::Iterable(_)
|
||||
webidl::ast::InterfaceMember::Iterable(_)
|
||||
| webidl::ast::InterfaceMember::Maplike(_)
|
||||
| webidl::ast::InterfaceMember::Setlike(_) => {
|
||||
warn!("Unsupported WebIDL interface member: {:?}", self);
|
||||
@ -637,3 +641,29 @@ impl<'a> WebidlParse<()> for webidl::ast::Enum {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> WebidlParse<&'a str> for webidl::ast::Const {
|
||||
fn webidl_parse(
|
||||
&self,
|
||||
program: &mut backend::ast::Program,
|
||||
_: &FirstPassRecord<'_>,
|
||||
interface_name: &'a str,
|
||||
) -> Result<()> {
|
||||
let syn_ty = webidl_const_ty_to_syn_ty(&self.type_);
|
||||
program.imports.push(backend::ast::Import {
|
||||
module: None,
|
||||
version: None,
|
||||
js_namespace: None,
|
||||
kind: backend::ast::ImportKind::Const(backend::ast::Const {
|
||||
vis: syn::Visibility::Public(syn::VisPublic {
|
||||
pub_token: Default::default(),
|
||||
}),
|
||||
name: rust_ident(self.name.to_shouty_snake_case().as_str()),
|
||||
interface_name: rust_ident(interface_name.to_camel_case().as_str()),
|
||||
ty: syn_ty,
|
||||
value: webidl_const_v_to_backend_const_v(&self.value),
|
||||
}),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,35 @@ fn shared_ref(ty: syn::Type) -> syn::Type {
|
||||
}.into()
|
||||
}
|
||||
|
||||
pub fn webidl_const_ty_to_syn_ty(ty: &webidl::ast::ConstType) -> syn::Type {
|
||||
use webidl::ast::ConstType::*;
|
||||
|
||||
// similar to webidl_ty_to_syn_ty
|
||||
match ty {
|
||||
Boolean => ident_ty(raw_ident("bool")),
|
||||
Byte => ident_ty(raw_ident("i8")),
|
||||
Octet => ident_ty(raw_ident("u8")),
|
||||
RestrictedDouble | UnrestrictedDouble => ident_ty(raw_ident("f64")),
|
||||
RestrictedFloat | UnrestrictedFloat => ident_ty(raw_ident("f32")),
|
||||
SignedLong => ident_ty(raw_ident("i32")),
|
||||
SignedLongLong => ident_ty(raw_ident("i64")),
|
||||
SignedShort => ident_ty(raw_ident("i16")),
|
||||
UnsignedLong => ident_ty(raw_ident("u32")),
|
||||
UnsignedLongLong => ident_ty(raw_ident("u64")),
|
||||
UnsignedShort => ident_ty(raw_ident("u16")),
|
||||
Identifier(ref id) => ident_ty(rust_ident(id)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn webidl_const_v_to_backend_const_v(v: &webidl::ast::ConstValue) -> backend::ast::ConstValue {
|
||||
match *v {
|
||||
webidl::ast::ConstValue::BooleanLiteral(b) => backend::ast::ConstValue::BooleanLiteral(b),
|
||||
webidl::ast::ConstValue::FloatLiteral(f) => backend::ast::ConstValue::FloatLiteral(f),
|
||||
webidl::ast::ConstValue::IntegerLiteral(i) => backend::ast::ConstValue::IntegerLiteral(i),
|
||||
webidl::ast::ConstValue::Null => backend::ast::ConstValue::Null,
|
||||
}
|
||||
}
|
||||
|
||||
fn simple_fn_arg(ident: Ident, ty: syn::Type) -> syn::ArgCaptured {
|
||||
syn::ArgCaptured {
|
||||
pat: syn::Pat::Ident(syn::PatIdent {
|
||||
|
190
crates/webidl/tests/all/consts.rs
Normal file
190
crates/webidl/tests/all/consts.rs
Normal file
@ -0,0 +1,190 @@
|
||||
use super::project;
|
||||
|
||||
#[test]
|
||||
fn bool() {
|
||||
project()
|
||||
.file(
|
||||
"foo.webidl",
|
||||
r#"
|
||||
interface Foo {
|
||||
const boolean not_true = false;
|
||||
const boolean not_false = true;
|
||||
};
|
||||
"#,
|
||||
)
|
||||
// a corresponding const in the js implementation is not required
|
||||
// value is taken directly from idl
|
||||
.file(
|
||||
"foo.js",
|
||||
r#"
|
||||
export class Foo {
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
|
||||
extern crate wasm_bindgen;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
pub mod foo;
|
||||
use foo::Foo;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn test() {
|
||||
let falsish: bool = Foo::NOT_TRUE;
|
||||
assert!(!falsish);
|
||||
let trueish: bool = Foo::NOT_FALSE;
|
||||
assert!(trueish);
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ints() {
|
||||
project()
|
||||
.file(
|
||||
"foo.webidl",
|
||||
r#"
|
||||
interface Byte {
|
||||
const byte imin = -128;
|
||||
const byte imax = 127;
|
||||
const octet umin = 0;
|
||||
const octet umax = 255;
|
||||
};
|
||||
interface Short {
|
||||
const short imin = -32768;
|
||||
const short imax = 32767;
|
||||
const unsigned short umin = 0;
|
||||
const unsigned short umax = 65535;
|
||||
};
|
||||
interface Long {
|
||||
const long imin = -2147483648;
|
||||
const long imax = 2147483647;
|
||||
const unsigned long umin = 0;
|
||||
const unsigned long umax = 4294967295;
|
||||
};
|
||||
interface LongLong {
|
||||
const long long imin = -9223372036854775808;
|
||||
const long long imax = 9223372036854775807;
|
||||
const unsigned long long umin = 0;
|
||||
// bug in webidl
|
||||
// https://github.com/sgodwincs/webidl-rs/issues/15
|
||||
//const unsigned long long umax = 18446744073709551615;
|
||||
};
|
||||
"#,
|
||||
)
|
||||
// a corresponding const in the js implementation is not required
|
||||
// value is taken directly from idl
|
||||
.file(
|
||||
"foo.js",
|
||||
r#"
|
||||
export class Byte {
|
||||
}
|
||||
export class Short {
|
||||
}
|
||||
export class Long {
|
||||
}
|
||||
export class LongLong {
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
|
||||
extern crate wasm_bindgen;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
pub mod foo;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn test() {
|
||||
assert_eq!(foo::Byte::IMIN, i8::min_value());
|
||||
assert_eq!(foo::Byte::IMAX, i8::max_value());
|
||||
assert_eq!(foo::Byte::UMIN, u8::min_value());
|
||||
assert_eq!(foo::Byte::UMAX, u8::max_value());
|
||||
|
||||
assert_eq!(foo::Short::IMIN, i16::min_value());
|
||||
assert_eq!(foo::Short::IMAX, i16::max_value());
|
||||
assert_eq!(foo::Short::UMIN, u16::min_value());
|
||||
assert_eq!(foo::Short::UMAX, u16::max_value());
|
||||
|
||||
assert_eq!(foo::Long::IMIN, i32::min_value());
|
||||
assert_eq!(foo::Long::IMAX, i32::max_value());
|
||||
assert_eq!(foo::Long::UMIN, u32::min_value());
|
||||
assert_eq!(foo::Long::UMAX, u32::max_value());
|
||||
|
||||
assert_eq!(foo::LongLong::IMIN, i64::min_value());
|
||||
assert_eq!(foo::LongLong::IMAX, i64::max_value());
|
||||
assert_eq!(foo::LongLong::UMIN, u64::min_value());
|
||||
//assert_eq!(foo::LongLong::UMAX, u64::max_value());
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn floats() {
|
||||
project()
|
||||
.file(
|
||||
"foo.webidl",
|
||||
r#"
|
||||
interface floats {
|
||||
const float f = 0.0;
|
||||
const unrestricted float neg_inf = -Infinity;
|
||||
const unrestricted float inf = Infinity;
|
||||
const unrestricted float nan = NaN;
|
||||
};
|
||||
interface doubles {
|
||||
const double d = 0.0;
|
||||
const unrestricted double neg_inf = -Infinity;
|
||||
const unrestricted double inf = Infinity;
|
||||
const unrestricted double nan = NaN;
|
||||
};
|
||||
"#,
|
||||
)
|
||||
// a corresponding const in the js implementation is not required
|
||||
// value is taken directly from idl
|
||||
.file(
|
||||
"foo.js",
|
||||
r#"
|
||||
export class floats {
|
||||
}
|
||||
export class doubles {
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
|
||||
extern crate wasm_bindgen;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
pub mod foo;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn test() {
|
||||
assert_eq!(foo::Floats::F, 0.0_f32);
|
||||
assert!(foo::Floats::NEG_INF.is_infinite());
|
||||
assert!(foo::Floats::NEG_INF.is_sign_negative());
|
||||
assert!(foo::Floats::INF.is_infinite());
|
||||
assert!(foo::Floats::INF.is_sign_positive());
|
||||
assert!(foo::Floats::NAN.is_nan());
|
||||
|
||||
assert_eq!(foo::Doubles::D, 0.0_f64);
|
||||
assert!(foo::Doubles::NEG_INF.is_infinite());
|
||||
assert!(foo::Doubles::NEG_INF.is_sign_negative());
|
||||
assert!(foo::Doubles::INF.is_infinite());
|
||||
assert!(foo::Doubles::INF.is_sign_positive());
|
||||
assert!(foo::Doubles::NAN.is_nan());
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
extern crate wasm_bindgen_test_project_builder as project_builder;
|
||||
use project_builder::project;
|
||||
|
||||
mod simple;
|
||||
mod consts;
|
||||
mod enums;
|
||||
mod simple;
|
||||
mod throws;
|
||||
|
@ -14,7 +14,7 @@ development.
|
||||
|
||||
[install Rust]: https://www.rust-lang.org/en-US/install.html
|
||||
|
||||
2. The tests for this project use Node. Make sure you have node >= 8 installed,
|
||||
2. The tests for this project use Node. Make sure you have node >= 10 installed,
|
||||
as that is when WebAssembly support was introduced. [Install Node].
|
||||
|
||||
[Install Node]: https://nodejs.org/en/
|
||||
|
@ -9,13 +9,13 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^10.5.2",
|
||||
"babel-eslint": "^8.2.5",
|
||||
"babel-eslint": "^8.2.6",
|
||||
"eslint": "^5.1.0",
|
||||
"geckodriver": "^1.11.0",
|
||||
"selenium-webdriver": "^4.0.0-alpha.1",
|
||||
"ts-loader": "^4.4.2",
|
||||
"typescript": "^2.7.2",
|
||||
"webpack": "^4.15.1",
|
||||
"webpack": "^4.16.0",
|
||||
"webpack-cli": "^3.0.8",
|
||||
"webpack-dev-server": "^3.1.4"
|
||||
}
|
||||
|
@ -77,7 +77,6 @@ pub trait RefMutFromWasmAbi: WasmDescribe {
|
||||
|
||||
pub trait Stack {
|
||||
fn push(&mut self, bits: u32);
|
||||
fn pop(&mut self) -> u32;
|
||||
}
|
||||
|
||||
/// An unsafe trait which represents types that are ABI-safe to pass via wasm
|
||||
@ -105,11 +104,15 @@ macro_rules! simple {
|
||||
($($t:tt)*) => ($(
|
||||
impl IntoWasmAbi for $t {
|
||||
type Abi = $t;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self, _extra: &mut Stack) -> $t { self }
|
||||
}
|
||||
|
||||
impl FromWasmAbi for $t {
|
||||
type Abi = $t;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: $t, _extra: &mut Stack) -> $t { js }
|
||||
}
|
||||
)*)
|
||||
@ -121,6 +124,8 @@ macro_rules! sixtyfour {
|
||||
($($t:tt)*) => ($(
|
||||
impl IntoWasmAbi for $t {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self, _extra: &mut Stack) -> WasmSlice {
|
||||
WasmSlice {
|
||||
ptr: self as u32,
|
||||
@ -131,6 +136,8 @@ macro_rules! sixtyfour {
|
||||
|
||||
impl FromWasmAbi for $t {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: WasmSlice, _extra: &mut Stack) -> $t {
|
||||
(js.ptr as $t) | ((js.len as $t) << 32)
|
||||
}
|
||||
@ -144,11 +151,15 @@ macro_rules! as_u32 {
|
||||
($($t:tt)*) => ($(
|
||||
impl IntoWasmAbi for $t {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self, _extra: &mut Stack) -> u32 { self as u32 }
|
||||
}
|
||||
|
||||
impl FromWasmAbi for $t {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: u32, _extra: &mut Stack) -> $t { js as $t }
|
||||
}
|
||||
)*)
|
||||
@ -159,6 +170,7 @@ as_u32!(i8 u8 i16 u16 isize usize);
|
||||
impl IntoWasmAbi for bool {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self, _extra: &mut Stack) -> u32 {
|
||||
self as u32
|
||||
}
|
||||
@ -167,6 +179,7 @@ impl IntoWasmAbi for bool {
|
||||
impl FromWasmAbi for bool {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: u32, _extra: &mut Stack) -> bool {
|
||||
js != 0
|
||||
}
|
||||
@ -174,6 +187,8 @@ impl FromWasmAbi for bool {
|
||||
|
||||
impl IntoWasmAbi for char {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self, _extra: &mut Stack) -> u32 {
|
||||
self as u32
|
||||
}
|
||||
@ -181,6 +196,8 @@ impl IntoWasmAbi for char {
|
||||
|
||||
impl FromWasmAbi for char {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: u32, _extra: &mut Stack) -> char {
|
||||
char::from_u32_unchecked(js)
|
||||
}
|
||||
@ -224,6 +241,7 @@ macro_rules! vectors {
|
||||
impl IntoWasmAbi for Box<[$t]> {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self, extra: &mut Stack) -> WasmSlice {
|
||||
let ptr = self.as_ptr();
|
||||
let len = self.len();
|
||||
@ -239,6 +257,7 @@ macro_rules! vectors {
|
||||
impl FromWasmAbi for Box<[$t]> {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: WasmSlice, extra: &mut Stack) -> Self {
|
||||
let ptr = <*mut $t>::from_abi(js.ptr, extra);
|
||||
let len = js.len as usize;
|
||||
@ -249,6 +268,7 @@ macro_rules! vectors {
|
||||
impl<'a> IntoWasmAbi for &'a [$t] {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self, extra: &mut Stack) -> WasmSlice {
|
||||
WasmSlice {
|
||||
ptr: self.as_ptr().into_abi(extra),
|
||||
@ -260,6 +280,7 @@ macro_rules! vectors {
|
||||
impl<'a> IntoWasmAbi for &'a mut [$t] {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self, extra: &mut Stack) -> WasmSlice {
|
||||
(&*self).into_abi(extra)
|
||||
}
|
||||
@ -269,6 +290,7 @@ macro_rules! vectors {
|
||||
type Abi = WasmSlice;
|
||||
type Anchor = &'static [$t];
|
||||
|
||||
#[inline]
|
||||
unsafe fn ref_from_abi(js: WasmSlice, extra: &mut Stack) -> &'static [$t] {
|
||||
slice::from_raw_parts(
|
||||
<*const $t>::from_abi(js.ptr, extra),
|
||||
@ -281,6 +303,7 @@ macro_rules! vectors {
|
||||
type Abi = WasmSlice;
|
||||
type Anchor = &'static mut [$t];
|
||||
|
||||
#[inline]
|
||||
unsafe fn ref_mut_from_abi(js: WasmSlice, extra: &mut Stack)
|
||||
-> &'static mut [$t]
|
||||
{
|
||||
@ -300,6 +323,7 @@ vectors! {
|
||||
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)
|
||||
}
|
||||
@ -316,6 +340,7 @@ if_std! {
|
||||
impl IntoWasmAbi for String {
|
||||
type Abi = <Vec<u8> as IntoWasmAbi>::Abi;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self, extra: &mut Stack) -> Self::Abi {
|
||||
self.into_bytes().into_abi(extra)
|
||||
}
|
||||
@ -324,6 +349,7 @@ if_std! {
|
||||
impl FromWasmAbi for String {
|
||||
type Abi = <Vec<u8> as FromWasmAbi>::Abi;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: Self::Abi, extra: &mut Stack) -> Self {
|
||||
String::from_utf8_unchecked(<Vec<u8>>::from_abi(js, extra))
|
||||
}
|
||||
@ -333,6 +359,7 @@ if_std! {
|
||||
impl<'a> IntoWasmAbi for &'a str {
|
||||
type Abi = <&'a [u8] as IntoWasmAbi>::Abi;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self, extra: &mut Stack) -> Self::Abi {
|
||||
self.as_bytes().into_abi(extra)
|
||||
}
|
||||
@ -342,6 +369,7 @@ impl RefFromWasmAbi for str {
|
||||
type Abi = <[u8] as RefFromWasmAbi>::Abi;
|
||||
type Anchor = &'static str;
|
||||
|
||||
#[inline]
|
||||
unsafe fn ref_from_abi(js: Self::Abi, extra: &mut Stack) -> Self::Anchor {
|
||||
str::from_utf8_unchecked(<[u8]>::ref_from_abi(js, extra))
|
||||
}
|
||||
@ -350,6 +378,7 @@ impl RefFromWasmAbi for str {
|
||||
impl IntoWasmAbi for JsValue {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self, _extra: &mut Stack) -> u32 {
|
||||
let ret = self.idx;
|
||||
mem::forget(self);
|
||||
@ -360,6 +389,7 @@ impl IntoWasmAbi for JsValue {
|
||||
impl FromWasmAbi for JsValue {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: u32, _extra: &mut Stack) -> JsValue {
|
||||
JsValue { idx: js }
|
||||
}
|
||||
@ -367,6 +397,8 @@ impl FromWasmAbi for JsValue {
|
||||
|
||||
impl<'a> IntoWasmAbi for &'a JsValue {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self, _extra: &mut Stack) -> u32 {
|
||||
self.idx
|
||||
}
|
||||
@ -376,6 +408,7 @@ impl RefFromWasmAbi for JsValue {
|
||||
type Abi = u32;
|
||||
type Anchor = ManuallyDrop<JsValue>;
|
||||
|
||||
#[inline]
|
||||
unsafe fn ref_from_abi(js: u32, _extra: &mut Stack) -> Self::Anchor {
|
||||
ManuallyDrop::new(JsValue { idx: js })
|
||||
}
|
||||
@ -385,6 +418,7 @@ if_std! {
|
||||
impl IntoWasmAbi for Box<[JsValue]> {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self, extra: &mut Stack) -> WasmSlice {
|
||||
let ptr = self.as_ptr();
|
||||
let len = self.len();
|
||||
@ -399,6 +433,7 @@ if_std! {
|
||||
impl FromWasmAbi for Box<[JsValue]> {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: WasmSlice, extra: &mut Stack) -> Self {
|
||||
let ptr = <*mut JsValue>::from_abi(js.ptr, extra);
|
||||
let len = js.len as usize;
|
||||
@ -415,12 +450,14 @@ const GLOBAL_STACK_CAP: usize = 16;
|
||||
static mut GLOBAL_STACK: [u32; GLOBAL_STACK_CAP] = [0; GLOBAL_STACK_CAP];
|
||||
|
||||
impl GlobalStack {
|
||||
#[inline]
|
||||
pub unsafe fn new() -> GlobalStack {
|
||||
GlobalStack { next: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl Stack for GlobalStack {
|
||||
#[inline]
|
||||
fn push(&mut self, val: u32) {
|
||||
unsafe {
|
||||
assert!(self.next < GLOBAL_STACK_CAP);
|
||||
@ -428,15 +465,6 @@ impl Stack for GlobalStack {
|
||||
self.next += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn pop(&mut self) -> u32 {
|
||||
unsafe {
|
||||
assert!(self.next < GLOBAL_STACK_CAP);
|
||||
let ret = GLOBAL_STACK[self.next];
|
||||
self.next += 1;
|
||||
ret
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
160
src/js.rs
160
src/js.rs
@ -240,6 +240,20 @@ extern "C" {
|
||||
#[wasm_bindgen(method)]
|
||||
pub fn push(this: &Array, value: JsValue) -> u32;
|
||||
|
||||
/// The reduce() method applies a function against an accumulator and each element in
|
||||
/// the array (from left to right) to reduce it to a single value.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
|
||||
#[wasm_bindgen(method)]
|
||||
pub fn reduce(this: &Array, predicate: &mut FnMut(JsValue, JsValue, u32, Array) -> JsValue, initial_value: JsValue) -> JsValue;
|
||||
|
||||
/// The reduceRight() method applies a function against an accumulator and each value
|
||||
/// of the array (from right-to-left) to reduce it to a single value.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/ReduceRight
|
||||
#[wasm_bindgen(method, js_name = reduceRight)]
|
||||
pub fn reduce_right(this: &Array, predicate: &mut FnMut(JsValue, JsValue, u32, Array) -> JsValue, initial_value: JsValue) -> JsValue;
|
||||
|
||||
/// The reverse() method reverses an array in place. The first array
|
||||
/// element becomes the last, and the last array element becomes the first.
|
||||
///
|
||||
@ -378,6 +392,152 @@ extern "C" {
|
||||
pub fn value_of(this: &Boolean) -> bool;
|
||||
}
|
||||
|
||||
// DataView
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
pub type DataView;
|
||||
|
||||
/// The `DataView` view provides a low-level interface for reading and
|
||||
/// writing multiple number types in an `ArrayBuffer` irrespective of the
|
||||
/// platform's endianness.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new(buffer: &ArrayBuffer, byteOffset: usize, byteLength: usize) -> DataView;
|
||||
|
||||
/// The ArrayBuffer referenced by this view. Fixed at construction time and thus read only.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/buffer
|
||||
#[wasm_bindgen(method, getter, structural)]
|
||||
pub fn buffer(this: &DataView) -> ArrayBuffer;
|
||||
|
||||
/// The length (in bytes) of this view from the start of its ArrayBuffer.
|
||||
/// Fixed at construction time and thus read only.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/byteLength
|
||||
#[wasm_bindgen(method, getter, structural, js_name = byteLength)]
|
||||
pub fn byte_length(this: &DataView) -> usize;
|
||||
|
||||
/// The offset (in bytes) of this view from the start of its ArrayBuffer.
|
||||
/// Fixed at construction time and thus read only.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/byteOffset
|
||||
#[wasm_bindgen(method, getter, structural, js_name = byteOffset)]
|
||||
pub fn byte_offset(this: &DataView) -> usize;
|
||||
|
||||
/// The getInt8() method gets a signed 8-bit integer (byte) at the
|
||||
/// specified byte offset from the start of the DataView.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getInt8
|
||||
#[wasm_bindgen(method, js_name = getInt8)]
|
||||
pub fn get_int8(this: &DataView, byte_offset: usize) -> i8;
|
||||
|
||||
/// The getUint8() method gets a unsigned 8-bit integer (byte) at the specified
|
||||
/// byte offset from the start of the DataView.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getUint8
|
||||
#[wasm_bindgen(method, js_name = getUint8)]
|
||||
pub fn get_uint8(this: &DataView, byte_offset: usize) -> u8;
|
||||
|
||||
/// The getInt16() method gets a signed 16-bit integer (byte) at the specified
|
||||
/// byte offset from the start of the DataView.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getInt16
|
||||
#[wasm_bindgen(method, js_name = getInt16)]
|
||||
pub fn get_int16(this: &DataView, byte_offset: usize) -> i16;
|
||||
|
||||
/// The getUint16() an unsigned 16-bit integer (unsigned byte) at the specified
|
||||
/// byte offset from the start of the view.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getUint16
|
||||
#[wasm_bindgen(method, js_name = getUint16)]
|
||||
pub fn get_uint16(this: &DataView, byte_offset: usize) -> u16;
|
||||
|
||||
/// The getInt32() method gets a signed 16-bit integer (byte) at the specified
|
||||
/// byte offset from the start of the DataView.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getInt32
|
||||
#[wasm_bindgen(method, js_name = getInt32)]
|
||||
pub fn get_int32(this: &DataView, byte_offset: usize) -> i32;
|
||||
|
||||
/// The getUint32() an unsigned 16-bit integer (unsigned byte) at the specified
|
||||
/// byte offset from the start of the view.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getUint32
|
||||
#[wasm_bindgen(method, js_name = getUint32)]
|
||||
pub fn get_uint32(this: &DataView, byte_offset: usize) -> u32;
|
||||
|
||||
/// The getFloat32() method gets a signed 32-bit float (float) at the specified
|
||||
/// byte offset from the start of the DataView.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getFloat32
|
||||
#[wasm_bindgen(method, js_name = getFloat32)]
|
||||
pub fn get_float32(this: &DataView, byte_offset: usize) -> f32;
|
||||
|
||||
/// The getFloat64() method gets a signed 32-bit float (float) at the specified
|
||||
/// byte offset from the start of the DataView.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getFloat64
|
||||
#[wasm_bindgen(method, js_name = getFloat64)]
|
||||
pub fn get_float64(this: &DataView, byte_offset: usize) -> f64;
|
||||
|
||||
/// The setInt8() method stores a signed 8-bit integer (byte) value at the
|
||||
/// specified byte offset from the start of the DataView.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setInt8
|
||||
#[wasm_bindgen(method, js_name = setInt8)]
|
||||
pub fn set_int8(this: &DataView, byte_offset: usize, value: i8);
|
||||
|
||||
/// The setUint8() method stores an unsigned 8-bit integer (byte) value at the
|
||||
/// specified byte offset from the start of the DataView.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setUint8
|
||||
#[wasm_bindgen(method, js_name = setUint8)]
|
||||
pub fn set_uint8(this: &DataView, byte_offset: usize, value: u8);
|
||||
|
||||
/// The setInt16() method stores a signed 16-bit integer (byte) value at the
|
||||
/// specified byte offset from the start of the DataView.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setInt16
|
||||
#[wasm_bindgen(method, js_name = setInt16)]
|
||||
pub fn set_int16(this: &DataView, byte_offset: usize, value: i16);
|
||||
|
||||
/// The setUint16() method stores an unsigned 16-bit integer (byte) value at the
|
||||
/// specified byte offset from the start of the DataView.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setUint16
|
||||
#[wasm_bindgen(method, js_name = setUint16)]
|
||||
pub fn set_uint16(this: &DataView, byte_offset: usize, value: u16);
|
||||
|
||||
/// The setInt32() method stores a signed 32-bit integer (byte) value at the
|
||||
/// specified byte offset from the start of the DataView.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setInt32
|
||||
#[wasm_bindgen(method, js_name = setInt32)]
|
||||
pub fn set_int32(this: &DataView, byte_offset: usize, value: i32);
|
||||
|
||||
/// The setUint32() method stores an unsigned 32-bit integer (byte) value at the
|
||||
/// specified byte offset from the start of the DataView.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setUint32
|
||||
#[wasm_bindgen(method, js_name = setUint32)]
|
||||
pub fn set_uint32(this: &DataView, byte_offset: usize, value: u32);
|
||||
|
||||
/// The setFloat32() method stores a signed 32-bit float (float) value at the
|
||||
/// specified byte offset from the start of the DataView.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setFloat32
|
||||
#[wasm_bindgen(method, js_name = setFloat32)]
|
||||
pub fn set_float32(this: &DataView, byte_offset: usize, value: f32);
|
||||
|
||||
/// The setFloat64() method stores a signed 64-bit float (float) value at the
|
||||
/// specified byte offset from the start of the DataView.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setFloat64
|
||||
#[wasm_bindgen(method, js_name = setFloat64)]
|
||||
pub fn set_float64(this: &DataView, byte_offset: usize, value: f64);
|
||||
}
|
||||
|
||||
// Error
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
|
27
src/lib.rs
27
src/lib.rs
@ -5,7 +5,7 @@
|
||||
//! this crate and this crate also provides JS bindings through the `JsValue`
|
||||
//! interface.
|
||||
|
||||
#![feature(use_extern_macros, wasm_import_module, try_reserve, unsize)]
|
||||
#![feature(use_extern_macros, wasm_import_module, unsize)]
|
||||
#![cfg_attr(feature = "js_globals", feature(proc_macro, wasm_custom_section))]
|
||||
#![no_std]
|
||||
|
||||
@ -661,24 +661,29 @@ pub mod __rt {
|
||||
}
|
||||
|
||||
if_std! {
|
||||
use std::prelude::v1::*;
|
||||
use std::alloc::{System, GlobalAlloc, Layout};
|
||||
use std::mem;
|
||||
|
||||
#[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);
|
||||
let align = mem::align_of::<usize>();
|
||||
if let Ok(layout) = Layout::from_size_align(size, align) {
|
||||
unsafe {
|
||||
let ptr = System.alloc(layout);
|
||||
if !ptr.is_null() {
|
||||
return ptr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super::throw("invalid malloc request");
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn __wbindgen_free(ptr: *mut u8, size: usize) {
|
||||
drop(Vec::<u8>::from_raw_parts(ptr, 0, size));
|
||||
let align = mem::align_of::<usize>();
|
||||
let layout = Layout::from_size_align_unchecked(size, align);
|
||||
System.dealloc(ptr, layout);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -830,3 +830,69 @@ fn map() {
|
||||
)
|
||||
.test()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reduce() {
|
||||
project()
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(proc_macro, wasm_custom_section)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::js;
|
||||
use JsValue;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn array_reduce(array: &js::Array) -> JsValue {
|
||||
array.reduce(&mut |ac, cr, _, _| JsValue::from_str(&format!("{}{}", &ac.as_string().unwrap(), &cr.as_string().unwrap().as_str())), JsValue::from_str(""))
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"test.js",
|
||||
r#"
|
||||
import * as assert from "assert";
|
||||
import * as wasm from "./out";
|
||||
|
||||
export function test() {
|
||||
assert.equal(wasm.array_reduce(['0', '1', '2', '3', '4']), '01234');
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reduce_right() {
|
||||
project()
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(proc_macro, wasm_custom_section)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::js;
|
||||
use JsValue;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn array_reduce_right(array: &js::Array) -> JsValue {
|
||||
array.reduce_right(&mut |ac, cr, _, _| JsValue::from_str(&format!("{}{}", &ac.as_string().unwrap(), &cr.as_string().unwrap().as_str())), JsValue::from_str(""))
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"test.js",
|
||||
r#"
|
||||
import * as assert from "assert";
|
||||
import * as wasm from "./out";
|
||||
|
||||
export function test() {
|
||||
assert.equal(wasm.array_reduce_right(['0', '1', '2', '3', '4']), '43210');
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test()
|
||||
}
|
55
tests/all/js_globals/DataView.rs
Normal file
55
tests/all/js_globals/DataView.rs
Normal file
@ -0,0 +1,55 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use super::project;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
project()
|
||||
.file("src/lib.rs", r#"
|
||||
#![feature(proc_macro, wasm_custom_section)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::js::{ArrayBuffer, DataView};
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn test_data_view(buffer: &ArrayBuffer, offset: usize, len: usize) {
|
||||
let v = DataView::new(buffer, offset, len);
|
||||
assert_eq!(v.byte_offset(), offset);
|
||||
assert_eq!(v.byte_length(), len);
|
||||
assert_eq!(v.get_int8(0), 2);
|
||||
assert_eq!(v.get_uint8(0), 2);
|
||||
|
||||
v.set_int8(0, 42);
|
||||
assert_eq!(v.get_int8(0), 42);
|
||||
v.set_uint8(0, 255);
|
||||
assert_eq!(v.get_uint8(0), 255);
|
||||
v.set_int16(0, 32767);
|
||||
assert_eq!(v.get_int16(0), 32767);
|
||||
v.set_uint16(0, 65535);
|
||||
assert_eq!(v.get_uint16(0), 65535);
|
||||
v.set_int32(0, 123456789);
|
||||
assert_eq!(v.get_int32(0), 123456789);
|
||||
v.set_uint32(0, 3_123_456_789);
|
||||
assert_eq!(v.get_uint32(0), 3_123_456_789);
|
||||
v.set_float32(0, 100.123);
|
||||
assert_eq!(v.get_float32(0), 100.123);
|
||||
v.set_float64(0, 123456789.123456);
|
||||
assert_eq!(v.get_float64(0), 123456789.123456);
|
||||
|
||||
v.set_int8(0, 42);
|
||||
}
|
||||
"#)
|
||||
.file("test.js", r#"
|
||||
import * as assert from "assert";
|
||||
import * as wasm from "./out";
|
||||
|
||||
export function test() {
|
||||
const bytes = new Int8Array(10);
|
||||
bytes[2] = 2;
|
||||
wasm.test_data_view(bytes.buffer, 2, 8);
|
||||
assert.equal(bytes[2], 42);
|
||||
}
|
||||
"#)
|
||||
.test()
|
||||
}
|
@ -6,6 +6,7 @@ mod Array;
|
||||
mod ArrayBuffer;
|
||||
mod ArrayIterator;
|
||||
mod Boolean;
|
||||
mod DataView;
|
||||
mod Date;
|
||||
mod Error;
|
||||
mod Function;
|
||||
|
16
yarn.lock
16
yarn.lock
@ -408,15 +408,15 @@ babel-code-frame@^6.26.0:
|
||||
esutils "^2.0.2"
|
||||
js-tokens "^3.0.2"
|
||||
|
||||
babel-eslint@^8.2.5:
|
||||
version "8.2.5"
|
||||
resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.5.tgz#dc2331c259d36782aa189da510c43dedd5adc7a3"
|
||||
babel-eslint@^8.2.6:
|
||||
version "8.2.6"
|
||||
resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.6.tgz#6270d0c73205628067c0f7ae1693a9e797acefd9"
|
||||
dependencies:
|
||||
"@babel/code-frame" "7.0.0-beta.44"
|
||||
"@babel/traverse" "7.0.0-beta.44"
|
||||
"@babel/types" "7.0.0-beta.44"
|
||||
babylon "7.0.0-beta.44"
|
||||
eslint-scope "~3.7.1"
|
||||
eslint-scope "3.7.1"
|
||||
eslint-visitor-keys "^1.0.0"
|
||||
|
||||
babylon@7.0.0-beta.44:
|
||||
@ -1239,7 +1239,7 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
|
||||
eslint-scope@^3.7.1, eslint-scope@~3.7.1:
|
||||
eslint-scope@3.7.1, eslint-scope@^3.7.1:
|
||||
version "3.7.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8"
|
||||
dependencies:
|
||||
@ -4150,9 +4150,9 @@ webpack-sources@^1.0.1, webpack-sources@^1.1.0:
|
||||
source-list-map "^2.0.0"
|
||||
source-map "~0.6.1"
|
||||
|
||||
webpack@^4.15.1:
|
||||
version "4.15.1"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.15.1.tgz#dc716779a3b88827c369f18c71a6137fa7e582fd"
|
||||
webpack@^4.16.0:
|
||||
version "4.16.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.16.0.tgz#660dae90890e55b8ed17c6f9d17bebb01dab5b4c"
|
||||
dependencies:
|
||||
"@webassemblyjs/ast" "1.5.13"
|
||||
"@webassemblyjs/helper-module-context" "1.5.13"
|
||||
|
Loading…
Reference in New Issue
Block a user