mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-03-31 01:11:06 +00: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),
|
Static(ImportStatic),
|
||||||
Type(ImportType),
|
Type(ImportType),
|
||||||
Enum(ImportEnum),
|
Enum(ImportEnum),
|
||||||
|
Const(Const),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
|
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
|
||||||
@ -174,6 +175,24 @@ pub struct TypeAlias {
|
|||||||
pub src: syn::Type,
|
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 {
|
impl Program {
|
||||||
pub(crate) fn shared(&self) -> shared::Program {
|
pub(crate) fn shared(&self) -> shared::Program {
|
||||||
shared::Program {
|
shared::Program {
|
||||||
@ -293,6 +312,7 @@ impl ImportKind {
|
|||||||
ImportKind::Static(_) => false,
|
ImportKind::Static(_) => false,
|
||||||
ImportKind::Type(_) => false,
|
ImportKind::Type(_) => false,
|
||||||
ImportKind::Enum(_) => false,
|
ImportKind::Enum(_) => false,
|
||||||
|
ImportKind::Const(_) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,6 +322,7 @@ impl ImportKind {
|
|||||||
ImportKind::Static(ref f) => shared::ImportKind::Static(f.shared()),
|
ImportKind::Static(ref f) => shared::ImportKind::Static(f.shared()),
|
||||||
ImportKind::Type(ref f) => shared::ImportKind::Type(f.shared()),
|
ImportKind::Type(ref f) => shared::ImportKind::Type(f.shared()),
|
||||||
ImportKind::Enum(ref f) => shared::ImportKind::Enum(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::Static(ref s) => s.to_tokens(tokens),
|
||||||
ast::ImportKind::Type(ref t) => t.to_tokens(tokens),
|
ast::ImportKind::Type(ref t) => t.to_tokens(tokens),
|
||||||
ast::ImportKind::Enum(ref e) => e.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::Static(_) => return,
|
||||||
ast::ImportKind::Type(_) => return,
|
ast::ImportKind::Type(_) => return,
|
||||||
ast::ImportKind::Enum(_) => return,
|
ast::ImportKind::Enum(_) => return,
|
||||||
|
ast::ImportKind::Const(_) => return,
|
||||||
};
|
};
|
||||||
let describe_name = format!("__wbindgen_describe_{}", f.shim);
|
let describe_name = format!("__wbindgen_describe_{}", f.shim);
|
||||||
let describe_name = Ident::new(&describe_name, Span::call_site());
|
let describe_name = Ident::new(&describe_name, Span::call_site());
|
||||||
@ -958,3 +960,41 @@ impl ToTokens for ast::TypeAlias {
|
|||||||
}).to_tokens(into);
|
}).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::Function(fun) => fun.imported_types(f),
|
||||||
ast::ImportKind::Type(ty) => ty.imported_types(f),
|
ast::ImportKind::Type(ty) => ty.imported_types(f),
|
||||||
ast::ImportKind::Enum(enm) => enm.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*
|
/// Remove any methods, statics, &c, that reference types that are *not*
|
||||||
/// defined.
|
/// defined.
|
||||||
pub trait RemoveUndefinedImports {
|
pub trait RemoveUndefinedImports {
|
||||||
|
@ -19,5 +19,5 @@ serde_derive = "1.0"
|
|||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
tempfile = "3.0"
|
tempfile = "3.0"
|
||||||
wasm-bindgen-shared = { path = "../shared", version = '=0.2.11' }
|
wasm-bindgen-shared = { path = "../shared", version = '=0.2.11' }
|
||||||
wasm-gc-api = "0.1"
|
wasm-gc-api = "0.1.8"
|
||||||
wasmi = "0.3"
|
wasmi = "0.3"
|
||||||
|
@ -1580,6 +1580,7 @@ impl<'a> Context<'a> {
|
|||||||
let wasm_bytes = parity_wasm::serialize(module)?;
|
let wasm_bytes = parity_wasm::serialize(module)?;
|
||||||
let bytes = wasm_gc::Config::new()
|
let bytes = wasm_gc::Config::new()
|
||||||
.demangle(self.config.demangle)
|
.demangle(self.config.demangle)
|
||||||
|
.keep_debug(self.config.keep_debug || self.config.debug)
|
||||||
.gc(&wasm_bytes)?;
|
.gc(&wasm_bytes)?;
|
||||||
*self.module = deserialize_buffer(&bytes)?;
|
*self.module = deserialize_buffer(&bytes)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -1757,6 +1758,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
|||||||
}
|
}
|
||||||
shared::ImportKind::Type(_) => {}
|
shared::ImportKind::Type(_) => {}
|
||||||
shared::ImportKind::Enum(_) => {}
|
shared::ImportKind::Enum(_) => {}
|
||||||
|
shared::ImportKind::Const(_) => {}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ pub struct Bindgen {
|
|||||||
debug: bool,
|
debug: bool,
|
||||||
typescript: bool,
|
typescript: bool,
|
||||||
demangle: bool,
|
demangle: bool,
|
||||||
|
keep_debug: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Bindgen {
|
impl Bindgen {
|
||||||
@ -45,6 +46,7 @@ impl Bindgen {
|
|||||||
debug: false,
|
debug: false,
|
||||||
typescript: false,
|
typescript: false,
|
||||||
demangle: true,
|
demangle: true,
|
||||||
|
keep_debug: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +95,11 @@ impl Bindgen {
|
|||||||
self
|
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> {
|
pub fn generate<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
|
||||||
self._generate(path.as_ref())
|
self._generate(path.as_ref())
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ Options:
|
|||||||
--no-typescript Don't emit a *.d.ts file
|
--no-typescript Don't emit a *.d.ts file
|
||||||
--debug Include otherwise-extraneous debug checks in output
|
--debug Include otherwise-extraneous debug checks in output
|
||||||
--no-demangle Don't demangle Rust symbol names
|
--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
|
-V --version Print the version number of wasm-bindgen
|
||||||
";
|
";
|
||||||
|
|
||||||
@ -47,6 +48,7 @@ struct Args {
|
|||||||
flag_version: bool,
|
flag_version: bool,
|
||||||
flag_no_demangle: bool,
|
flag_no_demangle: bool,
|
||||||
flag_no_modules_global: Option<String>,
|
flag_no_modules_global: Option<String>,
|
||||||
|
flag_keep_debug: bool,
|
||||||
arg_input: Option<PathBuf>,
|
arg_input: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +87,7 @@ fn rmain(args: &Args) -> Result<(), Error> {
|
|||||||
.no_modules(args.flag_no_modules)
|
.no_modules(args.flag_no_modules)
|
||||||
.debug(args.flag_debug)
|
.debug(args.flag_debug)
|
||||||
.demangle(!args.flag_no_demangle)
|
.demangle(!args.flag_no_demangle)
|
||||||
|
.keep_debug(args.flag_keep_debug)
|
||||||
.typescript(typescript);
|
.typescript(typescript);
|
||||||
if let Some(ref name) = args.flag_no_modules_global {
|
if let Some(ref name) = args.flag_no_modules_global {
|
||||||
b.no_modules_global(name);
|
b.no_modules_global(name);
|
||||||
|
@ -34,6 +34,7 @@ pub enum ImportKind {
|
|||||||
Static(ImportStatic),
|
Static(ImportStatic),
|
||||||
Type(ImportType),
|
Type(ImportType),
|
||||||
Enum(ImportEnum),
|
Enum(ImportEnum),
|
||||||
|
Const(Const)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
@ -124,6 +125,9 @@ pub struct StructField {
|
|||||||
pub comments: Vec<String>,
|
pub comments: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct Const {}
|
||||||
|
|
||||||
pub fn new_function(struct_name: &str) -> String {
|
pub fn new_function(struct_name: &str) -> String {
|
||||||
let mut name = format!("__wbg_");
|
let mut name = format!("__wbg_");
|
||||||
name.extend(struct_name.chars().flat_map(|s| s.to_lowercase()));
|
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};
|
use project_builder::{project, Project};
|
||||||
|
|
||||||
mod event;
|
mod event;
|
||||||
|
mod headers;
|
||||||
mod response;
|
mod response;
|
||||||
|
|
||||||
fn websys_project() -> Project {
|
fn websys_project() -> Project {
|
||||||
|
@ -30,11 +30,11 @@ use std::path::Path;
|
|||||||
use backend::defined::{ImportedTypeDefinitions, RemoveUndefinedImports};
|
use backend::defined::{ImportedTypeDefinitions, RemoveUndefinedImports};
|
||||||
use backend::util::{ident_ty, rust_ident, wrap_import_function};
|
use backend::util::{ident_ty, rust_ident, wrap_import_function};
|
||||||
use failure::ResultExt;
|
use failure::ResultExt;
|
||||||
use heck::CamelCase;
|
use heck::{CamelCase, ShoutySnakeCase};
|
||||||
use quote::ToTokens;
|
use quote::ToTokens;
|
||||||
|
|
||||||
use first_pass::{FirstPass, FirstPassRecord};
|
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)`.
|
/// Either `Ok(t)` or `Err(failure::Error)`.
|
||||||
pub type Result<T> = ::std::result::Result<T, 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,
|
js_namespace: None,
|
||||||
kind: backend::ast::ImportKind::Type(backend::ast::ImportType {
|
kind: backend::ast::ImportKind::Type(backend::ast::ImportType {
|
||||||
vis: public(),
|
vis: public(),
|
||||||
name: rust_ident(&self.name),
|
name: rust_ident(self.name.to_camel_case().as_str()),
|
||||||
attrs: Vec::new(),
|
attrs: Vec::new(),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
@ -343,7 +343,8 @@ impl<'a> WebidlParse<&'a webidl::ast::NonPartialInterface> for webidl::ast::Exte
|
|||||||
match self {
|
match self {
|
||||||
webidl::ast::ExtendedAttribute::ArgumentList(
|
webidl::ast::ExtendedAttribute::ArgumentList(
|
||||||
webidl::ast::ArgumentListExtendedAttribute { arguments, name },
|
webidl::ast::ArgumentListExtendedAttribute { arguments, name },
|
||||||
) if name == "Constructor" =>
|
)
|
||||||
|
if name == "Constructor" =>
|
||||||
{
|
{
|
||||||
add_constructor(arguments, &interface.name)
|
add_constructor(arguments, &interface.name)
|
||||||
}
|
}
|
||||||
@ -358,7 +359,8 @@ impl<'a> WebidlParse<&'a webidl::ast::NonPartialInterface> for webidl::ast::Exte
|
|||||||
rhs_arguments,
|
rhs_arguments,
|
||||||
rhs_name,
|
rhs_name,
|
||||||
},
|
},
|
||||||
) if lhs_name == "NamedConstructor" =>
|
)
|
||||||
|
if lhs_name == "NamedConstructor" =>
|
||||||
{
|
{
|
||||||
add_constructor(rhs_arguments, rhs_name)
|
add_constructor(rhs_arguments, rhs_name)
|
||||||
}
|
}
|
||||||
@ -389,9 +391,11 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::InterfaceMember {
|
|||||||
webidl::ast::InterfaceMember::Operation(op) => {
|
webidl::ast::InterfaceMember::Operation(op) => {
|
||||||
op.webidl_parse(program, first_pass, self_name)
|
op.webidl_parse(program, first_pass, self_name)
|
||||||
}
|
}
|
||||||
|
webidl::ast::InterfaceMember::Const(cnst) => {
|
||||||
|
cnst.webidl_parse(program, first_pass, self_name)
|
||||||
|
}
|
||||||
// TODO
|
// TODO
|
||||||
webidl::ast::InterfaceMember::Const(_)
|
webidl::ast::InterfaceMember::Iterable(_)
|
||||||
| webidl::ast::InterfaceMember::Iterable(_)
|
|
||||||
| webidl::ast::InterfaceMember::Maplike(_)
|
| webidl::ast::InterfaceMember::Maplike(_)
|
||||||
| webidl::ast::InterfaceMember::Setlike(_) => {
|
| webidl::ast::InterfaceMember::Setlike(_) => {
|
||||||
warn!("Unsupported WebIDL interface member: {:?}", self);
|
warn!("Unsupported WebIDL interface member: {:?}", self);
|
||||||
@ -637,3 +641,29 @@ impl<'a> WebidlParse<()> for webidl::ast::Enum {
|
|||||||
Ok(())
|
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()
|
}.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 {
|
fn simple_fn_arg(ident: Ident, ty: syn::Type) -> syn::ArgCaptured {
|
||||||
syn::ArgCaptured {
|
syn::ArgCaptured {
|
||||||
pat: syn::Pat::Ident(syn::PatIdent {
|
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;
|
extern crate wasm_bindgen_test_project_builder as project_builder;
|
||||||
use project_builder::project;
|
use project_builder::project;
|
||||||
|
|
||||||
mod simple;
|
mod consts;
|
||||||
mod enums;
|
mod enums;
|
||||||
|
mod simple;
|
||||||
mod throws;
|
mod throws;
|
||||||
|
@ -14,7 +14,7 @@ development.
|
|||||||
|
|
||||||
[install Rust]: https://www.rust-lang.org/en-US/install.html
|
[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].
|
as that is when WebAssembly support was introduced. [Install Node].
|
||||||
|
|
||||||
[Install Node]: https://nodejs.org/en/
|
[Install Node]: https://nodejs.org/en/
|
||||||
|
@ -9,13 +9,13 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^10.5.2",
|
"@types/node": "^10.5.2",
|
||||||
"babel-eslint": "^8.2.5",
|
"babel-eslint": "^8.2.6",
|
||||||
"eslint": "^5.1.0",
|
"eslint": "^5.1.0",
|
||||||
"geckodriver": "^1.11.0",
|
"geckodriver": "^1.11.0",
|
||||||
"selenium-webdriver": "^4.0.0-alpha.1",
|
"selenium-webdriver": "^4.0.0-alpha.1",
|
||||||
"ts-loader": "^4.4.2",
|
"ts-loader": "^4.4.2",
|
||||||
"typescript": "^2.7.2",
|
"typescript": "^2.7.2",
|
||||||
"webpack": "^4.15.1",
|
"webpack": "^4.16.0",
|
||||||
"webpack-cli": "^3.0.8",
|
"webpack-cli": "^3.0.8",
|
||||||
"webpack-dev-server": "^3.1.4"
|
"webpack-dev-server": "^3.1.4"
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,6 @@ pub trait RefMutFromWasmAbi: WasmDescribe {
|
|||||||
|
|
||||||
pub trait Stack {
|
pub trait Stack {
|
||||||
fn push(&mut self, bits: u32);
|
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
|
/// An unsafe trait which represents types that are ABI-safe to pass via wasm
|
||||||
@ -105,11 +104,15 @@ macro_rules! simple {
|
|||||||
($($t:tt)*) => ($(
|
($($t:tt)*) => ($(
|
||||||
impl IntoWasmAbi for $t {
|
impl IntoWasmAbi for $t {
|
||||||
type Abi = $t;
|
type Abi = $t;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn into_abi(self, _extra: &mut Stack) -> $t { self }
|
fn into_abi(self, _extra: &mut Stack) -> $t { self }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromWasmAbi for $t {
|
impl FromWasmAbi for $t {
|
||||||
type Abi = $t;
|
type Abi = $t;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn from_abi(js: $t, _extra: &mut Stack) -> $t { js }
|
unsafe fn from_abi(js: $t, _extra: &mut Stack) -> $t { js }
|
||||||
}
|
}
|
||||||
)*)
|
)*)
|
||||||
@ -121,6 +124,8 @@ macro_rules! sixtyfour {
|
|||||||
($($t:tt)*) => ($(
|
($($t:tt)*) => ($(
|
||||||
impl IntoWasmAbi for $t {
|
impl IntoWasmAbi for $t {
|
||||||
type Abi = WasmSlice;
|
type Abi = WasmSlice;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn into_abi(self, _extra: &mut Stack) -> WasmSlice {
|
fn into_abi(self, _extra: &mut Stack) -> WasmSlice {
|
||||||
WasmSlice {
|
WasmSlice {
|
||||||
ptr: self as u32,
|
ptr: self as u32,
|
||||||
@ -131,6 +136,8 @@ macro_rules! sixtyfour {
|
|||||||
|
|
||||||
impl FromWasmAbi for $t {
|
impl FromWasmAbi for $t {
|
||||||
type Abi = WasmSlice;
|
type Abi = WasmSlice;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn from_abi(js: WasmSlice, _extra: &mut Stack) -> $t {
|
unsafe fn from_abi(js: WasmSlice, _extra: &mut Stack) -> $t {
|
||||||
(js.ptr as $t) | ((js.len as $t) << 32)
|
(js.ptr as $t) | ((js.len as $t) << 32)
|
||||||
}
|
}
|
||||||
@ -144,11 +151,15 @@ macro_rules! as_u32 {
|
|||||||
($($t:tt)*) => ($(
|
($($t:tt)*) => ($(
|
||||||
impl IntoWasmAbi for $t {
|
impl IntoWasmAbi for $t {
|
||||||
type Abi = u32;
|
type Abi = u32;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn into_abi(self, _extra: &mut Stack) -> u32 { self as u32 }
|
fn into_abi(self, _extra: &mut Stack) -> u32 { self as u32 }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromWasmAbi for $t {
|
impl FromWasmAbi for $t {
|
||||||
type Abi = u32;
|
type Abi = u32;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn from_abi(js: u32, _extra: &mut Stack) -> $t { js as $t }
|
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 {
|
impl IntoWasmAbi for bool {
|
||||||
type Abi = u32;
|
type Abi = u32;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn into_abi(self, _extra: &mut Stack) -> u32 {
|
fn into_abi(self, _extra: &mut Stack) -> u32 {
|
||||||
self as u32
|
self as u32
|
||||||
}
|
}
|
||||||
@ -167,6 +179,7 @@ impl IntoWasmAbi for bool {
|
|||||||
impl FromWasmAbi for bool {
|
impl FromWasmAbi for bool {
|
||||||
type Abi = u32;
|
type Abi = u32;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn from_abi(js: u32, _extra: &mut Stack) -> bool {
|
unsafe fn from_abi(js: u32, _extra: &mut Stack) -> bool {
|
||||||
js != 0
|
js != 0
|
||||||
}
|
}
|
||||||
@ -174,6 +187,8 @@ impl FromWasmAbi for bool {
|
|||||||
|
|
||||||
impl IntoWasmAbi for char {
|
impl IntoWasmAbi for char {
|
||||||
type Abi = u32;
|
type Abi = u32;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn into_abi(self, _extra: &mut Stack) -> u32 {
|
fn into_abi(self, _extra: &mut Stack) -> u32 {
|
||||||
self as u32
|
self as u32
|
||||||
}
|
}
|
||||||
@ -181,6 +196,8 @@ impl IntoWasmAbi for char {
|
|||||||
|
|
||||||
impl FromWasmAbi for char {
|
impl FromWasmAbi for char {
|
||||||
type Abi = u32;
|
type Abi = u32;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn from_abi(js: u32, _extra: &mut Stack) -> char {
|
unsafe fn from_abi(js: u32, _extra: &mut Stack) -> char {
|
||||||
char::from_u32_unchecked(js)
|
char::from_u32_unchecked(js)
|
||||||
}
|
}
|
||||||
@ -224,6 +241,7 @@ macro_rules! vectors {
|
|||||||
impl IntoWasmAbi for Box<[$t]> {
|
impl IntoWasmAbi for Box<[$t]> {
|
||||||
type Abi = WasmSlice;
|
type Abi = WasmSlice;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn into_abi(self, extra: &mut Stack) -> WasmSlice {
|
fn into_abi(self, extra: &mut Stack) -> WasmSlice {
|
||||||
let ptr = self.as_ptr();
|
let ptr = self.as_ptr();
|
||||||
let len = self.len();
|
let len = self.len();
|
||||||
@ -239,6 +257,7 @@ macro_rules! vectors {
|
|||||||
impl FromWasmAbi for Box<[$t]> {
|
impl FromWasmAbi for Box<[$t]> {
|
||||||
type Abi = WasmSlice;
|
type Abi = WasmSlice;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn from_abi(js: WasmSlice, extra: &mut Stack) -> Self {
|
unsafe fn from_abi(js: WasmSlice, extra: &mut Stack) -> Self {
|
||||||
let ptr = <*mut $t>::from_abi(js.ptr, extra);
|
let ptr = <*mut $t>::from_abi(js.ptr, extra);
|
||||||
let len = js.len as usize;
|
let len = js.len as usize;
|
||||||
@ -249,6 +268,7 @@ macro_rules! vectors {
|
|||||||
impl<'a> IntoWasmAbi for &'a [$t] {
|
impl<'a> IntoWasmAbi for &'a [$t] {
|
||||||
type Abi = WasmSlice;
|
type Abi = WasmSlice;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn into_abi(self, extra: &mut Stack) -> WasmSlice {
|
fn into_abi(self, extra: &mut Stack) -> WasmSlice {
|
||||||
WasmSlice {
|
WasmSlice {
|
||||||
ptr: self.as_ptr().into_abi(extra),
|
ptr: self.as_ptr().into_abi(extra),
|
||||||
@ -260,6 +280,7 @@ macro_rules! vectors {
|
|||||||
impl<'a> IntoWasmAbi for &'a mut [$t] {
|
impl<'a> IntoWasmAbi for &'a mut [$t] {
|
||||||
type Abi = WasmSlice;
|
type Abi = WasmSlice;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn into_abi(self, extra: &mut Stack) -> WasmSlice {
|
fn into_abi(self, extra: &mut Stack) -> WasmSlice {
|
||||||
(&*self).into_abi(extra)
|
(&*self).into_abi(extra)
|
||||||
}
|
}
|
||||||
@ -269,6 +290,7 @@ macro_rules! vectors {
|
|||||||
type Abi = WasmSlice;
|
type Abi = WasmSlice;
|
||||||
type Anchor = &'static [$t];
|
type Anchor = &'static [$t];
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn ref_from_abi(js: WasmSlice, extra: &mut Stack) -> &'static [$t] {
|
unsafe fn ref_from_abi(js: WasmSlice, extra: &mut Stack) -> &'static [$t] {
|
||||||
slice::from_raw_parts(
|
slice::from_raw_parts(
|
||||||
<*const $t>::from_abi(js.ptr, extra),
|
<*const $t>::from_abi(js.ptr, extra),
|
||||||
@ -281,6 +303,7 @@ macro_rules! vectors {
|
|||||||
type Abi = WasmSlice;
|
type Abi = WasmSlice;
|
||||||
type Anchor = &'static mut [$t];
|
type Anchor = &'static mut [$t];
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn ref_mut_from_abi(js: WasmSlice, extra: &mut Stack)
|
unsafe fn ref_mut_from_abi(js: WasmSlice, extra: &mut Stack)
|
||||||
-> &'static mut [$t]
|
-> &'static mut [$t]
|
||||||
{
|
{
|
||||||
@ -300,6 +323,7 @@ vectors! {
|
|||||||
if_std! {
|
if_std! {
|
||||||
impl<T> IntoWasmAbi for Vec<T> where Box<[T]>: IntoWasmAbi {
|
impl<T> IntoWasmAbi for Vec<T> where Box<[T]>: IntoWasmAbi {
|
||||||
type Abi = <Box<[T]> as IntoWasmAbi>::Abi;
|
type Abi = <Box<[T]> as IntoWasmAbi>::Abi;
|
||||||
|
|
||||||
fn into_abi(self, extra: &mut Stack) -> Self::Abi {
|
fn into_abi(self, extra: &mut Stack) -> Self::Abi {
|
||||||
self.into_boxed_slice().into_abi(extra)
|
self.into_boxed_slice().into_abi(extra)
|
||||||
}
|
}
|
||||||
@ -316,6 +340,7 @@ if_std! {
|
|||||||
impl IntoWasmAbi for String {
|
impl IntoWasmAbi for String {
|
||||||
type Abi = <Vec<u8> as IntoWasmAbi>::Abi;
|
type Abi = <Vec<u8> as IntoWasmAbi>::Abi;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn into_abi(self, extra: &mut Stack) -> Self::Abi {
|
fn into_abi(self, extra: &mut Stack) -> Self::Abi {
|
||||||
self.into_bytes().into_abi(extra)
|
self.into_bytes().into_abi(extra)
|
||||||
}
|
}
|
||||||
@ -324,6 +349,7 @@ if_std! {
|
|||||||
impl FromWasmAbi for String {
|
impl FromWasmAbi for String {
|
||||||
type Abi = <Vec<u8> as FromWasmAbi>::Abi;
|
type Abi = <Vec<u8> as FromWasmAbi>::Abi;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn from_abi(js: Self::Abi, extra: &mut Stack) -> Self {
|
unsafe fn from_abi(js: Self::Abi, extra: &mut Stack) -> Self {
|
||||||
String::from_utf8_unchecked(<Vec<u8>>::from_abi(js, extra))
|
String::from_utf8_unchecked(<Vec<u8>>::from_abi(js, extra))
|
||||||
}
|
}
|
||||||
@ -333,6 +359,7 @@ if_std! {
|
|||||||
impl<'a> IntoWasmAbi for &'a str {
|
impl<'a> IntoWasmAbi for &'a str {
|
||||||
type Abi = <&'a [u8] as IntoWasmAbi>::Abi;
|
type Abi = <&'a [u8] as IntoWasmAbi>::Abi;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn into_abi(self, extra: &mut Stack) -> Self::Abi {
|
fn into_abi(self, extra: &mut Stack) -> Self::Abi {
|
||||||
self.as_bytes().into_abi(extra)
|
self.as_bytes().into_abi(extra)
|
||||||
}
|
}
|
||||||
@ -342,6 +369,7 @@ impl RefFromWasmAbi for str {
|
|||||||
type Abi = <[u8] as RefFromWasmAbi>::Abi;
|
type Abi = <[u8] as RefFromWasmAbi>::Abi;
|
||||||
type Anchor = &'static str;
|
type Anchor = &'static str;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn ref_from_abi(js: Self::Abi, extra: &mut Stack) -> Self::Anchor {
|
unsafe fn ref_from_abi(js: Self::Abi, extra: &mut Stack) -> Self::Anchor {
|
||||||
str::from_utf8_unchecked(<[u8]>::ref_from_abi(js, extra))
|
str::from_utf8_unchecked(<[u8]>::ref_from_abi(js, extra))
|
||||||
}
|
}
|
||||||
@ -350,6 +378,7 @@ impl RefFromWasmAbi for str {
|
|||||||
impl IntoWasmAbi for JsValue {
|
impl IntoWasmAbi for JsValue {
|
||||||
type Abi = u32;
|
type Abi = u32;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn into_abi(self, _extra: &mut Stack) -> u32 {
|
fn into_abi(self, _extra: &mut Stack) -> u32 {
|
||||||
let ret = self.idx;
|
let ret = self.idx;
|
||||||
mem::forget(self);
|
mem::forget(self);
|
||||||
@ -360,6 +389,7 @@ impl IntoWasmAbi for JsValue {
|
|||||||
impl FromWasmAbi for JsValue {
|
impl FromWasmAbi for JsValue {
|
||||||
type Abi = u32;
|
type Abi = u32;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn from_abi(js: u32, _extra: &mut Stack) -> JsValue {
|
unsafe fn from_abi(js: u32, _extra: &mut Stack) -> JsValue {
|
||||||
JsValue { idx: js }
|
JsValue { idx: js }
|
||||||
}
|
}
|
||||||
@ -367,6 +397,8 @@ impl FromWasmAbi for JsValue {
|
|||||||
|
|
||||||
impl<'a> IntoWasmAbi for &'a JsValue {
|
impl<'a> IntoWasmAbi for &'a JsValue {
|
||||||
type Abi = u32;
|
type Abi = u32;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn into_abi(self, _extra: &mut Stack) -> u32 {
|
fn into_abi(self, _extra: &mut Stack) -> u32 {
|
||||||
self.idx
|
self.idx
|
||||||
}
|
}
|
||||||
@ -376,6 +408,7 @@ impl RefFromWasmAbi for JsValue {
|
|||||||
type Abi = u32;
|
type Abi = u32;
|
||||||
type Anchor = ManuallyDrop<JsValue>;
|
type Anchor = ManuallyDrop<JsValue>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn ref_from_abi(js: u32, _extra: &mut Stack) -> Self::Anchor {
|
unsafe fn ref_from_abi(js: u32, _extra: &mut Stack) -> Self::Anchor {
|
||||||
ManuallyDrop::new(JsValue { idx: js })
|
ManuallyDrop::new(JsValue { idx: js })
|
||||||
}
|
}
|
||||||
@ -385,6 +418,7 @@ if_std! {
|
|||||||
impl IntoWasmAbi for Box<[JsValue]> {
|
impl IntoWasmAbi for Box<[JsValue]> {
|
||||||
type Abi = WasmSlice;
|
type Abi = WasmSlice;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn into_abi(self, extra: &mut Stack) -> WasmSlice {
|
fn into_abi(self, extra: &mut Stack) -> WasmSlice {
|
||||||
let ptr = self.as_ptr();
|
let ptr = self.as_ptr();
|
||||||
let len = self.len();
|
let len = self.len();
|
||||||
@ -399,6 +433,7 @@ if_std! {
|
|||||||
impl FromWasmAbi for Box<[JsValue]> {
|
impl FromWasmAbi for Box<[JsValue]> {
|
||||||
type Abi = WasmSlice;
|
type Abi = WasmSlice;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn from_abi(js: WasmSlice, extra: &mut Stack) -> Self {
|
unsafe fn from_abi(js: WasmSlice, extra: &mut Stack) -> Self {
|
||||||
let ptr = <*mut JsValue>::from_abi(js.ptr, extra);
|
let ptr = <*mut JsValue>::from_abi(js.ptr, extra);
|
||||||
let len = js.len as usize;
|
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];
|
static mut GLOBAL_STACK: [u32; GLOBAL_STACK_CAP] = [0; GLOBAL_STACK_CAP];
|
||||||
|
|
||||||
impl GlobalStack {
|
impl GlobalStack {
|
||||||
|
#[inline]
|
||||||
pub unsafe fn new() -> GlobalStack {
|
pub unsafe fn new() -> GlobalStack {
|
||||||
GlobalStack { next: 0 }
|
GlobalStack { next: 0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stack for GlobalStack {
|
impl Stack for GlobalStack {
|
||||||
|
#[inline]
|
||||||
fn push(&mut self, val: u32) {
|
fn push(&mut self, val: u32) {
|
||||||
unsafe {
|
unsafe {
|
||||||
assert!(self.next < GLOBAL_STACK_CAP);
|
assert!(self.next < GLOBAL_STACK_CAP);
|
||||||
@ -428,15 +465,6 @@ impl Stack for GlobalStack {
|
|||||||
self.next += 1;
|
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)]
|
#[doc(hidden)]
|
||||||
|
160
src/js.rs
160
src/js.rs
@ -240,6 +240,20 @@ extern "C" {
|
|||||||
#[wasm_bindgen(method)]
|
#[wasm_bindgen(method)]
|
||||||
pub fn push(this: &Array, value: JsValue) -> u32;
|
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
|
/// The reverse() method reverses an array in place. The first array
|
||||||
/// element becomes the last, and the last array element becomes the first.
|
/// 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;
|
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
|
// Error
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
extern "C" {
|
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`
|
//! this crate and this crate also provides JS bindings through the `JsValue`
|
||||||
//! interface.
|
//! 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))]
|
#![cfg_attr(feature = "js_globals", feature(proc_macro, wasm_custom_section))]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
@ -661,24 +661,29 @@ pub mod __rt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if_std! {
|
if_std! {
|
||||||
use std::prelude::v1::*;
|
use std::alloc::{System, GlobalAlloc, Layout};
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn __wbindgen_malloc(size: usize) -> *mut u8 {
|
pub extern fn __wbindgen_malloc(size: usize) -> *mut u8 {
|
||||||
use core::mem;
|
let align = mem::align_of::<usize>();
|
||||||
|
if let Ok(layout) = Layout::from_size_align(size, align) {
|
||||||
let mut ret = Vec::new();
|
unsafe {
|
||||||
if ret.try_reserve_exact(size).is_err() {
|
let ptr = System.alloc(layout);
|
||||||
super::throw("invalid malloc request");
|
if !ptr.is_null() {
|
||||||
|
return ptr
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let ptr = ret.as_mut_ptr();
|
|
||||||
mem::forget(ret);
|
super::throw("invalid malloc request");
|
||||||
return ptr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern fn __wbindgen_free(ptr: *mut u8, size: usize) {
|
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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[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 ArrayBuffer;
|
||||||
mod ArrayIterator;
|
mod ArrayIterator;
|
||||||
mod Boolean;
|
mod Boolean;
|
||||||
|
mod DataView;
|
||||||
mod Date;
|
mod Date;
|
||||||
mod Error;
|
mod Error;
|
||||||
mod Function;
|
mod Function;
|
||||||
|
16
yarn.lock
16
yarn.lock
@ -408,15 +408,15 @@ babel-code-frame@^6.26.0:
|
|||||||
esutils "^2.0.2"
|
esutils "^2.0.2"
|
||||||
js-tokens "^3.0.2"
|
js-tokens "^3.0.2"
|
||||||
|
|
||||||
babel-eslint@^8.2.5:
|
babel-eslint@^8.2.6:
|
||||||
version "8.2.5"
|
version "8.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.5.tgz#dc2331c259d36782aa189da510c43dedd5adc7a3"
|
resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.6.tgz#6270d0c73205628067c0f7ae1693a9e797acefd9"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/code-frame" "7.0.0-beta.44"
|
"@babel/code-frame" "7.0.0-beta.44"
|
||||||
"@babel/traverse" "7.0.0-beta.44"
|
"@babel/traverse" "7.0.0-beta.44"
|
||||||
"@babel/types" "7.0.0-beta.44"
|
"@babel/types" "7.0.0-beta.44"
|
||||||
babylon "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"
|
eslint-visitor-keys "^1.0.0"
|
||||||
|
|
||||||
babylon@7.0.0-beta.44:
|
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"
|
version "1.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
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"
|
version "3.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8"
|
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -4150,9 +4150,9 @@ webpack-sources@^1.0.1, webpack-sources@^1.1.0:
|
|||||||
source-list-map "^2.0.0"
|
source-list-map "^2.0.0"
|
||||||
source-map "~0.6.1"
|
source-map "~0.6.1"
|
||||||
|
|
||||||
webpack@^4.15.1:
|
webpack@^4.16.0:
|
||||||
version "4.15.1"
|
version "4.16.0"
|
||||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.15.1.tgz#dc716779a3b88827c369f18c71a6137fa7e582fd"
|
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.16.0.tgz#660dae90890e55b8ed17c6f9d17bebb01dab5b4c"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@webassemblyjs/ast" "1.5.13"
|
"@webassemblyjs/ast" "1.5.13"
|
||||||
"@webassemblyjs/helper-module-context" "1.5.13"
|
"@webassemblyjs/helper-module-context" "1.5.13"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user