mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-11 20:11:22 +00:00
Run rustfmt over everything
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
use Diagnostic;
|
||||
use proc_macro2::{Ident, Span};
|
||||
use shared;
|
||||
use syn;
|
||||
use Diagnostic;
|
||||
|
||||
/// An abstract syntax tree representing a rust program. Contains
|
||||
/// extra information for joining up this rust code with javascript.
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::collections::HashSet;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
|
||||
use std::sync::Mutex;
|
||||
|
||||
use proc_macro2::{Ident, Literal, Span, TokenStream};
|
||||
use quote::ToTokens;
|
||||
@ -89,9 +89,11 @@ impl TryToTokens for ast::Program {
|
||||
|
||||
// See comments in `crates/cli-support/src/lib.rs` about what this
|
||||
// `schema_version` is.
|
||||
let prefix_json = format!(r#"{{"schema_version":"{}","version":"{}"}}"#,
|
||||
shared::SCHEMA_VERSION,
|
||||
shared::version());
|
||||
let prefix_json = format!(
|
||||
r#"{{"schema_version":"{}","version":"{}"}}"#,
|
||||
shared::SCHEMA_VERSION,
|
||||
shared::version()
|
||||
);
|
||||
let mut bytes = Vec::new();
|
||||
bytes.push((prefix_json.len() >> 0) as u8);
|
||||
bytes.push((prefix_json.len() >> 8) as u8);
|
||||
@ -110,7 +112,8 @@ impl TryToTokens for ast::Program {
|
||||
#[doc(hidden)]
|
||||
pub static #generated_static_name: [u8; #generated_static_length] =
|
||||
*#generated_static_value;
|
||||
}).to_tokens(tokens);
|
||||
})
|
||||
.to_tokens(tokens);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -237,7 +240,8 @@ impl ToTokens for ast::Struct {
|
||||
(*js).borrow_mut()
|
||||
}
|
||||
}
|
||||
}).to_tokens(tokens);
|
||||
})
|
||||
.to_tokens(tokens);
|
||||
|
||||
for field in self.fields.iter() {
|
||||
field.to_tokens(tokens);
|
||||
@ -273,14 +277,16 @@ impl ToTokens for ast::StructField {
|
||||
&mut GlobalStack::new(),
|
||||
)
|
||||
}
|
||||
}).to_tokens(tokens);
|
||||
})
|
||||
.to_tokens(tokens);
|
||||
|
||||
Descriptor(
|
||||
&getter,
|
||||
quote! {
|
||||
<#ty as WasmDescribe>::describe();
|
||||
},
|
||||
).to_tokens(tokens);
|
||||
)
|
||||
.to_tokens(tokens);
|
||||
|
||||
if self.readonly {
|
||||
return;
|
||||
@ -305,7 +311,8 @@ impl ToTokens for ast::StructField {
|
||||
);
|
||||
(*js).borrow_mut().#name = val;
|
||||
}
|
||||
}).to_tokens(tokens);
|
||||
})
|
||||
.to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
|
||||
@ -461,7 +468,8 @@ impl TryToTokens for ast::Export {
|
||||
};
|
||||
#convert_ret
|
||||
}
|
||||
}).to_tokens(into);
|
||||
})
|
||||
.to_tokens(into);
|
||||
|
||||
// In addition to generating the shim function above which is what
|
||||
// our generated JS will invoke, we *also* generate a "descriptor"
|
||||
@ -488,7 +496,8 @@ impl TryToTokens for ast::Export {
|
||||
#(<#argtys as WasmDescribe>::describe();)*
|
||||
#describe_ret
|
||||
},
|
||||
).to_tokens(into);
|
||||
)
|
||||
.to_tokens(into);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -670,7 +679,8 @@ impl ToTokens for ast::ImportType {
|
||||
self.as_ref()
|
||||
}
|
||||
}
|
||||
}).to_tokens(tokens);
|
||||
})
|
||||
.to_tokens(tokens);
|
||||
for superclass in self.extends.iter() {
|
||||
(quote! {
|
||||
impl From<#rust_name> for #superclass {
|
||||
@ -688,7 +698,8 @@ impl ToTokens for ast::ImportType {
|
||||
#superclass::unchecked_from_js_ref(self.as_ref())
|
||||
}
|
||||
}
|
||||
}).to_tokens(tokens);
|
||||
})
|
||||
.to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -709,7 +720,8 @@ impl ToTokens for ast::ImportEnum {
|
||||
let this_index = current_idx;
|
||||
current_idx += 1;
|
||||
Literal::usize_unsuffixed(this_index)
|
||||
}).collect();
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Borrow variant_indexes because we need to use it multiple times inside the quote! macro
|
||||
let variant_indexes_ref = &variant_indexes;
|
||||
@ -946,7 +958,8 @@ impl TryToTokens for ast::ImportFunction {
|
||||
impl #class {
|
||||
#invocation
|
||||
}
|
||||
}).to_tokens(tokens);
|
||||
})
|
||||
.to_tokens(tokens);
|
||||
} else {
|
||||
invocation.to_tokens(tokens);
|
||||
}
|
||||
@ -981,7 +994,8 @@ impl<'a> ToTokens for DescribeImport<'a> {
|
||||
#(<#argtys as WasmDescribe>::describe();)*
|
||||
#inform_ret
|
||||
},
|
||||
).to_tokens(tokens);
|
||||
)
|
||||
.to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1025,7 +1039,8 @@ impl ToTokens for ast::Enum {
|
||||
inform(ENUM);
|
||||
}
|
||||
}
|
||||
}).to_tokens(into);
|
||||
})
|
||||
.to_tokens(into);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1061,7 +1076,8 @@ impl ToTokens for ast::ImportStatic {
|
||||
__inner: &_VAL,
|
||||
}
|
||||
};
|
||||
}).to_tokens(into);
|
||||
})
|
||||
.to_tokens(into);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1106,7 +1122,8 @@ impl ToTokens for ast::Const {
|
||||
impl #class {
|
||||
#declaration
|
||||
}
|
||||
}).to_tokens(tokens);
|
||||
})
|
||||
.to_tokens(tokens);
|
||||
} else {
|
||||
declaration.to_tokens(tokens);
|
||||
}
|
||||
@ -1247,7 +1264,8 @@ impl ToTokens for ast::Dictionary {
|
||||
}
|
||||
}
|
||||
};
|
||||
}).to_tokens(tokens);
|
||||
})
|
||||
.to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1309,6 +1327,7 @@ impl<'a, T: ToTokens> ToTokens for Descriptor<'a, T> {
|
||||
::wasm_bindgen::__rt::link_mem_intrinsics();
|
||||
#inner
|
||||
}
|
||||
}).to_tokens(tokens);
|
||||
})
|
||||
.to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ use std::collections::HashMap;
|
||||
|
||||
use proc_macro2::{Ident, Span};
|
||||
|
||||
use Diagnostic;
|
||||
use ast;
|
||||
use Diagnostic;
|
||||
|
||||
pub fn encode(program: &ast::Program) -> Result<Vec<u8>, Diagnostic> {
|
||||
let mut e = Encoder::new();
|
||||
@ -19,13 +19,15 @@ struct Interner {
|
||||
|
||||
impl Interner {
|
||||
fn new() -> Interner {
|
||||
Interner { map: RefCell::new(HashMap::new()) }
|
||||
Interner {
|
||||
map: RefCell::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
|
||||
fn intern(&self, s: &Ident) -> &str {
|
||||
let mut map = self.map.borrow_mut();
|
||||
if let Some(s) = map.get(s) {
|
||||
return unsafe { &*(&**s as *const str) }
|
||||
return unsafe { &*(&**s as *const str) };
|
||||
}
|
||||
map.insert(s.clone(), s.to_string());
|
||||
unsafe { &*(&*map[s] as *const str) }
|
||||
@ -36,17 +38,32 @@ impl Interner {
|
||||
}
|
||||
}
|
||||
|
||||
fn shared_program<'a>(prog: &'a ast::Program, intern: &'a Interner)
|
||||
-> Result<Program<'a>, Diagnostic>
|
||||
{
|
||||
fn shared_program<'a>(
|
||||
prog: &'a ast::Program,
|
||||
intern: &'a Interner,
|
||||
) -> Result<Program<'a>, Diagnostic> {
|
||||
Ok(Program {
|
||||
exports: prog.exports.iter().map(|a| shared_export(a, intern)).collect(),
|
||||
structs: prog.structs.iter().map(|a| shared_struct(a, intern)).collect(),
|
||||
exports: prog
|
||||
.exports
|
||||
.iter()
|
||||
.map(|a| shared_export(a, intern))
|
||||
.collect(),
|
||||
structs: prog
|
||||
.structs
|
||||
.iter()
|
||||
.map(|a| shared_struct(a, intern))
|
||||
.collect(),
|
||||
enums: prog.enums.iter().map(|a| shared_enum(a, intern)).collect(),
|
||||
imports: prog.imports.iter()
|
||||
imports: prog
|
||||
.imports
|
||||
.iter()
|
||||
.map(|a| shared_import(a, intern))
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
typescript_custom_sections: prog.typescript_custom_sections.iter().map(|x| -> &'a str { &x }).collect(),
|
||||
typescript_custom_sections: prog
|
||||
.typescript_custom_sections
|
||||
.iter()
|
||||
.map(|x| -> &'a str { &x })
|
||||
.collect(),
|
||||
// version: shared::version(),
|
||||
// schema_version: shared::SCHEMA_VERSION.to_string(),
|
||||
})
|
||||
@ -69,15 +86,17 @@ fn shared_export<'a>(export: &'a ast::Export, intern: &'a Interner) -> Export<'a
|
||||
}
|
||||
|
||||
fn shared_function<'a>(func: &'a ast::Function, _intern: &'a Interner) -> Function<'a> {
|
||||
Function {
|
||||
name: &func.name,
|
||||
}
|
||||
Function { name: &func.name }
|
||||
}
|
||||
|
||||
fn shared_enum<'a>(e: &'a ast::Enum, intern: &'a Interner) -> Enum<'a> {
|
||||
Enum {
|
||||
name: intern.intern(&e.name),
|
||||
variants: e.variants.iter().map(|v| shared_variant(v, intern)).collect(),
|
||||
variants: e
|
||||
.variants
|
||||
.iter()
|
||||
.map(|v| shared_variant(v, intern))
|
||||
.collect(),
|
||||
comments: e.comments.iter().map(|s| &**s).collect(),
|
||||
}
|
||||
}
|
||||
@ -89,9 +108,7 @@ fn shared_variant<'a>(v: &'a ast::Variant, intern: &'a Interner) -> EnumVariant<
|
||||
}
|
||||
}
|
||||
|
||||
fn shared_import<'a>(i: &'a ast::Import, intern: &'a Interner)
|
||||
-> Result<Import<'a>, Diagnostic>
|
||||
{
|
||||
fn shared_import<'a>(i: &'a ast::Import, intern: &'a Interner) -> Result<Import<'a>, Diagnostic> {
|
||||
Ok(Import {
|
||||
module: i.module.as_ref().map(|s| &**s),
|
||||
js_namespace: i.js_namespace.as_ref().map(|s| intern.intern(s)),
|
||||
@ -99,9 +116,10 @@ fn shared_import<'a>(i: &'a ast::Import, intern: &'a Interner)
|
||||
})
|
||||
}
|
||||
|
||||
fn shared_import_kind<'a>(i: &'a ast::ImportKind, intern: &'a Interner)
|
||||
-> Result<ImportKind<'a>, Diagnostic>
|
||||
{
|
||||
fn shared_import_kind<'a>(
|
||||
i: &'a ast::ImportKind,
|
||||
intern: &'a Interner,
|
||||
) -> Result<ImportKind<'a>, Diagnostic> {
|
||||
Ok(match i {
|
||||
ast::ImportKind::Function(f) => ImportKind::Function(shared_import_function(f, intern)?),
|
||||
ast::ImportKind::Static(f) => ImportKind::Static(shared_import_static(f, intern)),
|
||||
@ -110,11 +128,12 @@ fn shared_import_kind<'a>(i: &'a ast::ImportKind, intern: &'a Interner)
|
||||
})
|
||||
}
|
||||
|
||||
fn shared_import_function<'a>(i: &'a ast::ImportFunction, intern: &'a Interner)
|
||||
-> Result<ImportFunction<'a>, Diagnostic>
|
||||
{
|
||||
fn shared_import_function<'a>(
|
||||
i: &'a ast::ImportFunction,
|
||||
intern: &'a Interner,
|
||||
) -> Result<ImportFunction<'a>, Diagnostic> {
|
||||
let method = match &i.kind {
|
||||
ast::ImportFunctionKind::Method { class, kind, .. } => {
|
||||
ast::ImportFunctionKind::Method { class, kind, .. } => {
|
||||
let kind = match kind {
|
||||
ast::MethodKind::Constructor => MethodKind::Constructor,
|
||||
ast::MethodKind::Operation(ast::Operation { is_static, kind }) => {
|
||||
@ -123,9 +142,7 @@ fn shared_import_function<'a>(i: &'a ast::ImportFunction, intern: &'a Interner)
|
||||
ast::OperationKind::Regular => OperationKind::Regular,
|
||||
ast::OperationKind::Getter(g) => {
|
||||
let g = g.as_ref().map(|g| intern.intern(g));
|
||||
OperationKind::Getter(
|
||||
g.unwrap_or_else(|| i.infer_getter_property()),
|
||||
)
|
||||
OperationKind::Getter(g.unwrap_or_else(|| i.infer_getter_property()))
|
||||
}
|
||||
ast::OperationKind::Setter(s) => {
|
||||
let s = s.as_ref().map(|s| intern.intern(s));
|
||||
@ -141,10 +158,7 @@ fn shared_import_function<'a>(i: &'a ast::ImportFunction, intern: &'a Interner)
|
||||
MethodKind::Operation(Operation { is_static, kind })
|
||||
}
|
||||
};
|
||||
Some(MethodData {
|
||||
class,
|
||||
kind,
|
||||
})
|
||||
Some(MethodData { class, kind })
|
||||
}
|
||||
ast::ImportFunctionKind::Normal => None,
|
||||
};
|
||||
@ -159,44 +173,38 @@ fn shared_import_function<'a>(i: &'a ast::ImportFunction, intern: &'a Interner)
|
||||
})
|
||||
}
|
||||
|
||||
fn shared_import_static<'a>(i: &'a ast::ImportStatic, intern: &'a Interner)
|
||||
-> ImportStatic<'a>
|
||||
{
|
||||
fn shared_import_static<'a>(i: &'a ast::ImportStatic, intern: &'a Interner) -> ImportStatic<'a> {
|
||||
ImportStatic {
|
||||
name: &i.js_name,
|
||||
shim: intern.intern(&i.shim),
|
||||
}
|
||||
}
|
||||
|
||||
fn shared_import_type<'a>(i: &'a ast::ImportType, intern: &'a Interner)
|
||||
-> ImportType<'a>
|
||||
{
|
||||
fn shared_import_type<'a>(i: &'a ast::ImportType, intern: &'a Interner) -> ImportType<'a> {
|
||||
ImportType {
|
||||
name: &i.js_name,
|
||||
instanceof_shim: &i.instanceof_shim,
|
||||
vendor_prefixes: i.vendor_prefixes.iter()
|
||||
.map(|x| intern.intern(x))
|
||||
.collect(),
|
||||
vendor_prefixes: i.vendor_prefixes.iter().map(|x| intern.intern(x)).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn shared_import_enum<'a>(_i: &'a ast::ImportEnum, _intern: &'a Interner)
|
||||
-> ImportEnum
|
||||
{
|
||||
fn shared_import_enum<'a>(_i: &'a ast::ImportEnum, _intern: &'a Interner) -> ImportEnum {
|
||||
ImportEnum {}
|
||||
}
|
||||
|
||||
fn shared_struct<'a>(s: &'a ast::Struct, intern: &'a Interner) -> Struct<'a> {
|
||||
Struct {
|
||||
name: &s.js_name,
|
||||
fields: s.fields.iter().map(|s| shared_struct_field(s, intern)).collect(),
|
||||
fields: s
|
||||
.fields
|
||||
.iter()
|
||||
.map(|s| shared_struct_field(s, intern))
|
||||
.collect(),
|
||||
comments: s.comments.iter().map(|s| &**s).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn shared_struct_field<'a>(s: &'a ast::StructField, intern: &'a Interner)
|
||||
-> StructField<'a>
|
||||
{
|
||||
fn shared_struct_field<'a>(s: &'a ast::StructField, intern: &'a Interner) -> StructField<'a> {
|
||||
StructField {
|
||||
name: intern.intern(&s.name),
|
||||
readonly: s.readonly,
|
||||
|
@ -1,8 +1,5 @@
|
||||
#![recursion_limit = "256"]
|
||||
#![cfg_attr(
|
||||
feature = "extra-traits",
|
||||
deny(missing_debug_implementations)
|
||||
)]
|
||||
#![cfg_attr(feature = "extra-traits", deny(missing_debug_implementations))]
|
||||
#![doc(html_root_url = "https://docs.rs/wasm-bindgen-backend/0.2")]
|
||||
|
||||
#[macro_use]
|
||||
@ -25,6 +22,6 @@ mod error;
|
||||
|
||||
pub mod ast;
|
||||
mod codegen;
|
||||
mod encode;
|
||||
pub mod defined;
|
||||
mod encode;
|
||||
pub mod util;
|
||||
|
@ -71,7 +71,8 @@ where
|
||||
.map(|i| syn::PathSegment {
|
||||
ident: i,
|
||||
arguments: syn::PathArguments::None,
|
||||
}).collect();
|
||||
})
|
||||
.collect();
|
||||
|
||||
syn::TypePath {
|
||||
qself: None,
|
||||
@ -83,7 +84,8 @@ where
|
||||
},
|
||||
segments: syn::punctuated::Punctuated::from_iter(segments),
|
||||
},
|
||||
}.into()
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn ident_ty(ident: Ident) -> syn::Type {
|
||||
|
@ -6,14 +6,14 @@ pub trait Decode<'src>: Sized {
|
||||
fn decode_all(mut data: &'src [u8]) -> Self {
|
||||
let ret = Self::decode(&mut data);
|
||||
assert!(data.len() == 0);
|
||||
return ret
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
fn get<'a>(b: &mut &'a [u8]) -> u8 {
|
||||
let r = b[0];
|
||||
*b = &b[1..];
|
||||
return r
|
||||
return r;
|
||||
}
|
||||
|
||||
impl<'src> Decode<'src> for bool {
|
||||
@ -30,7 +30,7 @@ impl<'src> Decode<'src> for u32 {
|
||||
let byte = get(data);
|
||||
cur |= ((byte & 0x7f) as u32) << offset;
|
||||
if byte & 0x80 == 0 {
|
||||
break cur
|
||||
break cur;
|
||||
}
|
||||
offset += 7;
|
||||
}
|
||||
|
@ -44,7 +44,8 @@ pub fn rewrite(input: &mut Context) -> Result<(), Error> {
|
||||
.import_section()
|
||||
.map(|s| s.functions())
|
||||
.unwrap_or(0) as u32,
|
||||
}.remap_module(input.module);
|
||||
}
|
||||
.remap_module(input.module);
|
||||
|
||||
info.delete_function_table_entries(input);
|
||||
info.inject_imports(input)?;
|
||||
@ -236,13 +237,10 @@ impl ClosureDescriptors {
|
||||
.rust_argument("b")
|
||||
.finally("this.a = a;\n");
|
||||
} else {
|
||||
builder.rust_argument("this.a")
|
||||
.rust_argument("b");
|
||||
builder.rust_argument("this.a").rust_argument("b");
|
||||
}
|
||||
builder.finally("if (this.cnt-- == 1) d(this.a, b);");
|
||||
builder
|
||||
.process(&closure.function)?
|
||||
.finish("function", "f")
|
||||
builder.process(&closure.function)?.finish("function", "f")
|
||||
};
|
||||
input.expose_add_heap_object();
|
||||
input.function_table_needed = true;
|
||||
|
@ -329,8 +329,8 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
||||
} else {
|
||||
self.prelude(&format!(
|
||||
"\
|
||||
const ptr{i} = {arg}.ptr;\n\
|
||||
",
|
||||
const ptr{i} = {arg}.ptr;\n\
|
||||
",
|
||||
i = i,
|
||||
arg = name
|
||||
));
|
||||
@ -346,8 +346,8 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
||||
}
|
||||
self.prelude(&format!(
|
||||
"\
|
||||
{arg}.ptr = 0;\n\
|
||||
",
|
||||
{arg}.ptr = 0;\n\
|
||||
",
|
||||
arg = name
|
||||
));
|
||||
self.rust_arguments.push(format!("ptr{}", i));
|
||||
@ -549,7 +549,8 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
||||
self.ret_expr = "
|
||||
const ret = RET;
|
||||
return ret === 0xFFFFFF ? undefined : ret;
|
||||
".to_string();
|
||||
"
|
||||
.to_string();
|
||||
return Ok(self);
|
||||
}
|
||||
|
||||
@ -583,7 +584,8 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
||||
self.ret_expr = "
|
||||
const ret = RET;
|
||||
return ret === 0xFFFFFF ? undefined : ret !== 0;
|
||||
".to_string();
|
||||
"
|
||||
.to_string();
|
||||
return Ok(self);
|
||||
}
|
||||
Descriptor::Char => {
|
||||
@ -597,7 +599,8 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
||||
const present = getUint32Memory()[retptr / 4];
|
||||
const value = getUint32Memory()[retptr / 4 + 1];
|
||||
return present === 0 ? undefined : String.fromCodePoint(value);
|
||||
".to_string();
|
||||
"
|
||||
.to_string();
|
||||
return Ok(self);
|
||||
}
|
||||
_ => bail!(
|
||||
|
@ -3,10 +3,10 @@ use std::mem;
|
||||
|
||||
use decode;
|
||||
use failure::{Error, ResultExt};
|
||||
use parity_wasm::elements::*;
|
||||
use parity_wasm::elements::Error as ParityError;
|
||||
use shared;
|
||||
use gc;
|
||||
use parity_wasm::elements::Error as ParityError;
|
||||
use parity_wasm::elements::*;
|
||||
use shared;
|
||||
|
||||
use super::Bindgen;
|
||||
use descriptor::{Descriptor, VectorKind};
|
||||
@ -438,8 +438,10 @@ impl<'a> Context<'a> {
|
||||
|
||||
self.bind("__wbindgen_module", &|me| {
|
||||
if !me.config.no_modules {
|
||||
bail!("`wasm_bindgen::module` is currently only supported with \
|
||||
--no-modules");
|
||||
bail!(
|
||||
"`wasm_bindgen::module` is currently only supported with \
|
||||
--no-modules"
|
||||
);
|
||||
}
|
||||
me.expose_add_heap_object();
|
||||
Ok(format!(
|
||||
@ -504,7 +506,7 @@ impl<'a> Context<'a> {
|
||||
memory.push_str("})");
|
||||
|
||||
format!(
|
||||
"\
|
||||
"\
|
||||
(function() {{
|
||||
var wasm;
|
||||
var memory;
|
||||
@ -539,17 +541,19 @@ impl<'a> Context<'a> {
|
||||
}};
|
||||
self.{global_name} = Object.assign(init, __exports);
|
||||
}})();",
|
||||
globals = self.globals,
|
||||
module = module_name,
|
||||
global_name = self.config.no_modules_global
|
||||
.as_ref()
|
||||
.map(|s| &**s)
|
||||
.unwrap_or("wasm_bindgen"),
|
||||
init_memory = memory,
|
||||
globals = self.globals,
|
||||
module = module_name,
|
||||
global_name = self
|
||||
.config
|
||||
.no_modules_global
|
||||
.as_ref()
|
||||
.map(|s| &**s)
|
||||
.unwrap_or("wasm_bindgen"),
|
||||
init_memory = memory,
|
||||
)
|
||||
} else if self.config.no_modules {
|
||||
format!(
|
||||
"\
|
||||
"\
|
||||
(function() {{
|
||||
var wasm;
|
||||
const __exports = {{}};
|
||||
@ -579,12 +583,14 @@ impl<'a> Context<'a> {
|
||||
}};
|
||||
self.{global_name} = Object.assign(init, __exports);
|
||||
}})();",
|
||||
globals = self.globals,
|
||||
module = module_name,
|
||||
global_name = self.config.no_modules_global
|
||||
.as_ref()
|
||||
.map(|s| &**s)
|
||||
.unwrap_or("wasm_bindgen"),
|
||||
globals = self.globals,
|
||||
module = module_name,
|
||||
global_name = self
|
||||
.config
|
||||
.no_modules_global
|
||||
.as_ref()
|
||||
.map(|s| &**s)
|
||||
.unwrap_or("wasm_bindgen"),
|
||||
)
|
||||
} else {
|
||||
let import_wasm = if self.globals.len() == 0 {
|
||||
@ -787,7 +793,8 @@ impl<'a> Context<'a> {
|
||||
.filter_map(|s| match *s {
|
||||
Section::Import(ref mut s) => Some(s),
|
||||
_ => None,
|
||||
}).flat_map(|s| s.entries_mut());
|
||||
})
|
||||
.flat_map(|s| s.entries_mut());
|
||||
|
||||
for import in imports {
|
||||
if import.module() == "__wbindgen_placeholder__" {
|
||||
@ -1172,18 +1179,20 @@ impl<'a> Context<'a> {
|
||||
|
||||
fn expose_text_processor(&mut self, s: &str) {
|
||||
if self.config.nodejs_experimental_modules {
|
||||
self.imports.push_str(&format!("import {{ {} }} from 'util';\n", s));
|
||||
self.imports
|
||||
.push_str(&format!("import {{ {} }} from 'util';\n", s));
|
||||
self.global(&format!("let cached{0} = new {0}('utf-8');", s));
|
||||
} else if self.config.nodejs {
|
||||
self.global(&format!("const {0} = require('util').{0};", s));
|
||||
self.global(&format!("let cached{0} = new {0}('utf-8');", s));
|
||||
} else if !(self.config.browser || self.config.no_modules) {
|
||||
self.global(
|
||||
&format!("
|
||||
self.global(&format!(
|
||||
"
|
||||
const l{0} = typeof {0} === 'undefined' ? \
|
||||
require('util').{0} : {0};\
|
||||
", s)
|
||||
);
|
||||
",
|
||||
s
|
||||
));
|
||||
self.global(&format!("let cached{0} = new l{0}('utf-8');", s));
|
||||
} else {
|
||||
self.global(&format!("let cached{0} = new {0}('utf-8');", s));
|
||||
@ -1770,11 +1779,9 @@ impl<'a> Context<'a> {
|
||||
let module = module.parse_names().unwrap_or_else(|p| p.1);
|
||||
*self.module = module;
|
||||
if self.config.remove_name_section {
|
||||
self.module.sections_mut().retain(|s| {
|
||||
match s {
|
||||
Section::Name(_) => false,
|
||||
_ => true,
|
||||
}
|
||||
self.module.sections_mut().retain(|s| match s {
|
||||
Section::Name(_) => false,
|
||||
_ => true,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1815,7 +1822,8 @@ impl<'a> Context<'a> {
|
||||
.filter_map(|i| match i.external() {
|
||||
External::Memory(m) => Some((i, m)),
|
||||
_ => None,
|
||||
}).next()
|
||||
})
|
||||
.next()
|
||||
.expect("must import memory");
|
||||
assert_eq!(entry.field(), "memory");
|
||||
self.memory_init = Some(mem.limits().clone());
|
||||
@ -1857,14 +1865,19 @@ impl<'a> Context<'a> {
|
||||
if use_node_require {
|
||||
imports.push_str(&format!(
|
||||
"const {} = require(String.raw`{}`).{};\n",
|
||||
name, module, import.name()
|
||||
name,
|
||||
module,
|
||||
import.name()
|
||||
));
|
||||
} else if import.name() == name {
|
||||
imports.push_str(&format!("import {{ {} }} from '{}';\n", name, module));
|
||||
imports
|
||||
.push_str(&format!("import {{ {} }} from '{}';\n", name, module));
|
||||
} else {
|
||||
imports.push_str(&format!(
|
||||
"import {{ {} as {} }} from '{}';\n",
|
||||
import.name(), name, module
|
||||
import.name(),
|
||||
name,
|
||||
module
|
||||
));
|
||||
}
|
||||
name
|
||||
@ -1923,11 +1936,11 @@ impl<'a> Context<'a> {
|
||||
None => {
|
||||
let name = self.import_identifier(name);
|
||||
if import.structural || !name.contains(".") {
|
||||
return Ok(ImportTarget::Function(name))
|
||||
return Ok(ImportTarget::Function(name));
|
||||
}
|
||||
self.global(&format!("const {}_target = {};", import.shim, name));
|
||||
let target = format!("{}_target", import.shim);
|
||||
return Ok(ImportTarget::Function(target))
|
||||
return Ok(ImportTarget::Function(target));
|
||||
}
|
||||
};
|
||||
|
||||
@ -1939,7 +1952,11 @@ impl<'a> Context<'a> {
|
||||
decode::MethodKind::Operation(op) => op,
|
||||
};
|
||||
if import.structural {
|
||||
let class = if op.is_static { Some(class.clone()) } else { None };
|
||||
let class = if op.is_static {
|
||||
Some(class.clone())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
return Ok(match &op.kind {
|
||||
decode::OperationKind::Regular => {
|
||||
@ -1964,43 +1981,51 @@ impl<'a> Context<'a> {
|
||||
decode::OperationKind::IndexingDeleter => {
|
||||
ImportTarget::StructuralIndexingDeleter(class)
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
let target = format!("typeof {0} === 'undefined' ? null : {}{}",
|
||||
class,
|
||||
if op.is_static { "" } else { ".prototype" });
|
||||
let target = format!(
|
||||
"typeof {0} === 'undefined' ? null : {}{}",
|
||||
class,
|
||||
if op.is_static { "" } else { ".prototype" }
|
||||
);
|
||||
let (mut target, name) = match &op.kind {
|
||||
decode::OperationKind::Regular => {
|
||||
(format!("{}.{}", target, import.function.name), &import.function.name)
|
||||
}
|
||||
decode::OperationKind::Regular => (
|
||||
format!("{}.{}", target, import.function.name),
|
||||
&import.function.name,
|
||||
),
|
||||
decode::OperationKind::Getter(g) => {
|
||||
self.expose_get_inherited_descriptor();
|
||||
(format!(
|
||||
"GetOwnOrInheritedPropertyDescriptor({}, '{}').get",
|
||||
target, g,
|
||||
), g)
|
||||
(
|
||||
format!(
|
||||
"GetOwnOrInheritedPropertyDescriptor({}, '{}').get",
|
||||
target, g,
|
||||
),
|
||||
g,
|
||||
)
|
||||
}
|
||||
decode::OperationKind::Setter(s) => {
|
||||
self.expose_get_inherited_descriptor();
|
||||
(format!(
|
||||
"GetOwnOrInheritedPropertyDescriptor({}, '{}').set",
|
||||
target, s,
|
||||
), s)
|
||||
}
|
||||
decode::OperationKind::IndexingGetter => {
|
||||
panic!("indexing getter should be structural")
|
||||
}
|
||||
decode::OperationKind::IndexingSetter => {
|
||||
panic!("indexing setter should be structural")
|
||||
(
|
||||
format!(
|
||||
"GetOwnOrInheritedPropertyDescriptor({}, '{}').set",
|
||||
target, s,
|
||||
),
|
||||
s,
|
||||
)
|
||||
}
|
||||
decode::OperationKind::IndexingGetter => panic!("indexing getter should be structural"),
|
||||
decode::OperationKind::IndexingSetter => panic!("indexing setter should be structural"),
|
||||
decode::OperationKind::IndexingDeleter => {
|
||||
panic!("indexing deleter should be structural")
|
||||
}
|
||||
};
|
||||
target.push_str(&format!(" || function() {{
|
||||
target.push_str(&format!(
|
||||
" || function() {{
|
||||
throw new Error(`wasm-bindgen: {}.{} does not exist`);
|
||||
}}", class, name));
|
||||
}}",
|
||||
class, name
|
||||
));
|
||||
if op.is_static {
|
||||
target.insert(0, '(');
|
||||
target.push_str(").bind(");
|
||||
@ -2028,10 +2053,10 @@ impl<'a> Context<'a> {
|
||||
_ => continue,
|
||||
};
|
||||
if section.name() != "producers" {
|
||||
return
|
||||
return;
|
||||
}
|
||||
drop(update(section));
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
// `CustomSection::new` added in paritytech/parity-wasm#244 which isn't
|
||||
@ -2039,7 +2064,15 @@ impl<'a> Context<'a> {
|
||||
let data = [
|
||||
("producers".len() + 2) as u8,
|
||||
"producers".len() as u8,
|
||||
b'p', b'r', b'o', b'd', b'u', b'c', b'e', b'r', b's',
|
||||
b'p',
|
||||
b'r',
|
||||
b'o',
|
||||
b'd',
|
||||
b'u',
|
||||
b'c',
|
||||
b'e',
|
||||
b'r',
|
||||
b's',
|
||||
0,
|
||||
];
|
||||
let mut section = CustomSection::deserialize(&mut &data[..]).unwrap();
|
||||
@ -2058,11 +2091,9 @@ impl<'a> Context<'a> {
|
||||
version: String,
|
||||
}
|
||||
|
||||
let wasm_bindgen = || {
|
||||
FieldValue {
|
||||
name: "wasm-bindgen".to_string(),
|
||||
version: shared::version(),
|
||||
}
|
||||
let wasm_bindgen = || FieldValue {
|
||||
name: "wasm-bindgen".to_string(),
|
||||
version: shared::version(),
|
||||
};
|
||||
let mut fields = Vec::new();
|
||||
|
||||
@ -2090,7 +2121,7 @@ impl<'a> Context<'a> {
|
||||
fields.push(Field { name, values });
|
||||
}
|
||||
if data.len() != 0 {
|
||||
return Err(ParityError::InconsistentCode)
|
||||
return Err(ParityError::InconsistentCode);
|
||||
}
|
||||
|
||||
if !found_processed_by {
|
||||
@ -2199,7 +2230,8 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
Some(class_name)
|
||||
} else {
|
||||
None
|
||||
}).process(descriptor.unwrap_function())?
|
||||
})
|
||||
.process(descriptor.unwrap_function())?
|
||||
.finish("", &format!("wasm.{}", wasm_name));
|
||||
|
||||
let class = self
|
||||
@ -2323,9 +2355,14 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
// up the wasm import directly to the destination. We don't actually
|
||||
// wire up anything here, but we record it to get wired up later.
|
||||
if import.method.is_none() && shim.is_noop() {
|
||||
if let Import::Module { module, name, field: None } = name {
|
||||
if let Import::Module {
|
||||
module,
|
||||
name,
|
||||
field: None,
|
||||
} = name
|
||||
{
|
||||
shim.cx.direct_imports.insert(import.shim, (module, name));
|
||||
return Ok(())
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
@ -2439,12 +2476,9 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn register_vendor_prefix(
|
||||
&mut self,
|
||||
info: &decode::ImportType<'b>,
|
||||
) {
|
||||
fn register_vendor_prefix(&mut self, info: &decode::ImportType<'b>) {
|
||||
if info.vendor_prefixes.len() == 0 {
|
||||
return
|
||||
return;
|
||||
}
|
||||
self.vendor_prefixes
|
||||
.entry(info.name)
|
||||
@ -2452,9 +2486,11 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
.extend(info.vendor_prefixes.iter().cloned());
|
||||
}
|
||||
|
||||
fn determine_import(&self, import: &decode::Import<'b>, item: &'b str)
|
||||
-> Result<Import<'b>, Error>
|
||||
{
|
||||
fn determine_import(
|
||||
&self,
|
||||
import: &decode::Import<'b>,
|
||||
item: &'b str,
|
||||
) -> Result<Import<'b>, Error> {
|
||||
// First up, imports don't work at all in `--no-modules` mode as we're
|
||||
// not sure how to import them.
|
||||
if self.cx.config.no_modules {
|
||||
@ -2484,29 +2520,37 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
);
|
||||
}
|
||||
if let Some(ns) = &import.js_namespace {
|
||||
bail!("import of `{}` through js namespace `{}` isn't supported \
|
||||
right now when it lists a polyfill",
|
||||
item,
|
||||
ns);
|
||||
bail!(
|
||||
"import of `{}` through js namespace `{}` isn't supported \
|
||||
right now when it lists a polyfill",
|
||||
item,
|
||||
ns
|
||||
);
|
||||
}
|
||||
return Ok(Import::VendorPrefixed {
|
||||
name: item,
|
||||
prefixes: vendor_prefixes.clone(),
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
let name = import.js_namespace.as_ref().map(|s| &**s).unwrap_or(item);
|
||||
let field = if import.js_namespace.is_some() { Some(item) } else { None };
|
||||
let field = if import.js_namespace.is_some() {
|
||||
Some(item)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(match import.module {
|
||||
Some(module) => Import::Module { module, name, field },
|
||||
Some(module) => Import::Module {
|
||||
module,
|
||||
name,
|
||||
field,
|
||||
},
|
||||
None => Import::Global { name, field },
|
||||
})
|
||||
}
|
||||
|
||||
fn import_name(&mut self, import: &decode::Import<'b>, item: &'b str)
|
||||
-> Result<String, Error>
|
||||
{
|
||||
fn import_name(&mut self, import: &decode::Import<'b>, item: &'b str) -> Result<String, Error> {
|
||||
let import = self.determine_import(import, item)?;
|
||||
Ok(self.cx.import_identifier(import))
|
||||
}
|
||||
@ -2529,9 +2573,9 @@ impl<'a> Import<'a> {
|
||||
|
||||
fn name(&self) -> &'a str {
|
||||
match self {
|
||||
Import::Module { name, .. } |
|
||||
Import::Global { name, .. } |
|
||||
Import::VendorPrefixed { name, .. } => *name,
|
||||
Import::Module { name, .. }
|
||||
| Import::Global { name, .. }
|
||||
| Import::VendorPrefixed { name, .. } => *name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use failure::Error;
|
||||
|
||||
use super::{Context, Js2Rust, ImportTarget};
|
||||
use super::{Context, ImportTarget, Js2Rust};
|
||||
use descriptor::{Descriptor, Function};
|
||||
|
||||
/// Helper struct for manufacturing a shim in JS used to translate Rust types to
|
||||
@ -345,7 +345,8 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
self.ret_expr = "
|
||||
const val = JS;
|
||||
return isLikeNone(val) ? 0 : addHeapObject(val);
|
||||
".to_string();
|
||||
"
|
||||
.to_string();
|
||||
} else {
|
||||
self.ret_expr = "return addHeapObject(JS);".to_string()
|
||||
}
|
||||
@ -392,7 +393,8 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
self.ret_expr = "
|
||||
const val = JS;
|
||||
return isLikeNone(val) ? 0xFFFFFF : val;
|
||||
".to_string();
|
||||
"
|
||||
.to_string();
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@ -424,7 +426,8 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
self.ret_expr = "
|
||||
const val = JS;
|
||||
return isLikeNone(val) ? 0xFFFFFF : val ? 1 : 0;
|
||||
".to_string();
|
||||
"
|
||||
.to_string();
|
||||
return Ok(());
|
||||
}
|
||||
Descriptor::Char => {
|
||||
@ -435,7 +438,8 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
const val = JS;
|
||||
getUint32Memory()[ret / 4] = !isLikeNone(val);
|
||||
getUint32Memory()[ret / 4 + 1] = isLikeNone(val) ? 0 : val.codePointAt(0);
|
||||
".to_string();
|
||||
"
|
||||
.to_string();
|
||||
return Ok(());
|
||||
}
|
||||
_ => bail!(
|
||||
@ -561,16 +565,12 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
&format!("{}({}, ...{})", invoc, args.join(", "), last_arg),
|
||||
)
|
||||
} else {
|
||||
self.ret_expr.replace(
|
||||
"JS",
|
||||
&format!("{}(...{})", invoc, last_arg),
|
||||
)
|
||||
self.ret_expr
|
||||
.replace("JS", &format!("{}(...{})", invoc, last_arg))
|
||||
}
|
||||
} else {
|
||||
self.ret_expr.replace(
|
||||
"JS",
|
||||
&format!("{}({})", invoc, js_arguments.join(", ")),
|
||||
)
|
||||
self.ret_expr
|
||||
.replace("JS", &format!("{}({})", invoc, js_arguments.join(", ")))
|
||||
};
|
||||
Ok(ret)
|
||||
};
|
||||
@ -584,23 +584,17 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
Ok((self.js_arguments[0].clone(), &self.js_arguments[1..]))
|
||||
}
|
||||
(None, _) => bail!("setters must have {} arguments", amt + 1),
|
||||
(Some(class), n) if n == amt => {
|
||||
Ok((class.clone(), &self.js_arguments[..]))
|
||||
}
|
||||
(Some(class), n) if n == amt => Ok((class.clone(), &self.js_arguments[..])),
|
||||
(Some(_), _) => bail!("static setters must have {} arguments", amt),
|
||||
}
|
||||
};
|
||||
|
||||
let mut invoc = match invoc {
|
||||
ImportTarget::Function(f) => {
|
||||
handle_variadic(&f, &self.js_arguments)?
|
||||
}
|
||||
ImportTarget::Function(f) => handle_variadic(&f, &self.js_arguments)?,
|
||||
ImportTarget::Constructor(c) => {
|
||||
handle_variadic(&format!("new {}", c), &self.js_arguments)?
|
||||
}
|
||||
ImportTarget::Method(f) => {
|
||||
handle_variadic(&format!("{}.call", f), &self.js_arguments)?
|
||||
}
|
||||
ImportTarget::Method(f) => handle_variadic(&format!("{}.call", f), &self.js_arguments)?,
|
||||
ImportTarget::StructuralMethod(f) => {
|
||||
let (receiver, args) = match self.js_arguments.split_first() {
|
||||
Some(pair) => pair,
|
||||
|
@ -6,8 +6,8 @@ extern crate wasm_bindgen_shared as shared;
|
||||
extern crate wasm_bindgen_gc as gc;
|
||||
#[macro_use]
|
||||
extern crate failure;
|
||||
extern crate wasm_bindgen_wasm_interpreter as wasm_interpreter;
|
||||
extern crate wasm_bindgen_threads_xform as threads_xform;
|
||||
extern crate wasm_bindgen_wasm_interpreter as wasm_interpreter;
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
use std::env;
|
||||
@ -201,7 +201,8 @@ impl Bindgen {
|
||||
program,
|
||||
cx: &mut cx,
|
||||
vendor_prefixes: Default::default(),
|
||||
}.generate()?;
|
||||
}
|
||||
.generate()?;
|
||||
}
|
||||
cx.finalize(stem)?
|
||||
};
|
||||
@ -390,7 +391,7 @@ to open an issue at https://github.com/rustwasm/wasm-bindgen/issues!
|
||||
|
||||
fn get_remaining<'a>(data: &mut &'a [u8]) -> Option<&'a [u8]> {
|
||||
if data.len() == 0 {
|
||||
return None
|
||||
return None;
|
||||
}
|
||||
let len = ((data[0] as usize) << 0)
|
||||
| ((data[1] as usize) << 8)
|
||||
@ -401,11 +402,11 @@ fn get_remaining<'a>(data: &mut &'a [u8]) -> Option<&'a [u8]> {
|
||||
Some(a)
|
||||
}
|
||||
|
||||
fn verify_schema_matches<'a>(data: &'a [u8])
|
||||
-> Result<Option<&'a str>, Error>
|
||||
{
|
||||
fn verify_schema_matches<'a>(data: &'a [u8]) -> Result<Option<&'a str>, Error> {
|
||||
macro_rules! bad {
|
||||
() => (bail!("failed to decode what looked like wasm-bindgen data"))
|
||||
() => {
|
||||
bail!("failed to decode what looked like wasm-bindgen data")
|
||||
};
|
||||
}
|
||||
let data = match str::from_utf8(data) {
|
||||
Ok(s) => s,
|
||||
@ -424,7 +425,7 @@ fn verify_schema_matches<'a>(data: &'a [u8])
|
||||
None => bad!(),
|
||||
};
|
||||
if their_schema_version == shared::SCHEMA_VERSION {
|
||||
return Ok(None)
|
||||
return Ok(None);
|
||||
}
|
||||
let needle = "\"version\":\"";
|
||||
let rest = match data.find(needle) {
|
||||
@ -471,7 +472,7 @@ fn reset_indentation(s: &str) -> String {
|
||||
// backwards-compatibility with these options.
|
||||
fn threads_config() -> Option<threads_xform::Config> {
|
||||
if env::var("WASM_BINDGEN_THREADS").is_err() {
|
||||
return None
|
||||
return None;
|
||||
}
|
||||
let mut cfg = threads_xform::Config::new();
|
||||
if let Ok(s) = env::var("WASM_BINDGEN_THREADS_MAX_MEMORY") {
|
||||
|
@ -98,7 +98,8 @@ pub fn spawn(
|
||||
// header?)
|
||||
response.headers.retain(|(k, _)| k != "Cache-Control");
|
||||
return response;
|
||||
}).map_err(|e| format_err!("{}", e))?;
|
||||
})
|
||||
.map_err(|e| format_err!("{}", e))?;
|
||||
return Ok(srv);
|
||||
|
||||
fn try_asset(request: &Request, dir: &Path) -> Response {
|
||||
|
@ -6,8 +6,8 @@ extern crate wasm_bindgen;
|
||||
extern crate wasm_bindgen_futures;
|
||||
extern crate wasm_bindgen_test;
|
||||
|
||||
use futures::Future;
|
||||
use futures::unsync::oneshot;
|
||||
use futures::Future;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen_futures::{future_to_promise, JsFuture};
|
||||
use wasm_bindgen_test::*;
|
||||
@ -18,7 +18,8 @@ fn promise_resolve_is_ok_future() -> impl Future<Item = (), Error = JsValue> {
|
||||
JsFuture::from(p)
|
||||
.map(|x| {
|
||||
assert_eq!(x, 42);
|
||||
}).map_err(|_| unreachable!())
|
||||
})
|
||||
.map_err(|_| unreachable!())
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test(async)]
|
||||
@ -37,7 +38,8 @@ fn ok_future_is_resolved_promise() -> impl Future<Item = (), Error = JsValue> {
|
||||
JsFuture::from(p)
|
||||
.map(|x| {
|
||||
assert_eq!(x, 42);
|
||||
}).map_err(|_| unreachable!())
|
||||
})
|
||||
.map_err(|_| unreachable!())
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test(async)]
|
||||
@ -51,7 +53,7 @@ fn error_future_is_rejected_promise() -> impl Future<Item = (), Error = JsValue>
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn setTimeout(c: &Closure<FnMut()>);
|
||||
}
|
||||
|
||||
|
@ -42,9 +42,7 @@ impl BitSet {
|
||||
let i = *i as usize;
|
||||
let idx = i / BITS;
|
||||
let bit = 1 << (i % BITS);
|
||||
self.bits.get(idx)
|
||||
.map(|x| *x & bit != 0)
|
||||
.unwrap_or(false)
|
||||
self.bits.get(idx).map(|x| *x & bit != 0).unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ extern crate parity_wasm;
|
||||
extern crate log;
|
||||
extern crate rustc_demangle;
|
||||
|
||||
use std::collections::{HashSet, HashMap};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::iter;
|
||||
use std::mem;
|
||||
|
||||
@ -66,7 +66,7 @@ fn run(config: &mut Config, module: &mut Module) {
|
||||
if let Some(section) = module.export_section() {
|
||||
for (i, entry) in section.entries().iter().enumerate() {
|
||||
if cx.blacklist.contains(entry.field()) {
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
cx.add_export_entry(entry, i as u32);
|
||||
}
|
||||
@ -85,19 +85,19 @@ fn run(config: &mut Config, module: &mut Module) {
|
||||
let retain = match module.sections_mut()[i] {
|
||||
Section::Unparsed { .. } => {
|
||||
info!("unparsed section");
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
Section::Custom(ref s) => {
|
||||
if !cx.config.keep_debug && s.name().starts_with(".debug_") {
|
||||
false
|
||||
} else {
|
||||
info!("skipping custom section: {}", s.name());
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Section::Reloc(..) => {
|
||||
info!("skipping reloc section");
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
Section::Type(ref mut s) => cx.remap_type_section(s),
|
||||
Section::Import(ref mut s) => cx.remap_import_section(s),
|
||||
@ -106,11 +106,17 @@ fn run(config: &mut Config, module: &mut Module) {
|
||||
Section::Memory(ref mut s) => cx.remap_memory_section(s),
|
||||
Section::Global(ref mut s) => cx.remap_global_section(s),
|
||||
Section::Export(ref mut s) => cx.remap_export_section(s),
|
||||
Section::Start(ref mut i) => { cx.remap_function_idx(i); true }
|
||||
Section::Start(ref mut i) => {
|
||||
cx.remap_function_idx(i);
|
||||
true
|
||||
}
|
||||
Section::Element(ref mut s) => cx.remap_element_section(s),
|
||||
Section::Code(ref mut s) => cx.remap_code_section(s),
|
||||
Section::Data(ref mut s) => cx.remap_data_section(s),
|
||||
Section::Name(ref mut s) => { cx.remap_name_section(s); true }
|
||||
Section::Name(ref mut s) => {
|
||||
cx.remap_name_section(s);
|
||||
true
|
||||
}
|
||||
};
|
||||
if !retain {
|
||||
debug!("remove empty section");
|
||||
@ -187,20 +193,19 @@ impl<'a> LiveContext<'a> {
|
||||
|
||||
fn add_function(&mut self, idx: u32) {
|
||||
if !self.analysis.functions.insert(idx) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
debug!("adding function: {}", idx);
|
||||
|
||||
if idx < self.analysis.imported_functions {
|
||||
let imports = self.import_section.unwrap();
|
||||
let (i, import) = imports.entries()
|
||||
let (i, import) = imports
|
||||
.entries()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|&(_, i)| {
|
||||
match *i.external() {
|
||||
External::Function(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
.filter(|&(_, i)| match *i.external() {
|
||||
External::Function(_) => true,
|
||||
_ => false,
|
||||
})
|
||||
.skip(idx as usize)
|
||||
.next()
|
||||
@ -217,13 +222,14 @@ impl<'a> LiveContext<'a> {
|
||||
|
||||
fn add_table(&mut self, idx: u32) {
|
||||
if !self.analysis.tables.insert(idx) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
debug!("adding table: {}", idx);
|
||||
|
||||
// Add all element segments that initialize this table
|
||||
if let Some(elements) = self.element_section {
|
||||
let iter = elements.entries()
|
||||
let iter = elements
|
||||
.entries()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, d)| !d.passive() && d.index() == idx);
|
||||
@ -234,14 +240,13 @@ impl<'a> LiveContext<'a> {
|
||||
|
||||
if idx < self.analysis.imported_tables {
|
||||
let imports = self.import_section.unwrap();
|
||||
let (i, import) = imports.entries()
|
||||
let (i, import) = imports
|
||||
.entries()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|&(_, i)| {
|
||||
match *i.external() {
|
||||
External::Table(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
.filter(|&(_, i)| match *i.external() {
|
||||
External::Table(_) => true,
|
||||
_ => false,
|
||||
})
|
||||
.skip(idx as usize)
|
||||
.next()
|
||||
@ -257,13 +262,14 @@ impl<'a> LiveContext<'a> {
|
||||
|
||||
fn add_memory(&mut self, idx: u32) {
|
||||
if !self.analysis.memories.insert(idx) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
debug!("adding memory: {}", idx);
|
||||
|
||||
// Add all data segments that initialize this memory
|
||||
if let Some(data) = self.data_section {
|
||||
let iter = data.entries()
|
||||
let iter = data
|
||||
.entries()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, d)| !d.passive() && d.index() == idx);
|
||||
@ -275,14 +281,13 @@ impl<'a> LiveContext<'a> {
|
||||
// ... and add the import if it's an imported memory ..
|
||||
if idx < self.analysis.imported_memories {
|
||||
let imports = self.import_section.unwrap();
|
||||
let (i, import) = imports.entries()
|
||||
let (i, import) = imports
|
||||
.entries()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|&(_, i)| {
|
||||
match *i.external() {
|
||||
External::Memory(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
.filter(|&(_, i)| match *i.external() {
|
||||
External::Memory(_) => true,
|
||||
_ => false,
|
||||
})
|
||||
.skip(idx as usize)
|
||||
.next()
|
||||
@ -296,20 +301,19 @@ impl<'a> LiveContext<'a> {
|
||||
|
||||
fn add_global(&mut self, idx: u32) {
|
||||
if !self.analysis.globals.insert(idx) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
debug!("adding global: {}", idx);
|
||||
|
||||
if idx < self.analysis.imported_globals {
|
||||
let imports = self.import_section.unwrap();
|
||||
let (i, import) = imports.entries()
|
||||
let (i, import) = imports
|
||||
.entries()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|&(_, i)| {
|
||||
match *i.external() {
|
||||
External::Global(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
.filter(|&(_, i)| match *i.external() {
|
||||
External::Global(_) => true,
|
||||
_ => false,
|
||||
})
|
||||
.skip(idx as usize)
|
||||
.next()
|
||||
@ -337,7 +341,7 @@ impl<'a> LiveContext<'a> {
|
||||
|
||||
fn add_type(&mut self, idx: u32) {
|
||||
if !self.analysis.types.insert(idx) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
let types = self.type_section.expect("no types section");
|
||||
match types.types()[idx as usize] {
|
||||
@ -377,23 +381,20 @@ impl<'a> LiveContext<'a> {
|
||||
|
||||
fn add_opcode(&mut self, code: &Instruction) {
|
||||
match *code {
|
||||
Instruction::Block(ref b) |
|
||||
Instruction::Loop(ref b) |
|
||||
Instruction::If(ref b) => self.add_block_type(b),
|
||||
Instruction::Block(ref b) | Instruction::Loop(ref b) | Instruction::If(ref b) => {
|
||||
self.add_block_type(b)
|
||||
}
|
||||
Instruction::Call(f) => self.add_function(f),
|
||||
Instruction::CallIndirect(t, _) => {
|
||||
self.add_type(t);
|
||||
self.add_table(0);
|
||||
}
|
||||
Instruction::GetGlobal(i) |
|
||||
Instruction::SetGlobal(i) => self.add_global(i),
|
||||
Instruction::MemoryInit(i) |
|
||||
Instruction::MemoryDrop(i) => {
|
||||
Instruction::GetGlobal(i) | Instruction::SetGlobal(i) => self.add_global(i),
|
||||
Instruction::MemoryInit(i) | Instruction::MemoryDrop(i) => {
|
||||
self.add_memory(0);
|
||||
self.add_data_segment(i);
|
||||
}
|
||||
Instruction::TableInit(i) |
|
||||
Instruction::TableDrop(i) => {
|
||||
Instruction::TableInit(i) | Instruction::TableDrop(i) => {
|
||||
self.add_table(0);
|
||||
self.add_element_segment(i);
|
||||
}
|
||||
@ -410,7 +411,7 @@ impl<'a> LiveContext<'a> {
|
||||
|
||||
fn add_export_entry(&mut self, entry: &ExportEntry, idx: u32) {
|
||||
if !self.analysis.exports.insert(idx) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
match *entry.internal() {
|
||||
Internal::Function(i) => self.add_function(i),
|
||||
@ -422,7 +423,7 @@ impl<'a> LiveContext<'a> {
|
||||
|
||||
fn add_import_entry(&mut self, entry: &ImportEntry, idx: u32) {
|
||||
if !self.analysis.imports.insert(idx) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
debug!("adding import: {}", idx);
|
||||
match *entry.external() {
|
||||
@ -435,7 +436,7 @@ impl<'a> LiveContext<'a> {
|
||||
|
||||
fn add_data_segment(&mut self, idx: u32) {
|
||||
if !self.analysis.data_segments.insert(idx) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
let data = &self.data_section.unwrap().entries()[idx as usize];
|
||||
if !data.passive() {
|
||||
@ -448,7 +449,7 @@ impl<'a> LiveContext<'a> {
|
||||
|
||||
fn add_element_segment(&mut self, idx: u32) {
|
||||
if !self.analysis.elements.insert(idx) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
let seg = &self.element_section.unwrap().entries()[idx as usize];
|
||||
for member in seg.members() {
|
||||
@ -495,7 +496,7 @@ impl<'a> RemapContext<'a> {
|
||||
if let Some(prev) = map.get(&ty) {
|
||||
types.push(*prev);
|
||||
analysis.types.remove(&(i as u32));
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
map.insert(ty, ntypes);
|
||||
types.push(ntypes);
|
||||
@ -525,7 +526,10 @@ impl<'a> RemapContext<'a> {
|
||||
}
|
||||
if let Some(s) = m.function_section() {
|
||||
for i in 0..(s.entries().len() as u32) {
|
||||
if analysis.functions.contains(&(i + analysis.imported_functions)) {
|
||||
if analysis
|
||||
.functions
|
||||
.contains(&(i + analysis.imported_functions))
|
||||
{
|
||||
functions.push(nfunctions);
|
||||
nfunctions += 1;
|
||||
} else {
|
||||
@ -558,7 +562,10 @@ impl<'a> RemapContext<'a> {
|
||||
}
|
||||
if let Some(s) = m.memory_section() {
|
||||
for i in 0..(s.entries().len() as u32) {
|
||||
if analysis.memories.contains(&(i + analysis.imported_memories)) {
|
||||
if analysis
|
||||
.memories
|
||||
.contains(&(i + analysis.imported_memories))
|
||||
{
|
||||
memories.push(nmemories);
|
||||
nmemories += 1;
|
||||
} else {
|
||||
@ -804,17 +811,20 @@ impl<'a> RemapContext<'a> {
|
||||
|
||||
fn remap_instruction(&self, i: &mut Instruction) {
|
||||
match *i {
|
||||
Instruction::Block(ref mut b) |
|
||||
Instruction::Loop(ref mut b) |
|
||||
Instruction::If(ref mut b) => self.remap_block_type(b),
|
||||
Instruction::Block(ref mut b)
|
||||
| Instruction::Loop(ref mut b)
|
||||
| Instruction::If(ref mut b) => self.remap_block_type(b),
|
||||
Instruction::Call(ref mut f) => self.remap_function_idx(f),
|
||||
Instruction::CallIndirect(ref mut t, _) => self.remap_type_idx(t),
|
||||
Instruction::GetGlobal(ref mut i) |
|
||||
Instruction::SetGlobal(ref mut i) => self.remap_global_idx(i),
|
||||
Instruction::TableInit(ref mut i) |
|
||||
Instruction::TableDrop(ref mut i) => self.remap_element_idx(i),
|
||||
Instruction::MemoryInit(ref mut i) |
|
||||
Instruction::MemoryDrop(ref mut i) => self.remap_data_idx(i),
|
||||
Instruction::GetGlobal(ref mut i) | Instruction::SetGlobal(ref mut i) => {
|
||||
self.remap_global_idx(i)
|
||||
}
|
||||
Instruction::TableInit(ref mut i) | Instruction::TableDrop(ref mut i) => {
|
||||
self.remap_element_idx(i)
|
||||
}
|
||||
Instruction::MemoryInit(ref mut i) | Instruction::MemoryDrop(ref mut i) => {
|
||||
self.remap_data_idx(i)
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@ -984,7 +994,7 @@ fn gc_body(
|
||||
let mut next = ty.params().len() as u32;
|
||||
for i in ty.params().len()..used.len() {
|
||||
if !used[i] {
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
// We're using this local, so map it to the next index (the lowest).
|
||||
// Find all other locals with the same type and lump then into our
|
||||
@ -999,13 +1009,12 @@ fn gc_body(
|
||||
next += 1;
|
||||
}
|
||||
}
|
||||
body.locals_mut().push(Local::new((next - before) as u32, local_tys[i]));
|
||||
body.locals_mut()
|
||||
.push(Local::new((next - before) as u32, local_tys[i]));
|
||||
}
|
||||
|
||||
for instr in body.code_mut().elements_mut() {
|
||||
let get = |i: &u32| {
|
||||
map[*i as usize].unwrap()
|
||||
};
|
||||
let get = |i: &u32| map[*i as usize].unwrap();
|
||||
match instr {
|
||||
Instruction::GetLocal(i) => *i = get(i),
|
||||
Instruction::SetLocal(i) => *i = get(i),
|
||||
|
@ -10,8 +10,8 @@ use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
use rayon::prelude::*;
|
||||
use parity_wasm::elements::Module;
|
||||
use rayon::prelude::*;
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
struct Test {
|
||||
@ -31,13 +31,11 @@ fn find_tests(tests: &mut Vec<Test>, path: &Path) {
|
||||
let path = entry.path();
|
||||
if entry.file_type().unwrap().is_dir() {
|
||||
find_tests(tests, &path);
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
|
||||
if path.extension().and_then(|s| s.to_str()) == Some("wat") {
|
||||
tests.push(Test {
|
||||
input: path,
|
||||
});
|
||||
tests.push(Test { input: path });
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -45,10 +43,9 @@ fn find_tests(tests: &mut Vec<Test>, path: &Path) {
|
||||
fn run_tests(tests: &[Test]) {
|
||||
println!("");
|
||||
|
||||
let results = tests.par_iter()
|
||||
.map(|test| {
|
||||
run_test(test).map_err(|e| (test, e.to_string()))
|
||||
})
|
||||
let results = tests
|
||||
.par_iter()
|
||||
.map(|test| run_test(test).map_err(|e| (test, e.to_string())))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut bad = false;
|
||||
@ -81,7 +78,7 @@ fn run_test(test: &Test) -> Result<(), Box<Error>> {
|
||||
.arg(f.path())
|
||||
.status()?;
|
||||
if !status.success() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "failed to run wat2wasm").into())
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "failed to run wat2wasm").into());
|
||||
}
|
||||
|
||||
let wasm = fs::read(f.path())?;
|
||||
@ -100,7 +97,7 @@ fn run_test(test: &Test) -> Result<(), Box<Error>> {
|
||||
.stderr(Stdio::inherit())
|
||||
.output()?;
|
||||
if !status.status.success() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "failed to run wasm2wat").into())
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "failed to run wasm2wat").into());
|
||||
}
|
||||
let actual = String::from_utf8(status.stdout)?;
|
||||
let actual = actual.trim();
|
||||
@ -110,8 +107,7 @@ fn run_test(test: &Test) -> Result<(), Box<Error>> {
|
||||
} else {
|
||||
if actual != expected {
|
||||
println!("{:?} {:?}", actual, expected);
|
||||
return Err(io::Error::new(io::ErrorKind::Other,
|
||||
"test failed").into())
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "test failed").into());
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,7 +115,8 @@ fn run_test(test: &Test) -> Result<(), Box<Error>> {
|
||||
}
|
||||
|
||||
fn extract_expected(input: &str) -> String {
|
||||
input.lines()
|
||||
input
|
||||
.lines()
|
||||
.filter(|l| l.starts_with(";; "))
|
||||
.skip_while(|l| !l.contains("STDOUT"))
|
||||
.skip(1)
|
||||
@ -130,7 +127,8 @@ fn extract_expected(input: &str) -> String {
|
||||
}
|
||||
|
||||
fn generate_blesssed(input: &str, actual: &str) -> String {
|
||||
let mut input = input.lines()
|
||||
let mut input = input
|
||||
.lines()
|
||||
.filter(|l| !l.starts_with(";;"))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
@ -144,5 +142,5 @@ fn generate_blesssed(input: &str, actual: &str) -> String {
|
||||
input.push_str("\n");
|
||||
}
|
||||
input.push_str(";; STDOUT\n");
|
||||
return input
|
||||
return input;
|
||||
}
|
||||
|
@ -52,8 +52,14 @@ fn test() {
|
||||
v.set_float64(0, 123456789.123456);
|
||||
assert_eq!(v.get_float64(0), 123456789.123456);
|
||||
v.set_float64_endian(0, f64::from_bits(0x1122334411223344), true);
|
||||
assert_eq!(v.get_float64_endian(0, true), f64::from_bits(0x1122334411223344));
|
||||
assert_eq!(v.get_float64_endian(0, false), f64::from_bits(0x4433221144332211));
|
||||
assert_eq!(
|
||||
v.get_float64_endian(0, true),
|
||||
f64::from_bits(0x1122334411223344)
|
||||
);
|
||||
assert_eq!(
|
||||
v.get_float64_endian(0, false),
|
||||
f64::from_bits(0x4433221144332211)
|
||||
);
|
||||
|
||||
v.set_int8(0, 42);
|
||||
|
||||
|
@ -30,19 +30,13 @@ fn try_iter_handles_iteration_protocol() {
|
||||
|
||||
assert!(try_iter(&get_not_iterable()).unwrap().is_none());
|
||||
assert!(try_iter(&get_symbol_iterator_throws()).is_err());
|
||||
assert!(
|
||||
try_iter(&get_symbol_iterator_not_function())
|
||||
.unwrap()
|
||||
.is_none()
|
||||
);
|
||||
assert!(
|
||||
try_iter(&get_symbol_iterator_returns_not_object())
|
||||
.unwrap()
|
||||
.is_none()
|
||||
);
|
||||
assert!(
|
||||
try_iter(&get_symbol_iterator_returns_object_without_next())
|
||||
.unwrap()
|
||||
.is_none()
|
||||
);
|
||||
assert!(try_iter(&get_symbol_iterator_not_function())
|
||||
.unwrap()
|
||||
.is_none());
|
||||
assert!(try_iter(&get_symbol_iterator_returns_not_object())
|
||||
.unwrap()
|
||||
.is_none());
|
||||
assert!(try_iter(&get_symbol_iterator_returns_object_without_next())
|
||||
.unwrap()
|
||||
.is_none());
|
||||
}
|
||||
|
@ -62,7 +62,8 @@ fn compile_valid() -> impl Future<Item = (), Error = JsValue> {
|
||||
JsFuture::from(p)
|
||||
.map(|module| {
|
||||
assert!(module.is_instance_of::<WebAssembly::Module>());
|
||||
}).map_err(|_| unreachable!())
|
||||
})
|
||||
.map_err(|_| unreachable!())
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
@ -197,11 +198,9 @@ fn instantiate_streaming() -> impl Future<Item = (), Error = JsValue> {
|
||||
let imports = get_imports();
|
||||
let p = WebAssembly::instantiate_streaming(&response, &imports);
|
||||
JsFuture::from(p).map(|obj| {
|
||||
assert!(
|
||||
Reflect::get(obj.as_ref(), &"instance".into())
|
||||
.unwrap()
|
||||
.is_instance_of::<WebAssembly::Instance>()
|
||||
);
|
||||
assert!(Reflect::get(obj.as_ref(), &"instance".into())
|
||||
.unwrap()
|
||||
.is_instance_of::<WebAssembly::Instance>());
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,8 @@ impl BindgenAttrs {
|
||||
.filter_map(|a| match a {
|
||||
BindgenAttr::Module(s) => Some(&s[..]),
|
||||
_ => None,
|
||||
}).next()
|
||||
})
|
||||
.next()
|
||||
}
|
||||
|
||||
/// Whether the catch attribute is present
|
||||
@ -76,7 +77,8 @@ impl BindgenAttrs {
|
||||
.filter_map(|a| match a {
|
||||
BindgenAttr::StaticMethodOf(c) => Some(c),
|
||||
_ => None,
|
||||
}).next()
|
||||
})
|
||||
.next()
|
||||
}
|
||||
|
||||
/// Whether the method attributes is present
|
||||
@ -94,7 +96,8 @@ impl BindgenAttrs {
|
||||
.filter_map(|a| match a {
|
||||
BindgenAttr::JsNamespace(s) => Some(s),
|
||||
_ => None,
|
||||
}).next()
|
||||
})
|
||||
.next()
|
||||
}
|
||||
|
||||
/// Get the first getter attribute
|
||||
@ -104,7 +107,8 @@ impl BindgenAttrs {
|
||||
.filter_map(|a| match a {
|
||||
BindgenAttr::Getter(g) => Some(g.clone()),
|
||||
_ => None,
|
||||
}).next()
|
||||
})
|
||||
.next()
|
||||
}
|
||||
|
||||
/// Get the first setter attribute
|
||||
@ -114,7 +118,8 @@ impl BindgenAttrs {
|
||||
.filter_map(|a| match a {
|
||||
BindgenAttr::Setter(s) => Some(s.clone()),
|
||||
_ => None,
|
||||
}).next()
|
||||
})
|
||||
.next()
|
||||
}
|
||||
|
||||
/// Whether the indexing getter attributes is present
|
||||
@ -151,10 +156,13 @@ impl BindgenAttrs {
|
||||
|
||||
/// Whether the `final` attribute is present
|
||||
fn final_(&self) -> Option<&Ident> {
|
||||
self.attrs.iter().filter_map(|a| match a {
|
||||
BindgenAttr::Final(i) => Some(i),
|
||||
_ => None,
|
||||
}).next()
|
||||
self.attrs
|
||||
.iter()
|
||||
.filter_map(|a| match a {
|
||||
BindgenAttr::Final(i) => Some(i),
|
||||
_ => None,
|
||||
})
|
||||
.next()
|
||||
}
|
||||
|
||||
/// Whether the readonly attributes is present
|
||||
@ -172,7 +180,8 @@ impl BindgenAttrs {
|
||||
.filter_map(|a| match a {
|
||||
BindgenAttr::JsName(s, span) => Some((&s[..], *span)),
|
||||
_ => None,
|
||||
}).next()
|
||||
})
|
||||
.next()
|
||||
}
|
||||
|
||||
/// Get the first js_class attribute
|
||||
@ -182,7 +191,8 @@ impl BindgenAttrs {
|
||||
.filter_map(|a| match a {
|
||||
BindgenAttr::JsClass(s) => Some(&s[..]),
|
||||
_ => None,
|
||||
}).next()
|
||||
})
|
||||
.next()
|
||||
}
|
||||
|
||||
/// Return the list of classes that a type extends
|
||||
@ -281,7 +291,7 @@ impl Parse for BindgenAttr {
|
||||
return Ok(BindgenAttr::Structural);
|
||||
}
|
||||
if attr == "final" {
|
||||
return Ok(BindgenAttr::Final(attr))
|
||||
return Ok(BindgenAttr::Final(attr));
|
||||
}
|
||||
if attr == "readonly" {
|
||||
return Ok(BindgenAttr::Readonly);
|
||||
@ -386,7 +396,8 @@ impl<'a> ConvertToAst<BindgenAttrs> for &'a mut syn::ItemStruct {
|
||||
);
|
||||
}
|
||||
let mut fields = Vec::new();
|
||||
let js_name = opts.js_name()
|
||||
let js_name = opts
|
||||
.js_name()
|
||||
.map(|s| s.0.to_string())
|
||||
.unwrap_or(self.ident.to_string());
|
||||
if let syn::Fields::Named(names) = &mut self.fields {
|
||||
@ -441,7 +452,8 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a Option<String>)> for syn::ForeignItemFn
|
||||
self.vis.clone(),
|
||||
false,
|
||||
None,
|
||||
)?.0;
|
||||
)?
|
||||
.0;
|
||||
let catch = opts.catch();
|
||||
let variadic = opts.variadic();
|
||||
let js_ret = if catch {
|
||||
@ -664,7 +676,8 @@ impl ConvertToAst<BindgenAttrs> for syn::ItemFn {
|
||||
self.vis,
|
||||
false,
|
||||
None,
|
||||
)?.0)
|
||||
)?
|
||||
.0)
|
||||
}
|
||||
}
|
||||
|
||||
@ -735,7 +748,8 @@ fn function_from_decl(
|
||||
None
|
||||
}
|
||||
_ => panic!("arguments cannot be `self` or ignored"),
|
||||
}).collect::<Vec<_>>();
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let ret = match output {
|
||||
syn::ReturnType::Default => None,
|
||||
@ -832,7 +846,7 @@ impl<'a> MacroParse<(Option<BindgenAttrs>, &'a mut TokenStream)> for syn::Item {
|
||||
bail_span!(
|
||||
self,
|
||||
"#[wasm_bindgen] can only be applied to a function, \
|
||||
struct, enum, impl, or extern block",
|
||||
struct, enum, impl, or extern block",
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -885,9 +899,11 @@ impl<'a> MacroParse<BindgenAttrs> for &'a mut syn::ItemImpl {
|
||||
}
|
||||
|
||||
impl<'a, 'b> MacroParse<&'a BindgenAttrs> for (&'a Ident, &'b mut syn::ImplItem) {
|
||||
fn macro_parse(self, program: &mut ast::Program, impl_opts: &'a BindgenAttrs)
|
||||
-> Result<(), Diagnostic>
|
||||
{
|
||||
fn macro_parse(
|
||||
self,
|
||||
program: &mut ast::Program,
|
||||
impl_opts: &'a BindgenAttrs,
|
||||
) -> Result<(), Diagnostic> {
|
||||
let (class, item) = self;
|
||||
let method = match item {
|
||||
syn::ImplItem::Method(ref mut m) => m,
|
||||
@ -939,7 +955,8 @@ impl<'a, 'b> MacroParse<&'a BindgenAttrs> for (&'a Ident, &'b mut syn::ImplItem)
|
||||
true,
|
||||
Some(class),
|
||||
)?;
|
||||
let js_class = impl_opts.js_class()
|
||||
let js_class = impl_opts
|
||||
.js_class()
|
||||
.map(|s| s.to_string())
|
||||
.unwrap_or(class.to_string());
|
||||
|
||||
@ -1001,7 +1018,8 @@ impl MacroParse<()> for syn::ItemEnum {
|
||||
name: v.ident.clone(),
|
||||
value,
|
||||
})
|
||||
}).collect::<Result<_, Diagnostic>>()?;
|
||||
})
|
||||
.collect::<Result<_, Diagnostic>>()?;
|
||||
let comments = extract_doc_comments(&self.attrs);
|
||||
program.enums.push(ast::Enum {
|
||||
name: self.ident,
|
||||
@ -1025,10 +1043,10 @@ impl MacroParse<BindgenAttrs> for syn::ItemConst {
|
||||
..
|
||||
}) => {
|
||||
program.typescript_custom_sections.push(litstr.value());
|
||||
},
|
||||
}
|
||||
_ => {
|
||||
bail_span!(self, "Expected a string literal to be used with #[wasm_bindgen(typescript_custom_section)].");
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -6,113 +6,114 @@ pub const SCHEMA_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! shared_api {
|
||||
($mac:ident) => ($mac! {
|
||||
struct Program<'a> {
|
||||
exports: Vec<Export<'a>>,
|
||||
enums: Vec<Enum<'a>>,
|
||||
imports: Vec<Import<'a>>,
|
||||
structs: Vec<Struct<'a>>,
|
||||
typescript_custom_sections: Vec<&'a str>,
|
||||
// version: &'a str,
|
||||
// schema_version: &'a str,
|
||||
}
|
||||
($mac:ident) => {
|
||||
$mac! {
|
||||
struct Program<'a> {
|
||||
exports: Vec<Export<'a>>,
|
||||
enums: Vec<Enum<'a>>,
|
||||
imports: Vec<Import<'a>>,
|
||||
structs: Vec<Struct<'a>>,
|
||||
typescript_custom_sections: Vec<&'a str>,
|
||||
// version: &'a str,
|
||||
// schema_version: &'a str,
|
||||
}
|
||||
|
||||
struct Import<'a> {
|
||||
module: Option<&'a str>,
|
||||
js_namespace: Option<&'a str>,
|
||||
kind: ImportKind<'a>,
|
||||
}
|
||||
struct Import<'a> {
|
||||
module: Option<&'a str>,
|
||||
js_namespace: Option<&'a str>,
|
||||
kind: ImportKind<'a>,
|
||||
}
|
||||
|
||||
enum ImportKind<'a> {
|
||||
Function(ImportFunction<'a>),
|
||||
Static(ImportStatic<'a>),
|
||||
Type(ImportType<'a>),
|
||||
Enum(ImportEnum),
|
||||
}
|
||||
enum ImportKind<'a> {
|
||||
Function(ImportFunction<'a>),
|
||||
Static(ImportStatic<'a>),
|
||||
Type(ImportType<'a>),
|
||||
Enum(ImportEnum),
|
||||
}
|
||||
|
||||
struct ImportFunction<'a> {
|
||||
shim: &'a str,
|
||||
catch: bool,
|
||||
variadic: bool,
|
||||
method: Option<MethodData<'a>>,
|
||||
structural: bool,
|
||||
function: Function<'a>,
|
||||
}
|
||||
struct ImportFunction<'a> {
|
||||
shim: &'a str,
|
||||
catch: bool,
|
||||
variadic: bool,
|
||||
method: Option<MethodData<'a>>,
|
||||
structural: bool,
|
||||
function: Function<'a>,
|
||||
}
|
||||
|
||||
struct MethodData<'a> {
|
||||
class: &'a str,
|
||||
kind: MethodKind<'a>,
|
||||
}
|
||||
struct MethodData<'a> {
|
||||
class: &'a str,
|
||||
kind: MethodKind<'a>,
|
||||
}
|
||||
|
||||
enum MethodKind<'a> {
|
||||
Constructor,
|
||||
Operation(Operation<'a>),
|
||||
}
|
||||
enum MethodKind<'a> {
|
||||
Constructor,
|
||||
Operation(Operation<'a>),
|
||||
}
|
||||
|
||||
struct Operation<'a> {
|
||||
is_static: bool,
|
||||
kind: OperationKind<'a>,
|
||||
}
|
||||
struct Operation<'a> {
|
||||
is_static: bool,
|
||||
kind: OperationKind<'a>,
|
||||
}
|
||||
|
||||
enum OperationKind<'a> {
|
||||
Regular,
|
||||
Getter(&'a str),
|
||||
Setter(&'a str),
|
||||
IndexingGetter,
|
||||
IndexingSetter,
|
||||
IndexingDeleter,
|
||||
}
|
||||
enum OperationKind<'a> {
|
||||
Regular,
|
||||
Getter(&'a str),
|
||||
Setter(&'a str),
|
||||
IndexingGetter,
|
||||
IndexingSetter,
|
||||
IndexingDeleter,
|
||||
}
|
||||
|
||||
struct ImportStatic<'a> {
|
||||
name: &'a str,
|
||||
shim: &'a str,
|
||||
}
|
||||
struct ImportStatic<'a> {
|
||||
name: &'a str,
|
||||
shim: &'a str,
|
||||
}
|
||||
|
||||
struct ImportType<'a> {
|
||||
name: &'a str,
|
||||
instanceof_shim: &'a str,
|
||||
vendor_prefixes: Vec<&'a str>,
|
||||
}
|
||||
struct ImportType<'a> {
|
||||
name: &'a str,
|
||||
instanceof_shim: &'a str,
|
||||
vendor_prefixes: Vec<&'a str>,
|
||||
}
|
||||
|
||||
struct ImportEnum {}
|
||||
struct ImportEnum {}
|
||||
|
||||
struct Export<'a> {
|
||||
class: Option<&'a str>,
|
||||
method: bool,
|
||||
consumed: bool,
|
||||
is_constructor: bool,
|
||||
function: Function<'a>,
|
||||
comments: Vec<&'a str>,
|
||||
}
|
||||
struct Export<'a> {
|
||||
class: Option<&'a str>,
|
||||
method: bool,
|
||||
consumed: bool,
|
||||
is_constructor: bool,
|
||||
function: Function<'a>,
|
||||
comments: Vec<&'a str>,
|
||||
}
|
||||
|
||||
struct Enum<'a> {
|
||||
name: &'a str,
|
||||
variants: Vec<EnumVariant<'a>>,
|
||||
comments: Vec<&'a str>,
|
||||
}
|
||||
struct Enum<'a> {
|
||||
name: &'a str,
|
||||
variants: Vec<EnumVariant<'a>>,
|
||||
comments: Vec<&'a str>,
|
||||
}
|
||||
|
||||
struct EnumVariant<'a> {
|
||||
name: &'a str,
|
||||
value: u32,
|
||||
}
|
||||
struct EnumVariant<'a> {
|
||||
name: &'a str,
|
||||
value: u32,
|
||||
}
|
||||
|
||||
struct Function<'a> {
|
||||
name: &'a str,
|
||||
}
|
||||
struct Function<'a> {
|
||||
name: &'a str,
|
||||
}
|
||||
|
||||
struct Struct<'a> {
|
||||
name: &'a str,
|
||||
fields: Vec<StructField<'a>>,
|
||||
comments: Vec<&'a str>,
|
||||
}
|
||||
|
||||
struct StructField<'a> {
|
||||
name: &'a str,
|
||||
readonly: bool,
|
||||
comments: Vec<&'a str>,
|
||||
}
|
||||
}) // end of mac case
|
||||
struct Struct<'a> {
|
||||
name: &'a str,
|
||||
fields: Vec<StructField<'a>>,
|
||||
comments: Vec<&'a str>,
|
||||
}
|
||||
|
||||
struct StructField<'a> {
|
||||
name: &'a str,
|
||||
readonly: bool,
|
||||
comments: Vec<&'a str>,
|
||||
}
|
||||
}
|
||||
}; // end of mac case
|
||||
} // end of mac definition
|
||||
|
||||
pub fn new_function(struct_name: &str) -> String {
|
||||
|
@ -74,7 +74,8 @@ pub fn wasm_bindgen_test(
|
||||
#test_body
|
||||
}
|
||||
}
|
||||
}).into_iter(),
|
||||
})
|
||||
.into_iter(),
|
||||
);
|
||||
|
||||
tokens.extend(leading_tokens);
|
||||
|
@ -21,7 +21,7 @@ impl Config {
|
||||
/// Create a new configuration with default settings.
|
||||
pub fn new() -> Config {
|
||||
Config {
|
||||
maximum_memory: 1 << 30, // 1GB
|
||||
maximum_memory: 1 << 30, // 1GB
|
||||
thread_stack_size: 1 << 20, // 1MB
|
||||
}
|
||||
}
|
||||
@ -103,9 +103,7 @@ struct PassiveSegment {
|
||||
len: u32,
|
||||
}
|
||||
|
||||
fn switch_data_segments_to_passive(module: &mut Module)
|
||||
-> Result<Vec<PassiveSegment>, Error>
|
||||
{
|
||||
fn switch_data_segments_to_passive(module: &mut Module) -> Result<Vec<PassiveSegment>, Error> {
|
||||
// If there's no data, nothing to make passive!
|
||||
let section = match module.data_section_mut() {
|
||||
Some(section) => section,
|
||||
@ -147,9 +145,7 @@ fn get_offset(offset: &mut InitExpr) -> Result<&mut i32, Error> {
|
||||
}
|
||||
}
|
||||
|
||||
fn import_memory_zero(module: &mut Module)
|
||||
-> Result<(), Error>
|
||||
{
|
||||
fn import_memory_zero(module: &mut Module) -> Result<(), Error> {
|
||||
// If memory is exported, let's switch it to imported. If memory isn't
|
||||
// exported then there's nothing to do as we'll deal with importing it
|
||||
// later.
|
||||
@ -170,18 +166,14 @@ fn import_memory_zero(module: &mut Module)
|
||||
|
||||
// Remove all memory sections as well as exported memory, we're switching to
|
||||
// an import
|
||||
module.sections_mut().retain(|s| {
|
||||
match s {
|
||||
Section::Memory(_) => false,
|
||||
_ => true,
|
||||
}
|
||||
module.sections_mut().retain(|s| match s {
|
||||
Section::Memory(_) => false,
|
||||
_ => true,
|
||||
});
|
||||
if let Some(s) = module.export_section_mut() {
|
||||
s.entries_mut().retain(|s| {
|
||||
match s.internal() {
|
||||
Internal::Memory(_) => false,
|
||||
_ => true,
|
||||
}
|
||||
s.entries_mut().retain(|s| match s.internal() {
|
||||
Internal::Memory(_) => false,
|
||||
_ => true,
|
||||
});
|
||||
}
|
||||
|
||||
@ -215,14 +207,14 @@ fn maybe_add_import_section(module: &mut Module) -> usize {
|
||||
_ => {}
|
||||
}
|
||||
pos = Some(i);
|
||||
break
|
||||
break;
|
||||
}
|
||||
let empty = ImportSection::with_entries(Vec::new());
|
||||
let section = Section::Import(empty);
|
||||
let len = module.sections().len();
|
||||
let pos = pos.unwrap_or_else(|| len - 1);
|
||||
module.sections_mut().insert(pos, section);
|
||||
return pos
|
||||
return pos;
|
||||
}
|
||||
|
||||
fn share_imported_memory_zero(module: &mut Module, memory_max: u32) -> Result<(), Error> {
|
||||
@ -245,7 +237,7 @@ fn share_imported_memory_zero(module: &mut Module, memory_max: u32) -> Result<()
|
||||
Some(mem.limits().maximum().unwrap_or(memory_max / PAGE_SIZE)),
|
||||
true,
|
||||
);
|
||||
return Ok(())
|
||||
return Ok(());
|
||||
}
|
||||
panic!("failed to find an imported memory")
|
||||
}
|
||||
@ -293,23 +285,23 @@ fn maybe_add_global_section(module: &mut Module) -> usize {
|
||||
// https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#high-level-structure
|
||||
for i in 0..module.sections().len() {
|
||||
match &mut module.sections_mut()[i] {
|
||||
Section::Type(_) |
|
||||
Section::Import(_) |
|
||||
Section::Function(_) |
|
||||
Section::Table(_) |
|
||||
Section::Memory(_) => continue,
|
||||
Section::Type(_)
|
||||
| Section::Import(_)
|
||||
| Section::Function(_)
|
||||
| Section::Table(_)
|
||||
| Section::Memory(_) => continue,
|
||||
Section::Global(_) => return i,
|
||||
_ => {}
|
||||
}
|
||||
pos = Some(i);
|
||||
break
|
||||
break;
|
||||
}
|
||||
let empty = GlobalSection::with_entries(Vec::new());
|
||||
let section = Section::Global(empty);
|
||||
let len = module.sections().len();
|
||||
let pos = pos.unwrap_or_else(|| len - 1);
|
||||
module.sections_mut().insert(pos, section);
|
||||
return pos
|
||||
return pos;
|
||||
}
|
||||
|
||||
fn inject_thread_id_counter(module: &mut Module) -> Result<u32, Error> {
|
||||
@ -323,14 +315,13 @@ fn inject_thread_id_counter(module: &mut Module) -> Result<u32, Error> {
|
||||
None => bail!("failed to find `__heap_base` for injecting thread id"),
|
||||
};
|
||||
|
||||
exports.entries()
|
||||
exports
|
||||
.entries()
|
||||
.iter()
|
||||
.filter(|e| e.field() == "__heap_base")
|
||||
.filter_map(|e| {
|
||||
match e.internal() {
|
||||
Internal::Global(idx) => Some(*idx),
|
||||
_ => None,
|
||||
}
|
||||
.filter_map(|e| match e.internal() {
|
||||
Internal::Global(idx) => Some(*idx),
|
||||
_ => None,
|
||||
})
|
||||
.next()
|
||||
};
|
||||
@ -414,7 +405,8 @@ fn find_stack_pointer(module: &mut Module) -> Result<Option<u32>, Error> {
|
||||
Some(s) => s,
|
||||
None => bail!("failed to find the stack pointer"),
|
||||
};
|
||||
let candidates = globals.entries()
|
||||
let candidates = globals
|
||||
.entries()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, g)| g.global_type().content_type() == ValueType::I32)
|
||||
@ -424,17 +416,19 @@ fn find_stack_pointer(module: &mut Module) -> Result<Option<u32>, Error> {
|
||||
// If there are no mutable i32 globals, assume this module doesn't even need
|
||||
// a stack pointer!
|
||||
if candidates.len() == 0 {
|
||||
return Ok(None)
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// Currently LLVM/LLD always use global 0 as the stack pointer, let's just
|
||||
// blindly assume that.
|
||||
if candidates[0].0 == 0 {
|
||||
return Ok(Some(0))
|
||||
return Ok(Some(0));
|
||||
}
|
||||
|
||||
bail!("the first global wasn't a mutable i32, has LLD changed or was \
|
||||
this wasm file not produced by LLD?")
|
||||
bail!(
|
||||
"the first global wasn't a mutable i32, has LLD changed or was \
|
||||
this wasm file not produced by LLD?"
|
||||
)
|
||||
}
|
||||
|
||||
fn start_with_init_memory(
|
||||
@ -451,7 +445,10 @@ fn start_with_init_memory(
|
||||
// Execute an atomic add to learn what our thread ID is
|
||||
instrs.push(Instruction::I32Const(addr as i32));
|
||||
instrs.push(Instruction::I32Const(1));
|
||||
let mem = parity_wasm::elements::MemArg { align: 2, offset: 0 };
|
||||
let mem = parity_wasm::elements::MemArg {
|
||||
align: 2,
|
||||
offset: 0,
|
||||
};
|
||||
instrs.push(Instruction::I32AtomicRmwAdd(mem));
|
||||
|
||||
// Store this thread ID into our thread ID global
|
||||
@ -500,7 +497,7 @@ fn start_with_init_memory(
|
||||
instrs.push(Instruction::I32Const(segment.offset as i32));
|
||||
// offset into segment
|
||||
instrs.push(Instruction::I32Const(0)); // offset into segment
|
||||
// amount to copy
|
||||
// amount to copy
|
||||
instrs.push(Instruction::I32Const(segment.len as i32));
|
||||
instrs.push(Instruction::MemoryInit(segment.idx));
|
||||
}
|
||||
@ -531,13 +528,14 @@ fn start_with_init_memory(
|
||||
};
|
||||
// ... and also be sure to add its signature to the function section ...
|
||||
let type_idx = {
|
||||
let section = module.type_section_mut().expect("module has no type section");
|
||||
let pos = section.types()
|
||||
let section = module
|
||||
.type_section_mut()
|
||||
.expect("module has no type section");
|
||||
let pos = section
|
||||
.types()
|
||||
.iter()
|
||||
.map(|t| {
|
||||
match t {
|
||||
Type::Function(t) => t,
|
||||
}
|
||||
.map(|t| match t {
|
||||
Type::Function(t) => t,
|
||||
})
|
||||
.position(|t| t.params().is_empty() && t.return_type().is_none());
|
||||
match pos {
|
||||
@ -549,7 +547,8 @@ fn start_with_init_memory(
|
||||
}
|
||||
}
|
||||
};
|
||||
module.function_section_mut()
|
||||
module
|
||||
.function_section_mut()
|
||||
.expect("module has no function section")
|
||||
.entries_mut()
|
||||
.push(Func::new(type_idx));
|
||||
@ -566,21 +565,21 @@ fn update_start_section(module: &mut Module, start: u32) {
|
||||
let mut pos = None;
|
||||
for i in 0..module.sections().len() {
|
||||
match &mut module.sections_mut()[i] {
|
||||
Section::Type(_) |
|
||||
Section::Import(_) |
|
||||
Section::Function(_) |
|
||||
Section::Table(_) |
|
||||
Section::Memory(_) |
|
||||
Section::Global(_) |
|
||||
Section::Export(_) => continue,
|
||||
Section::Type(_)
|
||||
| Section::Import(_)
|
||||
| Section::Function(_)
|
||||
| Section::Table(_)
|
||||
| Section::Memory(_)
|
||||
| Section::Global(_)
|
||||
| Section::Export(_) => continue,
|
||||
Section::Start(start_idx) => {
|
||||
*start_idx = start;
|
||||
return
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
pos = Some(i);
|
||||
break
|
||||
break;
|
||||
}
|
||||
let section = Section::Start(start);
|
||||
let len = module.sections().len();
|
||||
@ -588,28 +587,22 @@ fn update_start_section(module: &mut Module, start: u32) {
|
||||
module.sections_mut().insert(pos, section);
|
||||
}
|
||||
|
||||
fn implement_thread_intrinsics(
|
||||
module: &mut Module,
|
||||
globals: &Globals,
|
||||
) -> Result<(), Error> {
|
||||
fn implement_thread_intrinsics(module: &mut Module, globals: &Globals) -> Result<(), Error> {
|
||||
let mut map = HashMap::new();
|
||||
{
|
||||
let imports = match module.import_section() {
|
||||
Some(i) => i,
|
||||
None => return Ok(()),
|
||||
};
|
||||
let entries = imports.entries()
|
||||
let entries = imports
|
||||
.entries()
|
||||
.iter()
|
||||
.filter(|i| {
|
||||
match i.external() {
|
||||
External::Function(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
.filter(|i| match i.external() {
|
||||
External::Function(_) => true,
|
||||
_ => false,
|
||||
})
|
||||
.enumerate()
|
||||
.filter(|(_, entry)| {
|
||||
entry.module() == "__wbindgen_thread_xform__"
|
||||
});
|
||||
.filter(|(_, entry)| entry.module() == "__wbindgen_thread_xform__");
|
||||
for (idx, entry) in entries {
|
||||
let type_idx = match entry.external() {
|
||||
External::Function(i) => *i,
|
||||
@ -622,17 +615,13 @@ fn implement_thread_intrinsics(
|
||||
// Validate the type for this intrinsic
|
||||
match entry.field() {
|
||||
"__wbindgen_thread_id" => {
|
||||
if !fty.params().is_empty() ||
|
||||
fty.return_type() != Some(ValueType::I32)
|
||||
{
|
||||
if !fty.params().is_empty() || fty.return_type() != Some(ValueType::I32) {
|
||||
bail!("__wbindgen_thread_id intrinsic has the wrong signature");
|
||||
}
|
||||
map.insert(idx as u32, Instruction::GetGlobal(globals.thread_id));
|
||||
}
|
||||
"__wbindgen_tcb_get" => {
|
||||
if !fty.params().is_empty() ||
|
||||
fty.return_type() != Some(ValueType::I32)
|
||||
{
|
||||
if !fty.params().is_empty() || fty.return_type() != Some(ValueType::I32) {
|
||||
bail!("__wbindgen_tcb_get intrinsic has the wrong signature");
|
||||
}
|
||||
map.insert(idx as u32, Instruction::GetGlobal(globals.thread_tcb));
|
||||
@ -653,12 +642,10 @@ fn implement_thread_intrinsics(
|
||||
for body in module.code_section_mut().unwrap().bodies_mut() {
|
||||
for instr in body.code_mut().elements_mut() {
|
||||
let other = match instr {
|
||||
Instruction::Call(idx) => {
|
||||
match map.get(idx) {
|
||||
Some(other) => other,
|
||||
None => continue,
|
||||
}
|
||||
}
|
||||
Instruction::Call(idx) => match map.get(idx) {
|
||||
Some(other) => other,
|
||||
None => continue,
|
||||
},
|
||||
_ => continue,
|
||||
};
|
||||
*instr = other.clone();
|
||||
|
@ -93,7 +93,8 @@ fn build_function(
|
||||
segments,
|
||||
},
|
||||
})
|
||||
}).collect::<Vec<_>>();
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut ret_segments = syn::punctuated::Punctuated::new();
|
||||
ret_segments.push(syn::PathSegment {
|
||||
|
@ -262,10 +262,12 @@ impl Interpreter {
|
||||
Instruction::I32Const(x) => Some((i, x as u32, entry)),
|
||||
_ => None,
|
||||
}
|
||||
}).find(|(_i, offset, entry)| {
|
||||
})
|
||||
.find(|(_i, offset, entry)| {
|
||||
*offset <= descriptor_table_idx
|
||||
&& descriptor_table_idx < (*offset + entry.members().len() as u32)
|
||||
}).expect("failed to find index in table elements");
|
||||
})
|
||||
.expect("failed to find index in table elements");
|
||||
let idx = (descriptor_table_idx - offset) as usize;
|
||||
let descriptor_idx = entry.members()[idx];
|
||||
|
||||
@ -300,7 +302,8 @@ impl Interpreter {
|
||||
.map(|i| {
|
||||
assert_eq!(i.value_type(), ValueType::I32);
|
||||
i.count()
|
||||
}).unwrap_or(0);
|
||||
})
|
||||
.unwrap_or(0);
|
||||
|
||||
let code_sig = sections.functions.entries()[code_idx].type_ref();
|
||||
let function_ty = match §ions.types.types()[code_sig as usize] {
|
||||
|
@ -59,7 +59,8 @@ fn try_main() -> Result<(), failure::Error> {
|
||||
.map(|mut p| {
|
||||
p.drain(0.."CARGO_FEATURE_".len());
|
||||
p
|
||||
}).collect::<HashSet<_>>();
|
||||
})
|
||||
.collect::<HashSet<_>>();
|
||||
|
||||
let mut allowed = Vec::new();
|
||||
for feature in features.filter(|f| !f.starts_with("#") && !f.starts_with("[")) {
|
||||
|
@ -10,8 +10,8 @@ extern "C" {
|
||||
#[wasm_bindgen_test]
|
||||
fn element() {
|
||||
/* Tests needed for:
|
||||
namespace_uri
|
||||
*/
|
||||
namespace_uri
|
||||
*/
|
||||
let element = new_div();
|
||||
|
||||
assert_eq!(element.prefix(), None, "Shouldn't have a prefix");
|
||||
@ -52,17 +52,17 @@ fn element() {
|
||||
"Should return nothing if removed"
|
||||
);
|
||||
/* Tests needed for:
|
||||
get_attribute_ns
|
||||
*/
|
||||
get_attribute_ns
|
||||
*/
|
||||
|
||||
/*TODO should we enable toggle_attribute tests? (Firefox Nightly + Chrome canary only)
|
||||
// TODO toggle_attribute should permit a single argument when optional arguments are supported
|
||||
assert!(!element.has_attribute("disabled"), "Should not be disabled");
|
||||
assert!(element.toggle_attribute("disabled", true).unwrap(), "Should return true when attribute is set");
|
||||
assert!(element.has_attribute("disabled"), "Should be disabled");
|
||||
assert!(!element.toggle_attribute("disabled", false).unwrap(), "Should return false when attribute is not set");
|
||||
assert!(!element.has_attribute("disabled"), "Should not be disabled");
|
||||
*/
|
||||
// TODO toggle_attribute should permit a single argument when optional arguments are supported
|
||||
assert!(!element.has_attribute("disabled"), "Should not be disabled");
|
||||
assert!(element.toggle_attribute("disabled", true).unwrap(), "Should return true when attribute is set");
|
||||
assert!(element.has_attribute("disabled"), "Should be disabled");
|
||||
assert!(!element.toggle_attribute("disabled", false).unwrap(), "Should return false when attribute is not set");
|
||||
assert!(!element.has_attribute("disabled"), "Should not be disabled");
|
||||
*/
|
||||
|
||||
assert!(!element.has_attribute("title"), "Should not have a title");
|
||||
assert_eq!(
|
||||
@ -79,8 +79,8 @@ get_attribute_ns
|
||||
);
|
||||
assert!(!element.has_attribute("title"), "Should not have a title");
|
||||
/* Tests needed for:
|
||||
set_attribute_ns
|
||||
*/
|
||||
set_attribute_ns
|
||||
*/
|
||||
|
||||
assert!(!element.has_attributes(), "Should not have any attributes");
|
||||
assert_eq!(
|
||||
@ -95,10 +95,10 @@ set_attribute_ns
|
||||
"Should return nothing if removed"
|
||||
);
|
||||
/* Tests needed for:
|
||||
remove_attribute_ns
|
||||
has_attribure_ns
|
||||
closest
|
||||
*/
|
||||
remove_attribute_ns
|
||||
has_attribure_ns
|
||||
closest
|
||||
*/
|
||||
|
||||
assert_eq!(
|
||||
element.matches(".this-is-a-thing").unwrap(),
|
||||
@ -130,29 +130,29 @@ closest
|
||||
// TODO non standard moz_matches_selector should we even support?
|
||||
|
||||
/* Tests needed for:
|
||||
insert_adjacent_element
|
||||
insert_adjacent_text
|
||||
set_pointer_capture
|
||||
release_pointer_capture
|
||||
has_pointer_capture
|
||||
set_capture
|
||||
release_capture
|
||||
scroll_top
|
||||
set_scroll_top
|
||||
scroll_left
|
||||
set_scroll_left
|
||||
scroll_width
|
||||
scroll_height
|
||||
scroll,
|
||||
scroll_to
|
||||
scroll_by
|
||||
client_top
|
||||
client_left
|
||||
client_width
|
||||
client_height
|
||||
scroll_top_max
|
||||
scroll_left_max
|
||||
*/
|
||||
insert_adjacent_element
|
||||
insert_adjacent_text
|
||||
set_pointer_capture
|
||||
release_pointer_capture
|
||||
has_pointer_capture
|
||||
set_capture
|
||||
release_capture
|
||||
scroll_top
|
||||
set_scroll_top
|
||||
scroll_left
|
||||
set_scroll_left
|
||||
scroll_width
|
||||
scroll_height
|
||||
scroll,
|
||||
scroll_to
|
||||
scroll_by
|
||||
client_top
|
||||
client_left
|
||||
client_width
|
||||
client_height
|
||||
scroll_top_max
|
||||
scroll_left_max
|
||||
*/
|
||||
assert_eq!(element.inner_html(), "", "Should return no content");
|
||||
element.set_inner_html("<strong>Hey!</strong><em>Web!</em>");
|
||||
assert_eq!(
|
||||
@ -173,10 +173,10 @@ scroll_left_max
|
||||
assert_eq!(element.inner_html(), "", "Should return no content");
|
||||
|
||||
/* Tests needed for:
|
||||
outer_html
|
||||
set_outer_html
|
||||
insert_adjacent_html
|
||||
*/
|
||||
outer_html
|
||||
set_outer_html
|
||||
insert_adjacent_html
|
||||
*/
|
||||
|
||||
assert!(
|
||||
element.query_selector(".none-existant").unwrap().is_none(),
|
||||
@ -191,9 +191,9 @@ insert_adjacent_html
|
||||
"Should return no results"
|
||||
);
|
||||
/* Tests needed for:
|
||||
slot
|
||||
set_slot
|
||||
request_fullscreen
|
||||
request_pointer_lock
|
||||
*/
|
||||
slot
|
||||
set_slot
|
||||
request_fullscreen
|
||||
request_pointer_lock
|
||||
*/
|
||||
}
|
||||
|
@ -70,12 +70,12 @@ fn test_html_element() {
|
||||
assert!(element.is_content_editable(), "Should be content_editable");
|
||||
|
||||
/*TODO doesn't work in Chrome
|
||||
// TODO verify case where menu is passed
|
||||
match element.context_menu() {
|
||||
None => assert!(true, "Shouldn't have a custom menu set"),
|
||||
_ => assert!(false, "Shouldn't have a custom menu set")
|
||||
};
|
||||
*/
|
||||
// TODO verify case where menu is passed
|
||||
match element.context_menu() {
|
||||
None => assert!(true, "Shouldn't have a custom menu set"),
|
||||
_ => assert!(false, "Shouldn't have a custom menu set")
|
||||
};
|
||||
*/
|
||||
|
||||
// TODO: This test is also broken in Chrome (but not Firefox).
|
||||
// assert!(!element.spellcheck(), "Shouldn't be spellchecked");
|
||||
|
@ -53,10 +53,10 @@ fn test_input_element() {
|
||||
assert!(element.default_checked(), "Should have an default_checked");
|
||||
|
||||
/*TODO fix
|
||||
assert!(!element.checked(), "Shouldn't be checked");
|
||||
element.set_checked(true);
|
||||
assert!(element.checked(), "Should be checked");
|
||||
*/
|
||||
assert!(!element.checked(), "Shouldn't be checked");
|
||||
element.set_checked(true);
|
||||
assert!(element.checked(), "Should be checked");
|
||||
*/
|
||||
|
||||
assert!(!element.disabled(), "Shouldn't be disabled");
|
||||
element.set_disabled(true);
|
||||
@ -114,29 +114,29 @@ fn test_input_element() {
|
||||
assert!(!element.indeterminate(), "Shouldn't be indeterminate");
|
||||
*/
|
||||
/*TODO add tests
|
||||
pub fn indeterminate(&self) -> bool
|
||||
pub fn set_indeterminate(&self, indeterminate: bool)
|
||||
pub fn input_mode(&self) -> String
|
||||
pub fn set_input_mode(&self, input_mode: &str)
|
||||
pub fn list(&self) -> Option<HtmlElement>
|
||||
pub fn max(&self) -> String
|
||||
pub fn set_max(&self, max: &str)
|
||||
pub fn max_length(&self) -> i32
|
||||
pub fn set_max_length(&self, max_length: i32)
|
||||
pub fn min(&self) -> String
|
||||
pub fn set_min(&self, min: &str)
|
||||
pub fn min_length(&self) -> i32
|
||||
pub fn set_min_length(&self, min_length: i32)
|
||||
pub fn multiple(&self) -> bool
|
||||
pub fn set_multiple(&self, multiple: bool)
|
||||
*/
|
||||
pub fn indeterminate(&self) -> bool
|
||||
pub fn set_indeterminate(&self, indeterminate: bool)
|
||||
pub fn input_mode(&self) -> String
|
||||
pub fn set_input_mode(&self, input_mode: &str)
|
||||
pub fn list(&self) -> Option<HtmlElement>
|
||||
pub fn max(&self) -> String
|
||||
pub fn set_max(&self, max: &str)
|
||||
pub fn max_length(&self) -> i32
|
||||
pub fn set_max_length(&self, max_length: i32)
|
||||
pub fn min(&self) -> String
|
||||
pub fn set_min(&self, min: &str)
|
||||
pub fn min_length(&self) -> i32
|
||||
pub fn set_min_length(&self, min_length: i32)
|
||||
pub fn multiple(&self) -> bool
|
||||
pub fn set_multiple(&self, multiple: bool)
|
||||
*/
|
||||
assert_eq!(element.name(), "", "Should not have a name");
|
||||
element.set_name("namey");
|
||||
assert_eq!(element.name(), "namey", "Should have a name");
|
||||
/*TODO add tests
|
||||
pub fn pattern(&self) -> String
|
||||
pub fn set_pattern(&self, pattern: &str)
|
||||
*/
|
||||
pub fn pattern(&self) -> String
|
||||
pub fn set_pattern(&self, pattern: &str)
|
||||
*/
|
||||
assert_eq!(element.placeholder(), "", "Should not have a placeholder");
|
||||
element.set_placeholder("some text");
|
||||
assert_eq!(
|
||||
@ -153,30 +153,30 @@ pub fn set_pattern(&self, pattern: &str)
|
||||
element.set_required(true);
|
||||
assert!(element.required(), "Should be required");
|
||||
/*TODO add tests
|
||||
pub fn size(&self) -> u32
|
||||
pub fn set_size(&self, size: u32)
|
||||
*/
|
||||
pub fn size(&self) -> u32
|
||||
pub fn set_size(&self, size: u32)
|
||||
*/
|
||||
/*TODO fails in chrome
|
||||
element.set_type("image");
|
||||
assert_eq!(element.src(), "", "Should have no src");
|
||||
element.set_value("hey.png");
|
||||
assert_eq!(element.src(), "hey.png", "Should have a src");
|
||||
*/
|
||||
element.set_type("image");
|
||||
assert_eq!(element.src(), "", "Should have no src");
|
||||
element.set_value("hey.png");
|
||||
assert_eq!(element.src(), "hey.png", "Should have a src");
|
||||
*/
|
||||
/*TODO add tests
|
||||
pub fn src(&self) -> String
|
||||
pub fn set_src(&self, src: &str)
|
||||
pub fn step(&self) -> String
|
||||
pub fn set_step(&self, step: &str)
|
||||
pub fn type_(&self) -> String
|
||||
pub fn set_type(&self, type_: &str)
|
||||
pub fn default_value(&self) -> String
|
||||
pub fn set_default_value(&self, default_value: &str)
|
||||
*/
|
||||
pub fn src(&self) -> String
|
||||
pub fn set_src(&self, src: &str)
|
||||
pub fn step(&self) -> String
|
||||
pub fn set_step(&self, step: &str)
|
||||
pub fn type_(&self) -> String
|
||||
pub fn set_type(&self, type_: &str)
|
||||
pub fn default_value(&self) -> String
|
||||
pub fn set_default_value(&self, default_value: &str)
|
||||
*/
|
||||
/*TODO fails in chrome
|
||||
assert_eq!(element.value(), "", "Should have no value");
|
||||
element.set_value("hey!");
|
||||
assert_eq!(element.value(), "hey!", "Should have a value");
|
||||
*/
|
||||
assert_eq!(element.value(), "", "Should have no value");
|
||||
element.set_value("hey!");
|
||||
assert_eq!(element.value(), "hey!", "Should have a value");
|
||||
*/
|
||||
element.set_type("number");
|
||||
element.set_value("1");
|
||||
assert_eq!(element.value_as_number(), 1.0, "Should have value 1");
|
||||
@ -199,31 +199,31 @@ pub fn set_default_value(&self, default_value: &str)
|
||||
assert_eq!(element.check_validity(), true, "Should be valid");
|
||||
assert_eq!(element.report_validity(), true, "Should be valid");
|
||||
/*TODO add tests
|
||||
pub fn labels(&self) -> Option<NodeList>
|
||||
pub fn select(&self)
|
||||
pub fn selection_direction(&self) -> Result<Option<String>, JsValue>
|
||||
pub fn set_selection_direction(
|
||||
&self,
|
||||
selection_direction: Option<&str>
|
||||
) -> Result<(), JsValue>
|
||||
pub fn set_range_text(&self, replacement: &str) -> Result<(), JsValue>
|
||||
pub fn set_selection_range(
|
||||
&self,
|
||||
start: u32,
|
||||
end: u32,
|
||||
direction: &str
|
||||
) -> Result<(), JsValue>
|
||||
*/
|
||||
pub fn labels(&self) -> Option<NodeList>
|
||||
pub fn select(&self)
|
||||
pub fn selection_direction(&self) -> Result<Option<String>, JsValue>
|
||||
pub fn set_selection_direction(
|
||||
&self,
|
||||
selection_direction: Option<&str>
|
||||
) -> Result<(), JsValue>
|
||||
pub fn set_range_text(&self, replacement: &str) -> Result<(), JsValue>
|
||||
pub fn set_selection_range(
|
||||
&self,
|
||||
start: u32,
|
||||
end: u32,
|
||||
direction: &str
|
||||
) -> Result<(), JsValue>
|
||||
*/
|
||||
|
||||
assert_eq!(element.align(), "", "Should have no align");
|
||||
element.set_align("left");
|
||||
assert_eq!(element.align(), "left", "Should have an align");
|
||||
/*TODO add tests
|
||||
pub fn use_map(&self) -> String
|
||||
pub fn set_use_map(&self, use_map: &str)
|
||||
pub fn text_length(&self) -> i32
|
||||
pub fn webkitdirectory(&self) -> bool
|
||||
pub fn set_webkitdirectory(&self, webkitdirectory: bool)
|
||||
pub fn set_focus_state(&self, a_is_focused: bool)
|
||||
*/
|
||||
pub fn use_map(&self) -> String
|
||||
pub fn set_use_map(&self, use_map: &str)
|
||||
pub fn text_length(&self) -> i32
|
||||
pub fn webkitdirectory(&self) -> bool
|
||||
pub fn set_webkitdirectory(&self, webkitdirectory: bool)
|
||||
pub fn set_focus_state(&self, a_is_focused: bool)
|
||||
*/
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ pub mod input_element;
|
||||
//pub mod menu_element;
|
||||
//pub mod menu_item_element;
|
||||
pub mod dom_point;
|
||||
pub mod indexeddb;
|
||||
pub mod location;
|
||||
pub mod meta_element;
|
||||
pub mod meter_element;
|
||||
@ -55,7 +56,6 @@ pub mod style_element;
|
||||
pub mod table_element;
|
||||
pub mod title_element;
|
||||
pub mod xpath_result;
|
||||
pub mod indexeddb;
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn deref_works() {
|
||||
|
@ -8,7 +8,8 @@ fn test_option_element() {
|
||||
"option_value",
|
||||
false,
|
||||
true,
|
||||
).unwrap();
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
option.set_disabled(true);
|
||||
assert_eq!(
|
||||
|
@ -312,8 +312,8 @@ impl<'src> FirstPass<'src, ()> for weedle::InterfaceDefinition<'src> {
|
||||
interface_data.partial = false;
|
||||
interface_data.superclass = self.inheritance.map(|s| s.identifier.0);
|
||||
interface_data.definition_attributes = self.attributes.as_ref();
|
||||
interface_data.deprecated = util::get_rust_deprecated(&self.attributes)
|
||||
.map(|s| s.to_string());
|
||||
interface_data.deprecated =
|
||||
util::get_rust_deprecated(&self.attributes).map(|s| s.to_string());
|
||||
}
|
||||
if let Some(attrs) = &self.attributes {
|
||||
for attr in attrs.body.list.iter() {
|
||||
|
@ -527,12 +527,13 @@ impl<'a> IdlType<'a> {
|
||||
// it's up to users to dispatch and/or create instances
|
||||
// appropriately.
|
||||
if let syn::Type::Path(path) = &inner {
|
||||
if path.qself.is_none() && path
|
||||
.path
|
||||
.segments
|
||||
.last()
|
||||
.map(|p| p.value().ident == "JsValue")
|
||||
.unwrap_or(false)
|
||||
if path.qself.is_none()
|
||||
&& path
|
||||
.path
|
||||
.segments
|
||||
.last()
|
||||
.map(|p| p.value().ident == "JsValue")
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return Some(inner.clone());
|
||||
}
|
||||
@ -678,7 +679,8 @@ fn idl_type_flatten_test() {
|
||||
Sequence(Box::new(Double),),
|
||||
Interface("NodeList"),
|
||||
])),),
|
||||
]).flatten(),
|
||||
])
|
||||
.flatten(),
|
||||
vec![
|
||||
Interface("Node"),
|
||||
Sequence(Box::new(Long)),
|
||||
@ -710,5 +712,6 @@ fn clamped(t: syn::Type) -> syn::Type {
|
||||
.into_iter()
|
||||
.collect(),
|
||||
},
|
||||
}.into()
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
@ -128,8 +128,7 @@ fn parse(webidl_source: &str, allowed_types: Option<&[&str]>) -> Result<Program>
|
||||
if let backend::ast::ImportKind::Type(t) = &mut import.kind {
|
||||
t.extends.retain(|n| {
|
||||
let ident = &n.segments.last().unwrap().value().ident;
|
||||
first_pass_record.builtin_idents.contains(ident) ||
|
||||
filter(&ident.to_string())
|
||||
first_pass_record.builtin_idents.contains(ident) || filter(&ident.to_string())
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -176,7 +175,8 @@ fn builtin_idents() -> BTreeSet<Ident> {
|
||||
"Promise",
|
||||
"Function",
|
||||
"Clamped",
|
||||
].into_iter()
|
||||
]
|
||||
.into_iter()
|
||||
.map(|id| proc_macro2::Ident::new(id, proc_macro2::Span::call_site())),
|
||||
)
|
||||
}
|
||||
@ -240,7 +240,8 @@ fn compile_ast(mut ast: Program) -> String {
|
||||
|
||||
(quote! {
|
||||
pub mod #name { #m_tokens }
|
||||
}).to_tokens(&mut tokens);
|
||||
})
|
||||
.to_tokens(&mut tokens);
|
||||
}
|
||||
tokens.to_string()
|
||||
}
|
||||
@ -266,7 +267,8 @@ impl<'src> FirstPassRecord<'src> {
|
||||
} else {
|
||||
rust_ident("None")
|
||||
}
|
||||
}).collect(),
|
||||
})
|
||||
.collect(),
|
||||
variant_values: variants.iter().map(|v| v.0.to_string()).collect(),
|
||||
rust_attrs: vec![parse_quote!(#[derive(Copy, Clone, PartialEq, Debug)])],
|
||||
}),
|
||||
@ -505,7 +507,9 @@ impl<'src> FirstPassRecord<'src> {
|
||||
// whitelist a few names that have known polyfills
|
||||
match name {
|
||||
"AudioContext" => {
|
||||
import_type.vendor_prefixes.push(Ident::new("webkit", Span::call_site()));
|
||||
import_type
|
||||
.vendor_prefixes
|
||||
.push(Ident::new("webkit", Span::call_site()));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -657,12 +661,12 @@ impl<'src> FirstPassRecord<'src> {
|
||||
};
|
||||
let doc = match id {
|
||||
OperationId::Operation(None) => Some(String::new()),
|
||||
OperationId::Constructor(_) => {
|
||||
Some(format!("The `new {}(..)` constructor, creating a new \
|
||||
instance of `{0}`\n\n{}",
|
||||
self_name,
|
||||
mdn_doc(self_name, Some(self_name))))
|
||||
}
|
||||
OperationId::Constructor(_) => Some(format!(
|
||||
"The `new {}(..)` constructor, creating a new \
|
||||
instance of `{0}`\n\n{}",
|
||||
self_name,
|
||||
mdn_doc(self_name, Some(self_name))
|
||||
)),
|
||||
OperationId::Operation(Some(name)) => Some(format!(
|
||||
"The `{}()` method\n\n{}",
|
||||
name,
|
||||
|
@ -30,7 +30,8 @@ pub(crate) fn shared_ref(ty: syn::Type, mutable: bool) -> syn::Type {
|
||||
None
|
||||
},
|
||||
elem: Box::new(ty),
|
||||
}.into()
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Fix case of identifiers like `HTMLBRElement` or `texImage2D`
|
||||
@ -174,7 +175,8 @@ pub(crate) fn slice_ty(t: syn::Type) -> syn::Type {
|
||||
syn::TypeSlice {
|
||||
bracket_token: Default::default(),
|
||||
elem: Box::new(t),
|
||||
}.into()
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
/// From `T` create `Vec<T>`.
|
||||
@ -571,12 +573,13 @@ impl<'src> FirstPassRecord<'src> {
|
||||
let structural =
|
||||
force_structural || is_structural(signature.orig.attrs.as_ref(), container_attrs);
|
||||
let catch = force_throws || throws(&signature.orig.attrs);
|
||||
let variadic = signature.args.len() == signature.orig.args.len() && signature
|
||||
.orig
|
||||
.args
|
||||
.last()
|
||||
.map(|arg| arg.variadic)
|
||||
.unwrap_or(false);
|
||||
let variadic = signature.args.len() == signature.orig.args.len()
|
||||
&& signature
|
||||
.orig
|
||||
.args
|
||||
.last()
|
||||
.map(|arg| arg.variadic)
|
||||
.unwrap_or(false);
|
||||
ret.extend(
|
||||
self.create_one_function(
|
||||
name,
|
||||
@ -660,25 +663,20 @@ pub fn is_no_interface_object(ext_attrs: &Option<ExtendedAttributeList>) -> bool
|
||||
has_named_attribute(ext_attrs.as_ref(), "NoInterfaceObject")
|
||||
}
|
||||
|
||||
pub fn get_rust_deprecated<'a>(ext_attrs: &Option<ExtendedAttributeList<'a>>)
|
||||
-> Option<&'a str>
|
||||
{
|
||||
ext_attrs.as_ref()?
|
||||
pub fn get_rust_deprecated<'a>(ext_attrs: &Option<ExtendedAttributeList<'a>>) -> Option<&'a str> {
|
||||
ext_attrs
|
||||
.as_ref()?
|
||||
.body
|
||||
.list
|
||||
.iter()
|
||||
.filter_map(|attr| {
|
||||
match attr {
|
||||
ExtendedAttribute::Ident(id) => Some(id),
|
||||
_ => None,
|
||||
}
|
||||
.filter_map(|attr| match attr {
|
||||
ExtendedAttribute::Ident(id) => Some(id),
|
||||
_ => None,
|
||||
})
|
||||
.filter(|attr| attr.lhs_identifier.0 == "RustDeprecated")
|
||||
.filter_map(|ident| {
|
||||
match ident.rhs {
|
||||
IdentifierOrString::String(s) => Some(s),
|
||||
IdentifierOrString::Identifier(_) => None,
|
||||
}
|
||||
.filter_map(|ident| match ident.rhs {
|
||||
IdentifierOrString::String(s) => Some(s),
|
||||
IdentifierOrString::Identifier(_) => None,
|
||||
})
|
||||
.next()
|
||||
.map(|s| s.0)
|
||||
|
@ -51,7 +51,8 @@ pub fn run() -> Promise {
|
||||
let request = Request::new_with_str_and_init(
|
||||
"https://api.github.com/repos/rustwasm/wasm-bindgen/branches/master",
|
||||
&opts,
|
||||
).unwrap();
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
request
|
||||
.headers()
|
||||
@ -67,10 +68,12 @@ pub fn run() -> Promise {
|
||||
assert!(resp_value.is_instance_of::<Response>());
|
||||
let resp: Response = resp_value.dyn_into().unwrap();
|
||||
resp.json()
|
||||
}).and_then(|json_value: Promise| {
|
||||
})
|
||||
.and_then(|json_value: Promise| {
|
||||
// Convert this other `Promise` into a rust `Future`.
|
||||
JsFuture::from(json_value)
|
||||
}).and_then(|json| {
|
||||
})
|
||||
.and_then(|json| {
|
||||
// Use serde to parse the JSON into a struct.
|
||||
let branch_info: Branch = json.into_serde().unwrap();
|
||||
|
||||
|
@ -31,10 +31,7 @@ pub fn main() -> Result<(), JsValue> {
|
||||
context.move_to(event.offset_x() as f64, event.offset_y() as f64);
|
||||
pressed.set(true);
|
||||
}) as Box<FnMut(_)>);
|
||||
canvas.add_event_listener_with_callback(
|
||||
"mousedown",
|
||||
closure.as_ref().unchecked_ref(),
|
||||
)?;
|
||||
canvas.add_event_listener_with_callback("mousedown", closure.as_ref().unchecked_ref())?;
|
||||
closure.forget();
|
||||
}
|
||||
{
|
||||
@ -48,10 +45,7 @@ pub fn main() -> Result<(), JsValue> {
|
||||
context.move_to(event.offset_x() as f64, event.offset_y() as f64);
|
||||
}
|
||||
}) as Box<FnMut(_)>);
|
||||
canvas.add_event_listener_with_callback(
|
||||
"mousemove",
|
||||
closure.as_ref().unchecked_ref(),
|
||||
)?;
|
||||
canvas.add_event_listener_with_callback("mousemove", closure.as_ref().unchecked_ref())?;
|
||||
closure.forget();
|
||||
}
|
||||
{
|
||||
@ -62,10 +56,7 @@ pub fn main() -> Result<(), JsValue> {
|
||||
context.line_to(event.offset_x() as f64, event.offset_y() as f64);
|
||||
context.stroke();
|
||||
}) as Box<FnMut(_)>);
|
||||
canvas.add_event_listener_with_callback(
|
||||
"mouseup",
|
||||
closure.as_ref().unchecked_ref(),
|
||||
)?;
|
||||
canvas.add_event_listener_with_callback("mouseup", closure.as_ref().unchecked_ref())?;
|
||||
closure.forget();
|
||||
}
|
||||
|
||||
|
@ -7,16 +7,16 @@ extern crate web_sys;
|
||||
use std::cell::RefCell;
|
||||
use std::cmp;
|
||||
use std::rc::Rc;
|
||||
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering::SeqCst};
|
||||
use std::sync::atomic::ATOMIC_USIZE_INIT;
|
||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering::SeqCst};
|
||||
use std::sync::{Arc, Mutex, MutexGuard};
|
||||
|
||||
use futures::Future;
|
||||
use futures::sync::oneshot;
|
||||
use js_sys::{Promise, Error, WebAssembly, Uint8ClampedArray, Array};
|
||||
use wasm_bindgen::JsCast;
|
||||
use futures::Future;
|
||||
use js_sys::{Array, Error, Promise, Uint8ClampedArray, WebAssembly};
|
||||
use wasm_bindgen::prelude::*;
|
||||
use web_sys::{CanvasRenderingContext2d, Worker, Event, ErrorEvent};
|
||||
use wasm_bindgen::JsCast;
|
||||
use web_sys::{CanvasRenderingContext2d, ErrorEvent, Event, Worker};
|
||||
use web_sys::{DedicatedWorkerGlobalScope, MessageEvent};
|
||||
|
||||
macro_rules! console_log {
|
||||
@ -42,7 +42,8 @@ impl Scene {
|
||||
pub fn new(object: &JsValue) -> Result<Scene, JsValue> {
|
||||
console_error_panic_hook::set_once();
|
||||
Ok(Scene {
|
||||
inner: object.into_serde()
|
||||
inner: object
|
||||
.into_serde()
|
||||
.map_err(|e| JsValue::from(e.to_string()))?,
|
||||
})
|
||||
}
|
||||
@ -82,7 +83,7 @@ impl Scene {
|
||||
Ok(false) => *slot = Some(data),
|
||||
Err(e) => {
|
||||
*slot = Some(data);
|
||||
return Err(e)
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -145,10 +146,7 @@ impl WorkerPool {
|
||||
workers.push(worker);
|
||||
}
|
||||
|
||||
Ok(WorkerPool {
|
||||
workers,
|
||||
callback,
|
||||
})
|
||||
Ok(WorkerPool { workers, callback })
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,7 +209,7 @@ struct Shared {
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
extern "C" {
|
||||
type ImageData;
|
||||
|
||||
#[wasm_bindgen(constructor, catch)]
|
||||
@ -234,12 +232,12 @@ impl Render {
|
||||
if let Some(id) = id.as_f64() {
|
||||
if id == self.shared.id as f64 {
|
||||
self.ctx.put_image_data(image.unchecked_ref(), 0.0, 0.0)?;
|
||||
return Ok(done.as_bool() == Some(true))
|
||||
return Ok(done.as_bool() == Some(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
console_log!("unhandled message: {:?}", data);
|
||||
return Ok(false)
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
console_log!("unhandled event: {}", event.type_());
|
||||
@ -250,13 +248,10 @@ impl Render {
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn child_entry_point(ptr: u32) -> Result<(), JsValue> {
|
||||
let ptr = unsafe {
|
||||
Arc::from_raw(ptr as *const Shared)
|
||||
};
|
||||
let ptr = unsafe { Arc::from_raw(ptr as *const Shared) };
|
||||
assert_send(&ptr);
|
||||
|
||||
let global = js_sys::global()
|
||||
.unchecked_into::<DedicatedWorkerGlobalScope>();
|
||||
let global = js_sys::global().unchecked_into::<DedicatedWorkerGlobalScope>();
|
||||
ptr.work(&global)?;
|
||||
|
||||
return Ok(());
|
||||
@ -288,7 +283,7 @@ impl Shared {
|
||||
// If we're beyond the end then we're done!
|
||||
let start = self.next_pixel.fetch_add(BLOCK, SeqCst);
|
||||
if start >= end {
|
||||
break
|
||||
break;
|
||||
}
|
||||
|
||||
// Raytrace all our pixels synchronously, writing all the results
|
||||
@ -308,8 +303,7 @@ impl Shared {
|
||||
// Ok, time to synchronize and commit this data back into the main
|
||||
// image buffer for other threads and the main thread to see.
|
||||
let mut data = self.rgb_data.lock().unwrap();
|
||||
data[start * 4..(start + len) * 4]
|
||||
.copy_from_slice(&mut local_rgb[..len * 4]);
|
||||
data[start * 4..(start + len) * 4].copy_from_slice(&mut local_rgb[..len * 4]);
|
||||
|
||||
// As a "nifty feature" we try to have a live progressive rendering.
|
||||
// That means that we need to periodically send an `ImageData` to
|
||||
@ -319,7 +313,6 @@ impl Shared {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If we're the last thread out, be sure to update the main thread's
|
||||
// image as this is the last chance we'll get!
|
||||
if self.remaining.fetch_sub(1, SeqCst) == 1 {
|
||||
@ -341,19 +334,13 @@ impl Shared {
|
||||
// JS array using `slice`. This means we can't use
|
||||
// `web_sys::ImageData` right now but rather we have to use our own
|
||||
// binding.
|
||||
let mem = wasm_bindgen::memory()
|
||||
.unchecked_into::<WebAssembly::Memory>();
|
||||
let mem = Uint8ClampedArray::new(&mem.buffer())
|
||||
.slice(
|
||||
data.as_ptr() as u32,
|
||||
data.as_ptr() as u32 + data.len() as u32,
|
||||
);
|
||||
let mem = wasm_bindgen::memory().unchecked_into::<WebAssembly::Memory>();
|
||||
let mem = Uint8ClampedArray::new(&mem.buffer()).slice(
|
||||
data.as_ptr() as u32,
|
||||
data.as_ptr() as u32 + data.len() as u32,
|
||||
);
|
||||
drop(data); // unlock the lock, we've copied the data now
|
||||
let data = ImageData::new(
|
||||
&mem,
|
||||
self.scene.width as f64,
|
||||
self.scene.height as f64,
|
||||
)?;
|
||||
let data = ImageData::new(&mem, self.scene.width as f64, self.scene.height as f64)?;
|
||||
let arr = Array::new();
|
||||
arr.push(&data);
|
||||
arr.push(&JsValue::from(done));
|
||||
|
@ -74,7 +74,6 @@ impl FmOsc {
|
||||
// control the amount of modulation.
|
||||
fm_osc.connect_with_audio_node(&fm_gain)?;
|
||||
|
||||
|
||||
// Connect the FM oscillator to the frequency parameter of the main
|
||||
// oscillator, so that the FM node can modulate its frequency.
|
||||
fm_gain.connect_with_audio_param(&primary.frequency())?;
|
||||
|
@ -2,17 +2,16 @@ extern crate js_sys;
|
||||
extern crate wasm_bindgen;
|
||||
extern crate web_sys;
|
||||
|
||||
use js_sys::WebAssembly;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::JsCast;
|
||||
use web_sys::{WebGlProgram, WebGlRenderingContext, WebGlShader};
|
||||
use js_sys::{WebAssembly};
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn draw() -> Result<(), JsValue> {
|
||||
let document = web_sys::window().unwrap().document().unwrap();
|
||||
let canvas = document.get_element_by_id("canvas").unwrap();
|
||||
let canvas: web_sys::HtmlCanvasElement = canvas
|
||||
.dyn_into::<web_sys::HtmlCanvasElement>()?;
|
||||
let canvas: web_sys::HtmlCanvasElement = canvas.dyn_into::<web_sys::HtmlCanvasElement>()?;
|
||||
|
||||
let context = canvas
|
||||
.get_context("webgl")?
|
||||
@ -42,12 +41,12 @@ pub fn draw() -> Result<(), JsValue> {
|
||||
context.use_program(Some(&program));
|
||||
|
||||
let vertices: [f32; 9] = [-0.7, -0.7, 0.0, 0.7, -0.7, 0.0, 0.0, 0.7, 0.0];
|
||||
let memory_buffer = wasm_bindgen::memory().dyn_into::<WebAssembly::Memory>()?.buffer();
|
||||
let memory_buffer = wasm_bindgen::memory()
|
||||
.dyn_into::<WebAssembly::Memory>()?
|
||||
.buffer();
|
||||
let vertices_location = vertices.as_ptr() as u32 / 4;
|
||||
let vert_array = js_sys::Float32Array::new(&memory_buffer).subarray(
|
||||
vertices_location,
|
||||
vertices_location + vertices.len() as u32,
|
||||
);
|
||||
let vert_array = js_sys::Float32Array::new(&memory_buffer)
|
||||
.subarray(vertices_location, vertices_location + vertices.len() as u32);
|
||||
|
||||
let buffer = context.create_buffer().ok_or("failed to create buffer")?;
|
||||
context.bind_buffer(WebGlRenderingContext::ARRAY_BUFFER, Some(&buffer));
|
||||
|
33
src/lib.rs
33
src/lib.rs
@ -86,7 +86,6 @@ impl JsValue {
|
||||
_marker: marker::PhantomData,
|
||||
};
|
||||
|
||||
|
||||
/// The `true` JS value constant.
|
||||
pub const TRUE: JsValue = JsValue {
|
||||
idx: JSIDX_TRUE,
|
||||
@ -113,9 +112,7 @@ impl JsValue {
|
||||
/// be owned by the JS garbage collector.
|
||||
#[inline]
|
||||
pub fn from_str(s: &str) -> JsValue {
|
||||
unsafe {
|
||||
JsValue::_new(__wbindgen_string_new(s.as_ptr(), s.len()))
|
||||
}
|
||||
unsafe { JsValue::_new(__wbindgen_string_new(s.as_ptr(), s.len())) }
|
||||
}
|
||||
|
||||
/// Creates a new JS value which is a number.
|
||||
@ -124,9 +121,7 @@ impl JsValue {
|
||||
/// allocated number) and returns a handle to the JS version of it.
|
||||
#[inline]
|
||||
pub fn from_f64(n: f64) -> JsValue {
|
||||
unsafe {
|
||||
JsValue::_new(__wbindgen_number_new(n))
|
||||
}
|
||||
unsafe { JsValue::_new(__wbindgen_number_new(n)) }
|
||||
}
|
||||
|
||||
/// Creates a new JS value which is a boolean.
|
||||
@ -135,7 +130,11 @@ impl JsValue {
|
||||
/// allocated boolean) and returns a handle to the JS version of it.
|
||||
#[inline]
|
||||
pub fn from_bool(b: bool) -> JsValue {
|
||||
if b { JsValue::TRUE } else { JsValue::FALSE }
|
||||
if b {
|
||||
JsValue::TRUE
|
||||
} else {
|
||||
JsValue::FALSE
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new JS value representing `undefined`.
|
||||
@ -183,9 +182,7 @@ impl JsValue {
|
||||
T: serde::ser::Serialize + ?Sized,
|
||||
{
|
||||
let s = serde_json::to_string(t)?;
|
||||
unsafe {
|
||||
Ok(JsValue::_new(__wbindgen_json_parse(s.as_ptr(), s.len())))
|
||||
}
|
||||
unsafe { Ok(JsValue::_new(__wbindgen_json_parse(s.as_ptr(), s.len()))) }
|
||||
}
|
||||
|
||||
/// Invokes `JSON.stringify` on this value and then parses the resulting
|
||||
@ -351,7 +348,7 @@ if_std! {
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for JsValue {
|
||||
#[inline]
|
||||
#[inline]
|
||||
fn from(s: &'a str) -> JsValue {
|
||||
JsValue::from_str(s)
|
||||
}
|
||||
@ -588,9 +585,7 @@ impl<T: FromWasmAbi + 'static> Deref for JsStatic<T> {
|
||||
// wasm, as the pointer will eventually be invalidated but you can get
|
||||
// `&'static T` from this interface. We... probably need to deprecate
|
||||
// and/or remove this interface nowadays.
|
||||
unsafe {
|
||||
self.__inner.with(|ptr| &*(ptr as *const T))
|
||||
}
|
||||
unsafe { self.__inner.with(|ptr| &*(ptr as *const T)) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -648,16 +643,12 @@ pub fn throw_val(s: JsValue) -> ! {
|
||||
/// may prevent your wasm module from building down the road.
|
||||
#[doc(hidden)]
|
||||
pub fn module() -> JsValue {
|
||||
unsafe {
|
||||
JsValue::_new(__wbindgen_module())
|
||||
}
|
||||
unsafe { JsValue::_new(__wbindgen_module()) }
|
||||
}
|
||||
|
||||
/// Returns a handle to this wasm instance's `WebAssembly.Memory`
|
||||
pub fn memory() -> JsValue {
|
||||
unsafe {
|
||||
JsValue::_new(__wbindgen_memory())
|
||||
}
|
||||
unsafe { JsValue::_new(__wbindgen_memory()) }
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
@ -354,7 +354,6 @@ impl JsRename {
|
||||
#[wasm_bindgen(js_name = classes_foo)]
|
||||
pub fn foo() {}
|
||||
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct AccessFieldFoo {
|
||||
pub bar: AccessFieldBar,
|
||||
@ -389,13 +388,10 @@ pub struct RenamedExport {
|
||||
#[wasm_bindgen(js_class = JsRenamedExport)]
|
||||
impl RenamedExport {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new() -> RenamedExport{
|
||||
RenamedExport {
|
||||
x: 3,
|
||||
}
|
||||
}
|
||||
pub fn foo(&self) {
|
||||
pub fn new() -> RenamedExport {
|
||||
RenamedExport { x: 3 }
|
||||
}
|
||||
pub fn foo(&self) {}
|
||||
|
||||
pub fn bar(&self, other: &RenamedExport) {
|
||||
drop(other);
|
||||
|
@ -218,13 +218,17 @@ fn drop_drops() {
|
||||
|
||||
impl Drop for A {
|
||||
fn drop(&mut self) {
|
||||
unsafe { HIT = true; }
|
||||
unsafe {
|
||||
HIT = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
let a = A;
|
||||
let x: Closure<Fn()> = Closure::new(move || drop(&a));
|
||||
drop(x);
|
||||
unsafe { assert!(HIT); }
|
||||
unsafe {
|
||||
assert!(HIT);
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
@ -233,7 +237,9 @@ fn drop_during_call_ok() {
|
||||
struct A;
|
||||
impl Drop for A {
|
||||
fn drop(&mut self) {
|
||||
unsafe { HIT = true; }
|
||||
unsafe {
|
||||
HIT = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -246,7 +252,9 @@ fn drop_during_call_ok() {
|
||||
drop(rc2.borrow_mut().take().unwrap());
|
||||
|
||||
// `A` should not have been destroyed as a result
|
||||
unsafe { assert!(!HIT); }
|
||||
unsafe {
|
||||
assert!(!HIT);
|
||||
}
|
||||
|
||||
// allocate some heap memory to try to paper over our `3`
|
||||
drop(String::from("1234567890"));
|
||||
@ -256,12 +264,18 @@ fn drop_during_call_ok() {
|
||||
|
||||
// make sure `A` is bound to our closure environment.
|
||||
drop(&a);
|
||||
unsafe { assert!(!HIT); }
|
||||
unsafe {
|
||||
assert!(!HIT);
|
||||
}
|
||||
});
|
||||
drop_during_call_save(&x);
|
||||
*rc.borrow_mut() = Some(x);
|
||||
drop(rc);
|
||||
unsafe { assert!(!HIT); }
|
||||
unsafe {
|
||||
assert!(!HIT);
|
||||
}
|
||||
drop_during_call_call();
|
||||
unsafe { assert!(HIT); }
|
||||
unsafe {
|
||||
assert!(HIT);
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ fn dead_imports_not_generated() {
|
||||
#[cfg(feature = "nightly")]
|
||||
fn import_inside_function_works() {
|
||||
#[wasm_bindgen(module = "tests/wasm/imports.js")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn import_inside_function_works();
|
||||
}
|
||||
import_inside_function_works();
|
||||
@ -199,7 +199,7 @@ mod private {
|
||||
|
||||
pub fn foo() {
|
||||
#[wasm_bindgen(module = "tests/wasm/imports.js")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn import_inside_private_module();
|
||||
}
|
||||
import_inside_private_module();
|
||||
@ -207,7 +207,7 @@ mod private {
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn something_not_defined_in_the_environment();
|
||||
|
||||
type TypeThatIsNotDefined;
|
||||
@ -224,7 +224,7 @@ extern {
|
||||
#[wasm_bindgen_test]
|
||||
fn undefined_function_is_ok() {
|
||||
if !should_call_undefined_functions() {
|
||||
return
|
||||
return;
|
||||
}
|
||||
something_not_defined_in_the_environment();
|
||||
|
||||
|
@ -132,7 +132,8 @@ fn serde() {
|
||||
b: "foo".to_string(),
|
||||
c: None,
|
||||
d: Bar { a: 1 },
|
||||
}).unwrap(),
|
||||
})
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
let foo = ret.into_serde::<Foo>().unwrap();
|
||||
|
Reference in New Issue
Block a user