Run rustfmt over everything

This commit is contained in:
Alex Crichton
2018-11-27 12:07:59 -08:00
parent 4a70198143
commit 48f4adfa8c
45 changed files with 872 additions and 800 deletions

View File

@ -1,7 +1,7 @@
use Diagnostic;
use proc_macro2::{Ident, Span}; use proc_macro2::{Ident, Span};
use shared; use shared;
use syn; use syn;
use Diagnostic;
/// An abstract syntax tree representing a rust program. Contains /// An abstract syntax tree representing a rust program. Contains
/// extra information for joining up this rust code with javascript. /// extra information for joining up this rust code with javascript.

View File

@ -1,6 +1,6 @@
use std::collections::HashSet; use std::collections::HashSet;
use std::sync::Mutex;
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use std::sync::Mutex;
use proc_macro2::{Ident, Literal, Span, TokenStream}; use proc_macro2::{Ident, Literal, Span, TokenStream};
use quote::ToTokens; use quote::ToTokens;
@ -89,9 +89,11 @@ impl TryToTokens for ast::Program {
// See comments in `crates/cli-support/src/lib.rs` about what this // See comments in `crates/cli-support/src/lib.rs` about what this
// `schema_version` is. // `schema_version` is.
let prefix_json = format!(r#"{{"schema_version":"{}","version":"{}"}}"#, let prefix_json = format!(
r#"{{"schema_version":"{}","version":"{}"}}"#,
shared::SCHEMA_VERSION, shared::SCHEMA_VERSION,
shared::version()); shared::version()
);
let mut bytes = Vec::new(); let mut bytes = Vec::new();
bytes.push((prefix_json.len() >> 0) as u8); bytes.push((prefix_json.len() >> 0) as u8);
bytes.push((prefix_json.len() >> 8) as u8); bytes.push((prefix_json.len() >> 8) as u8);
@ -110,7 +112,8 @@ impl TryToTokens for ast::Program {
#[doc(hidden)] #[doc(hidden)]
pub static #generated_static_name: [u8; #generated_static_length] = pub static #generated_static_name: [u8; #generated_static_length] =
*#generated_static_value; *#generated_static_value;
}).to_tokens(tokens); })
.to_tokens(tokens);
Ok(()) Ok(())
} }
@ -237,7 +240,8 @@ impl ToTokens for ast::Struct {
(*js).borrow_mut() (*js).borrow_mut()
} }
} }
}).to_tokens(tokens); })
.to_tokens(tokens);
for field in self.fields.iter() { for field in self.fields.iter() {
field.to_tokens(tokens); field.to_tokens(tokens);
@ -273,14 +277,16 @@ impl ToTokens for ast::StructField {
&mut GlobalStack::new(), &mut GlobalStack::new(),
) )
} }
}).to_tokens(tokens); })
.to_tokens(tokens);
Descriptor( Descriptor(
&getter, &getter,
quote! { quote! {
<#ty as WasmDescribe>::describe(); <#ty as WasmDescribe>::describe();
}, },
).to_tokens(tokens); )
.to_tokens(tokens);
if self.readonly { if self.readonly {
return; return;
@ -305,7 +311,8 @@ impl ToTokens for ast::StructField {
); );
(*js).borrow_mut().#name = val; (*js).borrow_mut().#name = val;
} }
}).to_tokens(tokens); })
.to_tokens(tokens);
} }
} }
@ -461,7 +468,8 @@ impl TryToTokens for ast::Export {
}; };
#convert_ret #convert_ret
} }
}).to_tokens(into); })
.to_tokens(into);
// In addition to generating the shim function above which is what // In addition to generating the shim function above which is what
// our generated JS will invoke, we *also* generate a "descriptor" // our generated JS will invoke, we *also* generate a "descriptor"
@ -488,7 +496,8 @@ impl TryToTokens for ast::Export {
#(<#argtys as WasmDescribe>::describe();)* #(<#argtys as WasmDescribe>::describe();)*
#describe_ret #describe_ret
}, },
).to_tokens(into); )
.to_tokens(into);
Ok(()) Ok(())
} }
@ -670,7 +679,8 @@ impl ToTokens for ast::ImportType {
self.as_ref() self.as_ref()
} }
} }
}).to_tokens(tokens); })
.to_tokens(tokens);
for superclass in self.extends.iter() { for superclass in self.extends.iter() {
(quote! { (quote! {
impl From<#rust_name> for #superclass { impl From<#rust_name> for #superclass {
@ -688,7 +698,8 @@ impl ToTokens for ast::ImportType {
#superclass::unchecked_from_js_ref(self.as_ref()) #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; let this_index = current_idx;
current_idx += 1; current_idx += 1;
Literal::usize_unsuffixed(this_index) Literal::usize_unsuffixed(this_index)
}).collect(); })
.collect();
// Borrow variant_indexes because we need to use it multiple times inside the quote! macro // Borrow variant_indexes because we need to use it multiple times inside the quote! macro
let variant_indexes_ref = &variant_indexes; let variant_indexes_ref = &variant_indexes;
@ -946,7 +958,8 @@ impl TryToTokens for ast::ImportFunction {
impl #class { impl #class {
#invocation #invocation
} }
}).to_tokens(tokens); })
.to_tokens(tokens);
} else { } else {
invocation.to_tokens(tokens); invocation.to_tokens(tokens);
} }
@ -981,7 +994,8 @@ impl<'a> ToTokens for DescribeImport<'a> {
#(<#argtys as WasmDescribe>::describe();)* #(<#argtys as WasmDescribe>::describe();)*
#inform_ret #inform_ret
}, },
).to_tokens(tokens); )
.to_tokens(tokens);
} }
} }
@ -1025,7 +1039,8 @@ impl ToTokens for ast::Enum {
inform(ENUM); inform(ENUM);
} }
} }
}).to_tokens(into); })
.to_tokens(into);
} }
} }
@ -1061,7 +1076,8 @@ impl ToTokens for ast::ImportStatic {
__inner: &_VAL, __inner: &_VAL,
} }
}; };
}).to_tokens(into); })
.to_tokens(into);
} }
} }
@ -1106,7 +1122,8 @@ impl ToTokens for ast::Const {
impl #class { impl #class {
#declaration #declaration
} }
}).to_tokens(tokens); })
.to_tokens(tokens);
} else { } else {
declaration.to_tokens(tokens); 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(); ::wasm_bindgen::__rt::link_mem_intrinsics();
#inner #inner
} }
}).to_tokens(tokens); })
.to_tokens(tokens);
} }
} }

View File

@ -3,8 +3,8 @@ use std::collections::HashMap;
use proc_macro2::{Ident, Span}; use proc_macro2::{Ident, Span};
use Diagnostic;
use ast; use ast;
use Diagnostic;
pub fn encode(program: &ast::Program) -> Result<Vec<u8>, Diagnostic> { pub fn encode(program: &ast::Program) -> Result<Vec<u8>, Diagnostic> {
let mut e = Encoder::new(); let mut e = Encoder::new();
@ -19,13 +19,15 @@ struct Interner {
impl Interner { impl Interner {
fn new() -> Interner { fn new() -> Interner {
Interner { map: RefCell::new(HashMap::new()) } Interner {
map: RefCell::new(HashMap::new()),
}
} }
fn intern(&self, s: &Ident) -> &str { fn intern(&self, s: &Ident) -> &str {
let mut map = self.map.borrow_mut(); let mut map = self.map.borrow_mut();
if let Some(s) = map.get(s) { 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()); map.insert(s.clone(), s.to_string());
unsafe { &*(&*map[s] as *const str) } unsafe { &*(&*map[s] as *const str) }
@ -36,17 +38,32 @@ impl Interner {
} }
} }
fn shared_program<'a>(prog: &'a ast::Program, intern: &'a Interner) fn shared_program<'a>(
-> Result<Program<'a>, Diagnostic> prog: &'a ast::Program,
{ intern: &'a Interner,
) -> Result<Program<'a>, Diagnostic> {
Ok(Program { Ok(Program {
exports: prog.exports.iter().map(|a| shared_export(a, intern)).collect(), exports: prog
structs: prog.structs.iter().map(|a| shared_struct(a, intern)).collect(), .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(), 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)) .map(|a| shared_import(a, intern))
.collect::<Result<Vec<_>, _>>()?, .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(), // version: shared::version(),
// schema_version: shared::SCHEMA_VERSION.to_string(), // 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> { fn shared_function<'a>(func: &'a ast::Function, _intern: &'a Interner) -> Function<'a> {
Function { Function { name: &func.name }
name: &func.name,
}
} }
fn shared_enum<'a>(e: &'a ast::Enum, intern: &'a Interner) -> Enum<'a> { fn shared_enum<'a>(e: &'a ast::Enum, intern: &'a Interner) -> Enum<'a> {
Enum { Enum {
name: intern.intern(&e.name), 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(), 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) fn shared_import<'a>(i: &'a ast::Import, intern: &'a Interner) -> Result<Import<'a>, Diagnostic> {
-> Result<Import<'a>, Diagnostic>
{
Ok(Import { Ok(Import {
module: i.module.as_ref().map(|s| &**s), module: i.module.as_ref().map(|s| &**s),
js_namespace: i.js_namespace.as_ref().map(|s| intern.intern(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) fn shared_import_kind<'a>(
-> Result<ImportKind<'a>, Diagnostic> i: &'a ast::ImportKind,
{ intern: &'a Interner,
) -> Result<ImportKind<'a>, Diagnostic> {
Ok(match i { Ok(match i {
ast::ImportKind::Function(f) => ImportKind::Function(shared_import_function(f, intern)?), ast::ImportKind::Function(f) => ImportKind::Function(shared_import_function(f, intern)?),
ast::ImportKind::Static(f) => ImportKind::Static(shared_import_static(f, intern)), ast::ImportKind::Static(f) => ImportKind::Static(shared_import_static(f, intern)),
@ -110,9 +128,10 @@ fn shared_import_kind<'a>(i: &'a ast::ImportKind, intern: &'a Interner)
}) })
} }
fn shared_import_function<'a>(i: &'a ast::ImportFunction, intern: &'a Interner) fn shared_import_function<'a>(
-> Result<ImportFunction<'a>, Diagnostic> i: &'a ast::ImportFunction,
{ intern: &'a Interner,
) -> Result<ImportFunction<'a>, Diagnostic> {
let method = match &i.kind { let method = match &i.kind {
ast::ImportFunctionKind::Method { class, kind, .. } => { ast::ImportFunctionKind::Method { class, kind, .. } => {
let kind = match kind { let kind = match kind {
@ -123,9 +142,7 @@ fn shared_import_function<'a>(i: &'a ast::ImportFunction, intern: &'a Interner)
ast::OperationKind::Regular => OperationKind::Regular, ast::OperationKind::Regular => OperationKind::Regular,
ast::OperationKind::Getter(g) => { ast::OperationKind::Getter(g) => {
let g = g.as_ref().map(|g| intern.intern(g)); let g = g.as_ref().map(|g| intern.intern(g));
OperationKind::Getter( OperationKind::Getter(g.unwrap_or_else(|| i.infer_getter_property()))
g.unwrap_or_else(|| i.infer_getter_property()),
)
} }
ast::OperationKind::Setter(s) => { ast::OperationKind::Setter(s) => {
let s = s.as_ref().map(|s| intern.intern(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 }) MethodKind::Operation(Operation { is_static, kind })
} }
}; };
Some(MethodData { Some(MethodData { class, kind })
class,
kind,
})
} }
ast::ImportFunctionKind::Normal => None, 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) fn shared_import_static<'a>(i: &'a ast::ImportStatic, intern: &'a Interner) -> ImportStatic<'a> {
-> ImportStatic<'a>
{
ImportStatic { ImportStatic {
name: &i.js_name, name: &i.js_name,
shim: intern.intern(&i.shim), shim: intern.intern(&i.shim),
} }
} }
fn shared_import_type<'a>(i: &'a ast::ImportType, intern: &'a Interner) fn shared_import_type<'a>(i: &'a ast::ImportType, intern: &'a Interner) -> ImportType<'a> {
-> ImportType<'a>
{
ImportType { ImportType {
name: &i.js_name, name: &i.js_name,
instanceof_shim: &i.instanceof_shim, instanceof_shim: &i.instanceof_shim,
vendor_prefixes: i.vendor_prefixes.iter() vendor_prefixes: i.vendor_prefixes.iter().map(|x| intern.intern(x)).collect(),
.map(|x| intern.intern(x))
.collect(),
} }
} }
fn shared_import_enum<'a>(_i: &'a ast::ImportEnum, _intern: &'a Interner) fn shared_import_enum<'a>(_i: &'a ast::ImportEnum, _intern: &'a Interner) -> ImportEnum {
-> ImportEnum
{
ImportEnum {} ImportEnum {}
} }
fn shared_struct<'a>(s: &'a ast::Struct, intern: &'a Interner) -> Struct<'a> { fn shared_struct<'a>(s: &'a ast::Struct, intern: &'a Interner) -> Struct<'a> {
Struct { Struct {
name: &s.js_name, 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(), comments: s.comments.iter().map(|s| &**s).collect(),
} }
} }
fn shared_struct_field<'a>(s: &'a ast::StructField, intern: &'a Interner) fn shared_struct_field<'a>(s: &'a ast::StructField, intern: &'a Interner) -> StructField<'a> {
-> StructField<'a>
{
StructField { StructField {
name: intern.intern(&s.name), name: intern.intern(&s.name),
readonly: s.readonly, readonly: s.readonly,

View File

@ -1,8 +1,5 @@
#![recursion_limit = "256"] #![recursion_limit = "256"]
#![cfg_attr( #![cfg_attr(feature = "extra-traits", deny(missing_debug_implementations))]
feature = "extra-traits",
deny(missing_debug_implementations)
)]
#![doc(html_root_url = "https://docs.rs/wasm-bindgen-backend/0.2")] #![doc(html_root_url = "https://docs.rs/wasm-bindgen-backend/0.2")]
#[macro_use] #[macro_use]
@ -25,6 +22,6 @@ mod error;
pub mod ast; pub mod ast;
mod codegen; mod codegen;
mod encode;
pub mod defined; pub mod defined;
mod encode;
pub mod util; pub mod util;

View File

@ -71,7 +71,8 @@ where
.map(|i| syn::PathSegment { .map(|i| syn::PathSegment {
ident: i, ident: i,
arguments: syn::PathArguments::None, arguments: syn::PathArguments::None,
}).collect(); })
.collect();
syn::TypePath { syn::TypePath {
qself: None, qself: None,
@ -83,7 +84,8 @@ where
}, },
segments: syn::punctuated::Punctuated::from_iter(segments), segments: syn::punctuated::Punctuated::from_iter(segments),
}, },
}.into() }
.into()
} }
pub fn ident_ty(ident: Ident) -> syn::Type { pub fn ident_ty(ident: Ident) -> syn::Type {

View File

@ -6,14 +6,14 @@ pub trait Decode<'src>: Sized {
fn decode_all(mut data: &'src [u8]) -> Self { fn decode_all(mut data: &'src [u8]) -> Self {
let ret = Self::decode(&mut data); let ret = Self::decode(&mut data);
assert!(data.len() == 0); assert!(data.len() == 0);
return ret return ret;
} }
} }
fn get<'a>(b: &mut &'a [u8]) -> u8 { fn get<'a>(b: &mut &'a [u8]) -> u8 {
let r = b[0]; let r = b[0];
*b = &b[1..]; *b = &b[1..];
return r return r;
} }
impl<'src> Decode<'src> for bool { impl<'src> Decode<'src> for bool {
@ -30,7 +30,7 @@ impl<'src> Decode<'src> for u32 {
let byte = get(data); let byte = get(data);
cur |= ((byte & 0x7f) as u32) << offset; cur |= ((byte & 0x7f) as u32) << offset;
if byte & 0x80 == 0 { if byte & 0x80 == 0 {
break cur break cur;
} }
offset += 7; offset += 7;
} }

View File

@ -44,7 +44,8 @@ pub fn rewrite(input: &mut Context) -> Result<(), Error> {
.import_section() .import_section()
.map(|s| s.functions()) .map(|s| s.functions())
.unwrap_or(0) as u32, .unwrap_or(0) as u32,
}.remap_module(input.module); }
.remap_module(input.module);
info.delete_function_table_entries(input); info.delete_function_table_entries(input);
info.inject_imports(input)?; info.inject_imports(input)?;
@ -236,13 +237,10 @@ impl ClosureDescriptors {
.rust_argument("b") .rust_argument("b")
.finally("this.a = a;\n"); .finally("this.a = a;\n");
} else { } else {
builder.rust_argument("this.a") builder.rust_argument("this.a").rust_argument("b");
.rust_argument("b");
} }
builder.finally("if (this.cnt-- == 1) d(this.a, b);"); builder.finally("if (this.cnt-- == 1) d(this.a, b);");
builder builder.process(&closure.function)?.finish("function", "f")
.process(&closure.function)?
.finish("function", "f")
}; };
input.expose_add_heap_object(); input.expose_add_heap_object();
input.function_table_needed = true; input.function_table_needed = true;

View File

@ -549,7 +549,8 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
self.ret_expr = " self.ret_expr = "
const ret = RET; const ret = RET;
return ret === 0xFFFFFF ? undefined : ret; return ret === 0xFFFFFF ? undefined : ret;
".to_string(); "
.to_string();
return Ok(self); return Ok(self);
} }
@ -583,7 +584,8 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
self.ret_expr = " self.ret_expr = "
const ret = RET; const ret = RET;
return ret === 0xFFFFFF ? undefined : ret !== 0; return ret === 0xFFFFFF ? undefined : ret !== 0;
".to_string(); "
.to_string();
return Ok(self); return Ok(self);
} }
Descriptor::Char => { Descriptor::Char => {
@ -597,7 +599,8 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
const present = getUint32Memory()[retptr / 4]; const present = getUint32Memory()[retptr / 4];
const value = getUint32Memory()[retptr / 4 + 1]; const value = getUint32Memory()[retptr / 4 + 1];
return present === 0 ? undefined : String.fromCodePoint(value); return present === 0 ? undefined : String.fromCodePoint(value);
".to_string(); "
.to_string();
return Ok(self); return Ok(self);
} }
_ => bail!( _ => bail!(

View File

@ -3,10 +3,10 @@ use std::mem;
use decode; use decode;
use failure::{Error, ResultExt}; use failure::{Error, ResultExt};
use parity_wasm::elements::*;
use parity_wasm::elements::Error as ParityError;
use shared;
use gc; use gc;
use parity_wasm::elements::Error as ParityError;
use parity_wasm::elements::*;
use shared;
use super::Bindgen; use super::Bindgen;
use descriptor::{Descriptor, VectorKind}; use descriptor::{Descriptor, VectorKind};
@ -438,8 +438,10 @@ impl<'a> Context<'a> {
self.bind("__wbindgen_module", &|me| { self.bind("__wbindgen_module", &|me| {
if !me.config.no_modules { if !me.config.no_modules {
bail!("`wasm_bindgen::module` is currently only supported with \ bail!(
--no-modules"); "`wasm_bindgen::module` is currently only supported with \
--no-modules"
);
} }
me.expose_add_heap_object(); me.expose_add_heap_object();
Ok(format!( Ok(format!(
@ -541,7 +543,9 @@ impl<'a> Context<'a> {
}})();", }})();",
globals = self.globals, globals = self.globals,
module = module_name, module = module_name,
global_name = self.config.no_modules_global global_name = self
.config
.no_modules_global
.as_ref() .as_ref()
.map(|s| &**s) .map(|s| &**s)
.unwrap_or("wasm_bindgen"), .unwrap_or("wasm_bindgen"),
@ -581,7 +585,9 @@ impl<'a> Context<'a> {
}})();", }})();",
globals = self.globals, globals = self.globals,
module = module_name, module = module_name,
global_name = self.config.no_modules_global global_name = self
.config
.no_modules_global
.as_ref() .as_ref()
.map(|s| &**s) .map(|s| &**s)
.unwrap_or("wasm_bindgen"), .unwrap_or("wasm_bindgen"),
@ -787,7 +793,8 @@ impl<'a> Context<'a> {
.filter_map(|s| match *s { .filter_map(|s| match *s {
Section::Import(ref mut s) => Some(s), Section::Import(ref mut s) => Some(s),
_ => None, _ => None,
}).flat_map(|s| s.entries_mut()); })
.flat_map(|s| s.entries_mut());
for import in imports { for import in imports {
if import.module() == "__wbindgen_placeholder__" { if import.module() == "__wbindgen_placeholder__" {
@ -1172,18 +1179,20 @@ impl<'a> Context<'a> {
fn expose_text_processor(&mut self, s: &str) { fn expose_text_processor(&mut self, s: &str) {
if self.config.nodejs_experimental_modules { 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)); self.global(&format!("let cached{0} = new {0}('utf-8');", s));
} else if self.config.nodejs { } else if self.config.nodejs {
self.global(&format!("const {0} = require('util').{0};", s)); self.global(&format!("const {0} = require('util').{0};", s));
self.global(&format!("let cached{0} = new {0}('utf-8');", s)); self.global(&format!("let cached{0} = new {0}('utf-8');", s));
} else if !(self.config.browser || self.config.no_modules) { } else if !(self.config.browser || self.config.no_modules) {
self.global( self.global(&format!(
&format!(" "
const l{0} = typeof {0} === 'undefined' ? \ const l{0} = typeof {0} === 'undefined' ? \
require('util').{0} : {0};\ require('util').{0} : {0};\
", s) ",
); s
));
self.global(&format!("let cached{0} = new l{0}('utf-8');", s)); self.global(&format!("let cached{0} = new l{0}('utf-8');", s));
} else { } else {
self.global(&format!("let cached{0} = new {0}('utf-8');", s)); 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); let module = module.parse_names().unwrap_or_else(|p| p.1);
*self.module = module; *self.module = module;
if self.config.remove_name_section { if self.config.remove_name_section {
self.module.sections_mut().retain(|s| { self.module.sections_mut().retain(|s| match s {
match s {
Section::Name(_) => false, Section::Name(_) => false,
_ => true, _ => true,
}
}); });
} }
} }
@ -1815,7 +1822,8 @@ impl<'a> Context<'a> {
.filter_map(|i| match i.external() { .filter_map(|i| match i.external() {
External::Memory(m) => Some((i, m)), External::Memory(m) => Some((i, m)),
_ => None, _ => None,
}).next() })
.next()
.expect("must import memory"); .expect("must import memory");
assert_eq!(entry.field(), "memory"); assert_eq!(entry.field(), "memory");
self.memory_init = Some(mem.limits().clone()); self.memory_init = Some(mem.limits().clone());
@ -1857,14 +1865,19 @@ impl<'a> Context<'a> {
if use_node_require { if use_node_require {
imports.push_str(&format!( imports.push_str(&format!(
"const {} = require(String.raw`{}`).{};\n", "const {} = require(String.raw`{}`).{};\n",
name, module, import.name() name,
module,
import.name()
)); ));
} else if import.name() == 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 { } else {
imports.push_str(&format!( imports.push_str(&format!(
"import {{ {} as {} }} from '{}';\n", "import {{ {} as {} }} from '{}';\n",
import.name(), name, module import.name(),
name,
module
)); ));
} }
name name
@ -1923,11 +1936,11 @@ impl<'a> Context<'a> {
None => { None => {
let name = self.import_identifier(name); let name = self.import_identifier(name);
if import.structural || !name.contains(".") { if import.structural || !name.contains(".") {
return Ok(ImportTarget::Function(name)) return Ok(ImportTarget::Function(name));
} }
self.global(&format!("const {}_target = {};", import.shim, name)); self.global(&format!("const {}_target = {};", import.shim, name));
let target = format!("{}_target", import.shim); 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, decode::MethodKind::Operation(op) => op,
}; };
if import.structural { 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 { return Ok(match &op.kind {
decode::OperationKind::Regular => { decode::OperationKind::Regular => {
@ -1964,43 +1981,51 @@ impl<'a> Context<'a> {
decode::OperationKind::IndexingDeleter => { decode::OperationKind::IndexingDeleter => {
ImportTarget::StructuralIndexingDeleter(class) ImportTarget::StructuralIndexingDeleter(class)
} }
}) });
} }
let target = format!("typeof {0} === 'undefined' ? null : {}{}", let target = format!(
"typeof {0} === 'undefined' ? null : {}{}",
class, class,
if op.is_static { "" } else { ".prototype" }); if op.is_static { "" } else { ".prototype" }
);
let (mut target, name) = match &op.kind { let (mut target, name) = match &op.kind {
decode::OperationKind::Regular => { decode::OperationKind::Regular => (
(format!("{}.{}", target, import.function.name), &import.function.name) format!("{}.{}", target, import.function.name),
} &import.function.name,
),
decode::OperationKind::Getter(g) => { decode::OperationKind::Getter(g) => {
self.expose_get_inherited_descriptor(); self.expose_get_inherited_descriptor();
(format!( (
format!(
"GetOwnOrInheritedPropertyDescriptor({}, '{}').get", "GetOwnOrInheritedPropertyDescriptor({}, '{}').get",
target, g, target, g,
), g) ),
g,
)
} }
decode::OperationKind::Setter(s) => { decode::OperationKind::Setter(s) => {
self.expose_get_inherited_descriptor(); self.expose_get_inherited_descriptor();
(format!( (
format!(
"GetOwnOrInheritedPropertyDescriptor({}, '{}').set", "GetOwnOrInheritedPropertyDescriptor({}, '{}').set",
target, s, target, s,
), s) ),
} s,
decode::OperationKind::IndexingGetter => { )
panic!("indexing getter should be structural")
}
decode::OperationKind::IndexingSetter => {
panic!("indexing setter should be structural")
} }
decode::OperationKind::IndexingGetter => panic!("indexing getter should be structural"),
decode::OperationKind::IndexingSetter => panic!("indexing setter should be structural"),
decode::OperationKind::IndexingDeleter => { decode::OperationKind::IndexingDeleter => {
panic!("indexing deleter should be structural") panic!("indexing deleter should be structural")
} }
}; };
target.push_str(&format!(" || function() {{ target.push_str(&format!(
" || function() {{
throw new Error(`wasm-bindgen: {}.{} does not exist`); throw new Error(`wasm-bindgen: {}.{} does not exist`);
}}", class, name)); }}",
class, name
));
if op.is_static { if op.is_static {
target.insert(0, '('); target.insert(0, '(');
target.push_str(").bind("); target.push_str(").bind(");
@ -2028,10 +2053,10 @@ impl<'a> Context<'a> {
_ => continue, _ => continue,
}; };
if section.name() != "producers" { if section.name() != "producers" {
return return;
} }
drop(update(section)); drop(update(section));
return return;
} }
// `CustomSection::new` added in paritytech/parity-wasm#244 which isn't // `CustomSection::new` added in paritytech/parity-wasm#244 which isn't
@ -2039,7 +2064,15 @@ impl<'a> Context<'a> {
let data = [ let data = [
("producers".len() + 2) as u8, ("producers".len() + 2) as u8,
"producers".len() 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, 0,
]; ];
let mut section = CustomSection::deserialize(&mut &data[..]).unwrap(); let mut section = CustomSection::deserialize(&mut &data[..]).unwrap();
@ -2058,11 +2091,9 @@ impl<'a> Context<'a> {
version: String, version: String,
} }
let wasm_bindgen = || { let wasm_bindgen = || FieldValue {
FieldValue {
name: "wasm-bindgen".to_string(), name: "wasm-bindgen".to_string(),
version: shared::version(), version: shared::version(),
}
}; };
let mut fields = Vec::new(); let mut fields = Vec::new();
@ -2090,7 +2121,7 @@ impl<'a> Context<'a> {
fields.push(Field { name, values }); fields.push(Field { name, values });
} }
if data.len() != 0 { if data.len() != 0 {
return Err(ParityError::InconsistentCode) return Err(ParityError::InconsistentCode);
} }
if !found_processed_by { if !found_processed_by {
@ -2199,7 +2230,8 @@ impl<'a, 'b> SubContext<'a, 'b> {
Some(class_name) Some(class_name)
} else { } else {
None None
}).process(descriptor.unwrap_function())? })
.process(descriptor.unwrap_function())?
.finish("", &format!("wasm.{}", wasm_name)); .finish("", &format!("wasm.{}", wasm_name));
let class = self 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 // 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. // wire up anything here, but we record it to get wired up later.
if import.method.is_none() && shim.is_noop() { 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)); shim.cx.direct_imports.insert(import.shim, (module, name));
return Ok(()) return Ok(());
} }
} }
@ -2439,12 +2476,9 @@ impl<'a, 'b> SubContext<'a, 'b> {
Ok(()) Ok(())
} }
fn register_vendor_prefix( fn register_vendor_prefix(&mut self, info: &decode::ImportType<'b>) {
&mut self,
info: &decode::ImportType<'b>,
) {
if info.vendor_prefixes.len() == 0 { if info.vendor_prefixes.len() == 0 {
return return;
} }
self.vendor_prefixes self.vendor_prefixes
.entry(info.name) .entry(info.name)
@ -2452,9 +2486,11 @@ impl<'a, 'b> SubContext<'a, 'b> {
.extend(info.vendor_prefixes.iter().cloned()); .extend(info.vendor_prefixes.iter().cloned());
} }
fn determine_import(&self, import: &decode::Import<'b>, item: &'b str) fn determine_import(
-> Result<Import<'b>, Error> &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 // First up, imports don't work at all in `--no-modules` mode as we're
// not sure how to import them. // not sure how to import them.
if self.cx.config.no_modules { if self.cx.config.no_modules {
@ -2484,29 +2520,37 @@ impl<'a, 'b> SubContext<'a, 'b> {
); );
} }
if let Some(ns) = &import.js_namespace { if let Some(ns) = &import.js_namespace {
bail!("import of `{}` through js namespace `{}` isn't supported \ bail!(
"import of `{}` through js namespace `{}` isn't supported \
right now when it lists a polyfill", right now when it lists a polyfill",
item, item,
ns); ns
);
} }
return Ok(Import::VendorPrefixed { return Ok(Import::VendorPrefixed {
name: item, name: item,
prefixes: vendor_prefixes.clone(), prefixes: vendor_prefixes.clone(),
}) });
} }
let name = import.js_namespace.as_ref().map(|s| &**s).unwrap_or(item); 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 { Ok(match import.module {
Some(module) => Import::Module { module, name, field }, Some(module) => Import::Module {
module,
name,
field,
},
None => Import::Global { name, field }, None => Import::Global { name, field },
}) })
} }
fn import_name(&mut self, import: &decode::Import<'b>, item: &'b str) fn import_name(&mut self, import: &decode::Import<'b>, item: &'b str) -> Result<String, Error> {
-> Result<String, Error>
{
let import = self.determine_import(import, item)?; let import = self.determine_import(import, item)?;
Ok(self.cx.import_identifier(import)) Ok(self.cx.import_identifier(import))
} }
@ -2529,9 +2573,9 @@ impl<'a> Import<'a> {
fn name(&self) -> &'a str { fn name(&self) -> &'a str {
match self { match self {
Import::Module { name, .. } | Import::Module { name, .. }
Import::Global { name, .. } | | Import::Global { name, .. }
Import::VendorPrefixed { name, .. } => *name, | Import::VendorPrefixed { name, .. } => *name,
} }
} }
} }

View File

@ -1,6 +1,6 @@
use failure::Error; use failure::Error;
use super::{Context, Js2Rust, ImportTarget}; use super::{Context, ImportTarget, Js2Rust};
use descriptor::{Descriptor, Function}; use descriptor::{Descriptor, Function};
/// Helper struct for manufacturing a shim in JS used to translate Rust types to /// 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 = " self.ret_expr = "
const val = JS; const val = JS;
return isLikeNone(val) ? 0 : addHeapObject(val); return isLikeNone(val) ? 0 : addHeapObject(val);
".to_string(); "
.to_string();
} else { } else {
self.ret_expr = "return addHeapObject(JS);".to_string() self.ret_expr = "return addHeapObject(JS);".to_string()
} }
@ -392,7 +393,8 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
self.ret_expr = " self.ret_expr = "
const val = JS; const val = JS;
return isLikeNone(val) ? 0xFFFFFF : val; return isLikeNone(val) ? 0xFFFFFF : val;
".to_string(); "
.to_string();
return Ok(()); return Ok(());
} }
@ -424,7 +426,8 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
self.ret_expr = " self.ret_expr = "
const val = JS; const val = JS;
return isLikeNone(val) ? 0xFFFFFF : val ? 1 : 0; return isLikeNone(val) ? 0xFFFFFF : val ? 1 : 0;
".to_string(); "
.to_string();
return Ok(()); return Ok(());
} }
Descriptor::Char => { Descriptor::Char => {
@ -435,7 +438,8 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
const val = JS; const val = JS;
getUint32Memory()[ret / 4] = !isLikeNone(val); getUint32Memory()[ret / 4] = !isLikeNone(val);
getUint32Memory()[ret / 4 + 1] = isLikeNone(val) ? 0 : val.codePointAt(0); getUint32Memory()[ret / 4 + 1] = isLikeNone(val) ? 0 : val.codePointAt(0);
".to_string(); "
.to_string();
return Ok(()); return Ok(());
} }
_ => bail!( _ => bail!(
@ -561,16 +565,12 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
&format!("{}({}, ...{})", invoc, args.join(", "), last_arg), &format!("{}({}, ...{})", invoc, args.join(", "), last_arg),
) )
} else { } else {
self.ret_expr.replace( self.ret_expr
"JS", .replace("JS", &format!("{}(...{})", invoc, last_arg))
&format!("{}(...{})", invoc, last_arg),
)
} }
} else { } else {
self.ret_expr.replace( self.ret_expr
"JS", .replace("JS", &format!("{}({})", invoc, js_arguments.join(", ")))
&format!("{}({})", invoc, js_arguments.join(", ")),
)
}; };
Ok(ret) Ok(ret)
}; };
@ -584,23 +584,17 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
Ok((self.js_arguments[0].clone(), &self.js_arguments[1..])) Ok((self.js_arguments[0].clone(), &self.js_arguments[1..]))
} }
(None, _) => bail!("setters must have {} arguments", amt + 1), (None, _) => bail!("setters must have {} arguments", amt + 1),
(Some(class), n) if n == amt => { (Some(class), n) if n == amt => Ok((class.clone(), &self.js_arguments[..])),
Ok((class.clone(), &self.js_arguments[..]))
}
(Some(_), _) => bail!("static setters must have {} arguments", amt), (Some(_), _) => bail!("static setters must have {} arguments", amt),
} }
}; };
let mut invoc = match invoc { let mut invoc = match invoc {
ImportTarget::Function(f) => { ImportTarget::Function(f) => handle_variadic(&f, &self.js_arguments)?,
handle_variadic(&f, &self.js_arguments)?
}
ImportTarget::Constructor(c) => { ImportTarget::Constructor(c) => {
handle_variadic(&format!("new {}", c), &self.js_arguments)? handle_variadic(&format!("new {}", c), &self.js_arguments)?
} }
ImportTarget::Method(f) => { ImportTarget::Method(f) => handle_variadic(&format!("{}.call", f), &self.js_arguments)?,
handle_variadic(&format!("{}.call", f), &self.js_arguments)?
}
ImportTarget::StructuralMethod(f) => { ImportTarget::StructuralMethod(f) => {
let (receiver, args) = match self.js_arguments.split_first() { let (receiver, args) = match self.js_arguments.split_first() {
Some(pair) => pair, Some(pair) => pair,

View File

@ -6,8 +6,8 @@ extern crate wasm_bindgen_shared as shared;
extern crate wasm_bindgen_gc as gc; extern crate wasm_bindgen_gc as gc;
#[macro_use] #[macro_use]
extern crate failure; 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_threads_xform as threads_xform;
extern crate wasm_bindgen_wasm_interpreter as wasm_interpreter;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::env; use std::env;
@ -201,7 +201,8 @@ impl Bindgen {
program, program,
cx: &mut cx, cx: &mut cx,
vendor_prefixes: Default::default(), vendor_prefixes: Default::default(),
}.generate()?; }
.generate()?;
} }
cx.finalize(stem)? 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]> { fn get_remaining<'a>(data: &mut &'a [u8]) -> Option<&'a [u8]> {
if data.len() == 0 { if data.len() == 0 {
return None return None;
} }
let len = ((data[0] as usize) << 0) let len = ((data[0] as usize) << 0)
| ((data[1] as usize) << 8) | ((data[1] as usize) << 8)
@ -401,11 +402,11 @@ fn get_remaining<'a>(data: &mut &'a [u8]) -> Option<&'a [u8]> {
Some(a) Some(a)
} }
fn verify_schema_matches<'a>(data: &'a [u8]) fn verify_schema_matches<'a>(data: &'a [u8]) -> Result<Option<&'a str>, Error> {
-> Result<Option<&'a str>, Error>
{
macro_rules! bad { 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) { let data = match str::from_utf8(data) {
Ok(s) => s, Ok(s) => s,
@ -424,7 +425,7 @@ fn verify_schema_matches<'a>(data: &'a [u8])
None => bad!(), None => bad!(),
}; };
if their_schema_version == shared::SCHEMA_VERSION { if their_schema_version == shared::SCHEMA_VERSION {
return Ok(None) return Ok(None);
} }
let needle = "\"version\":\""; let needle = "\"version\":\"";
let rest = match data.find(needle) { let rest = match data.find(needle) {
@ -471,7 +472,7 @@ fn reset_indentation(s: &str) -> String {
// backwards-compatibility with these options. // backwards-compatibility with these options.
fn threads_config() -> Option<threads_xform::Config> { fn threads_config() -> Option<threads_xform::Config> {
if env::var("WASM_BINDGEN_THREADS").is_err() { if env::var("WASM_BINDGEN_THREADS").is_err() {
return None return None;
} }
let mut cfg = threads_xform::Config::new(); let mut cfg = threads_xform::Config::new();
if let Ok(s) = env::var("WASM_BINDGEN_THREADS_MAX_MEMORY") { if let Ok(s) = env::var("WASM_BINDGEN_THREADS_MAX_MEMORY") {

View File

@ -98,7 +98,8 @@ pub fn spawn(
// header?) // header?)
response.headers.retain(|(k, _)| k != "Cache-Control"); response.headers.retain(|(k, _)| k != "Cache-Control");
return response; return response;
}).map_err(|e| format_err!("{}", e))?; })
.map_err(|e| format_err!("{}", e))?;
return Ok(srv); return Ok(srv);
fn try_asset(request: &Request, dir: &Path) -> Response { fn try_asset(request: &Request, dir: &Path) -> Response {

View File

@ -6,8 +6,8 @@ extern crate wasm_bindgen;
extern crate wasm_bindgen_futures; extern crate wasm_bindgen_futures;
extern crate wasm_bindgen_test; extern crate wasm_bindgen_test;
use futures::Future;
use futures::unsync::oneshot; use futures::unsync::oneshot;
use futures::Future;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_futures::{future_to_promise, JsFuture}; use wasm_bindgen_futures::{future_to_promise, JsFuture};
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
@ -18,7 +18,8 @@ fn promise_resolve_is_ok_future() -> impl Future<Item = (), Error = JsValue> {
JsFuture::from(p) JsFuture::from(p)
.map(|x| { .map(|x| {
assert_eq!(x, 42); assert_eq!(x, 42);
}).map_err(|_| unreachable!()) })
.map_err(|_| unreachable!())
} }
#[wasm_bindgen_test(async)] #[wasm_bindgen_test(async)]
@ -37,7 +38,8 @@ fn ok_future_is_resolved_promise() -> impl Future<Item = (), Error = JsValue> {
JsFuture::from(p) JsFuture::from(p)
.map(|x| { .map(|x| {
assert_eq!(x, 42); assert_eq!(x, 42);
}).map_err(|_| unreachable!()) })
.map_err(|_| unreachable!())
} }
#[wasm_bindgen_test(async)] #[wasm_bindgen_test(async)]
@ -51,7 +53,7 @@ fn error_future_is_rejected_promise() -> impl Future<Item = (), Error = JsValue>
} }
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
fn setTimeout(c: &Closure<FnMut()>); fn setTimeout(c: &Closure<FnMut()>);
} }

View File

@ -42,9 +42,7 @@ impl BitSet {
let i = *i as usize; let i = *i as usize;
let idx = i / BITS; let idx = i / BITS;
let bit = 1 << (i % BITS); let bit = 1 << (i % BITS);
self.bits.get(idx) self.bits.get(idx).map(|x| *x & bit != 0).unwrap_or(false)
.map(|x| *x & bit != 0)
.unwrap_or(false)
} }
} }

View File

@ -8,7 +8,7 @@ extern crate parity_wasm;
extern crate log; extern crate log;
extern crate rustc_demangle; extern crate rustc_demangle;
use std::collections::{HashSet, HashMap}; use std::collections::{HashMap, HashSet};
use std::iter; use std::iter;
use std::mem; use std::mem;
@ -66,7 +66,7 @@ fn run(config: &mut Config, module: &mut Module) {
if let Some(section) = module.export_section() { if let Some(section) = module.export_section() {
for (i, entry) in section.entries().iter().enumerate() { for (i, entry) in section.entries().iter().enumerate() {
if cx.blacklist.contains(entry.field()) { if cx.blacklist.contains(entry.field()) {
continue continue;
} }
cx.add_export_entry(entry, i as u32); 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] { let retain = match module.sections_mut()[i] {
Section::Unparsed { .. } => { Section::Unparsed { .. } => {
info!("unparsed section"); info!("unparsed section");
continue continue;
} }
Section::Custom(ref s) => { Section::Custom(ref s) => {
if !cx.config.keep_debug && s.name().starts_with(".debug_") { if !cx.config.keep_debug && s.name().starts_with(".debug_") {
false false
} else { } else {
info!("skipping custom section: {}", s.name()); info!("skipping custom section: {}", s.name());
continue continue;
} }
} }
Section::Reloc(..) => { Section::Reloc(..) => {
info!("skipping reloc section"); info!("skipping reloc section");
continue continue;
} }
Section::Type(ref mut s) => cx.remap_type_section(s), Section::Type(ref mut s) => cx.remap_type_section(s),
Section::Import(ref mut s) => cx.remap_import_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::Memory(ref mut s) => cx.remap_memory_section(s),
Section::Global(ref mut s) => cx.remap_global_section(s), Section::Global(ref mut s) => cx.remap_global_section(s),
Section::Export(ref mut s) => cx.remap_export_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::Element(ref mut s) => cx.remap_element_section(s),
Section::Code(ref mut s) => cx.remap_code_section(s), Section::Code(ref mut s) => cx.remap_code_section(s),
Section::Data(ref mut s) => cx.remap_data_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 { if !retain {
debug!("remove empty section"); debug!("remove empty section");
@ -187,20 +193,19 @@ impl<'a> LiveContext<'a> {
fn add_function(&mut self, idx: u32) { fn add_function(&mut self, idx: u32) {
if !self.analysis.functions.insert(idx) { if !self.analysis.functions.insert(idx) {
return return;
} }
debug!("adding function: {}", idx); debug!("adding function: {}", idx);
if idx < self.analysis.imported_functions { if idx < self.analysis.imported_functions {
let imports = self.import_section.unwrap(); let imports = self.import_section.unwrap();
let (i, import) = imports.entries() let (i, import) = imports
.entries()
.iter() .iter()
.enumerate() .enumerate()
.filter(|&(_, i)| { .filter(|&(_, i)| match *i.external() {
match *i.external() {
External::Function(_) => true, External::Function(_) => true,
_ => false, _ => false,
}
}) })
.skip(idx as usize) .skip(idx as usize)
.next() .next()
@ -217,13 +222,14 @@ impl<'a> LiveContext<'a> {
fn add_table(&mut self, idx: u32) { fn add_table(&mut self, idx: u32) {
if !self.analysis.tables.insert(idx) { if !self.analysis.tables.insert(idx) {
return return;
} }
debug!("adding table: {}", idx); debug!("adding table: {}", idx);
// Add all element segments that initialize this table // Add all element segments that initialize this table
if let Some(elements) = self.element_section { if let Some(elements) = self.element_section {
let iter = elements.entries() let iter = elements
.entries()
.iter() .iter()
.enumerate() .enumerate()
.filter(|(_, d)| !d.passive() && d.index() == idx); .filter(|(_, d)| !d.passive() && d.index() == idx);
@ -234,14 +240,13 @@ impl<'a> LiveContext<'a> {
if idx < self.analysis.imported_tables { if idx < self.analysis.imported_tables {
let imports = self.import_section.unwrap(); let imports = self.import_section.unwrap();
let (i, import) = imports.entries() let (i, import) = imports
.entries()
.iter() .iter()
.enumerate() .enumerate()
.filter(|&(_, i)| { .filter(|&(_, i)| match *i.external() {
match *i.external() {
External::Table(_) => true, External::Table(_) => true,
_ => false, _ => false,
}
}) })
.skip(idx as usize) .skip(idx as usize)
.next() .next()
@ -257,13 +262,14 @@ impl<'a> LiveContext<'a> {
fn add_memory(&mut self, idx: u32) { fn add_memory(&mut self, idx: u32) {
if !self.analysis.memories.insert(idx) { if !self.analysis.memories.insert(idx) {
return return;
} }
debug!("adding memory: {}", idx); debug!("adding memory: {}", idx);
// Add all data segments that initialize this memory // Add all data segments that initialize this memory
if let Some(data) = self.data_section { if let Some(data) = self.data_section {
let iter = data.entries() let iter = data
.entries()
.iter() .iter()
.enumerate() .enumerate()
.filter(|(_, d)| !d.passive() && d.index() == idx); .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 .. // ... and add the import if it's an imported memory ..
if idx < self.analysis.imported_memories { if idx < self.analysis.imported_memories {
let imports = self.import_section.unwrap(); let imports = self.import_section.unwrap();
let (i, import) = imports.entries() let (i, import) = imports
.entries()
.iter() .iter()
.enumerate() .enumerate()
.filter(|&(_, i)| { .filter(|&(_, i)| match *i.external() {
match *i.external() {
External::Memory(_) => true, External::Memory(_) => true,
_ => false, _ => false,
}
}) })
.skip(idx as usize) .skip(idx as usize)
.next() .next()
@ -296,20 +301,19 @@ impl<'a> LiveContext<'a> {
fn add_global(&mut self, idx: u32) { fn add_global(&mut self, idx: u32) {
if !self.analysis.globals.insert(idx) { if !self.analysis.globals.insert(idx) {
return return;
} }
debug!("adding global: {}", idx); debug!("adding global: {}", idx);
if idx < self.analysis.imported_globals { if idx < self.analysis.imported_globals {
let imports = self.import_section.unwrap(); let imports = self.import_section.unwrap();
let (i, import) = imports.entries() let (i, import) = imports
.entries()
.iter() .iter()
.enumerate() .enumerate()
.filter(|&(_, i)| { .filter(|&(_, i)| match *i.external() {
match *i.external() {
External::Global(_) => true, External::Global(_) => true,
_ => false, _ => false,
}
}) })
.skip(idx as usize) .skip(idx as usize)
.next() .next()
@ -337,7 +341,7 @@ impl<'a> LiveContext<'a> {
fn add_type(&mut self, idx: u32) { fn add_type(&mut self, idx: u32) {
if !self.analysis.types.insert(idx) { if !self.analysis.types.insert(idx) {
return return;
} }
let types = self.type_section.expect("no types section"); let types = self.type_section.expect("no types section");
match types.types()[idx as usize] { match types.types()[idx as usize] {
@ -377,23 +381,20 @@ impl<'a> LiveContext<'a> {
fn add_opcode(&mut self, code: &Instruction) { fn add_opcode(&mut self, code: &Instruction) {
match *code { match *code {
Instruction::Block(ref b) | Instruction::Block(ref b) | Instruction::Loop(ref b) | Instruction::If(ref b) => {
Instruction::Loop(ref b) | self.add_block_type(b)
Instruction::If(ref b) => self.add_block_type(b), }
Instruction::Call(f) => self.add_function(f), Instruction::Call(f) => self.add_function(f),
Instruction::CallIndirect(t, _) => { Instruction::CallIndirect(t, _) => {
self.add_type(t); self.add_type(t);
self.add_table(0); self.add_table(0);
} }
Instruction::GetGlobal(i) | Instruction::GetGlobal(i) | Instruction::SetGlobal(i) => self.add_global(i),
Instruction::SetGlobal(i) => self.add_global(i), Instruction::MemoryInit(i) | Instruction::MemoryDrop(i) => {
Instruction::MemoryInit(i) |
Instruction::MemoryDrop(i) => {
self.add_memory(0); self.add_memory(0);
self.add_data_segment(i); self.add_data_segment(i);
} }
Instruction::TableInit(i) | Instruction::TableInit(i) | Instruction::TableDrop(i) => {
Instruction::TableDrop(i) => {
self.add_table(0); self.add_table(0);
self.add_element_segment(i); self.add_element_segment(i);
} }
@ -410,7 +411,7 @@ impl<'a> LiveContext<'a> {
fn add_export_entry(&mut self, entry: &ExportEntry, idx: u32) { fn add_export_entry(&mut self, entry: &ExportEntry, idx: u32) {
if !self.analysis.exports.insert(idx) { if !self.analysis.exports.insert(idx) {
return return;
} }
match *entry.internal() { match *entry.internal() {
Internal::Function(i) => self.add_function(i), 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) { fn add_import_entry(&mut self, entry: &ImportEntry, idx: u32) {
if !self.analysis.imports.insert(idx) { if !self.analysis.imports.insert(idx) {
return return;
} }
debug!("adding import: {}", idx); debug!("adding import: {}", idx);
match *entry.external() { match *entry.external() {
@ -435,7 +436,7 @@ impl<'a> LiveContext<'a> {
fn add_data_segment(&mut self, idx: u32) { fn add_data_segment(&mut self, idx: u32) {
if !self.analysis.data_segments.insert(idx) { if !self.analysis.data_segments.insert(idx) {
return return;
} }
let data = &self.data_section.unwrap().entries()[idx as usize]; let data = &self.data_section.unwrap().entries()[idx as usize];
if !data.passive() { if !data.passive() {
@ -448,7 +449,7 @@ impl<'a> LiveContext<'a> {
fn add_element_segment(&mut self, idx: u32) { fn add_element_segment(&mut self, idx: u32) {
if !self.analysis.elements.insert(idx) { if !self.analysis.elements.insert(idx) {
return return;
} }
let seg = &self.element_section.unwrap().entries()[idx as usize]; let seg = &self.element_section.unwrap().entries()[idx as usize];
for member in seg.members() { for member in seg.members() {
@ -495,7 +496,7 @@ impl<'a> RemapContext<'a> {
if let Some(prev) = map.get(&ty) { if let Some(prev) = map.get(&ty) {
types.push(*prev); types.push(*prev);
analysis.types.remove(&(i as u32)); analysis.types.remove(&(i as u32));
continue continue;
} }
map.insert(ty, ntypes); map.insert(ty, ntypes);
types.push(ntypes); types.push(ntypes);
@ -525,7 +526,10 @@ impl<'a> RemapContext<'a> {
} }
if let Some(s) = m.function_section() { if let Some(s) = m.function_section() {
for i in 0..(s.entries().len() as u32) { 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); functions.push(nfunctions);
nfunctions += 1; nfunctions += 1;
} else { } else {
@ -558,7 +562,10 @@ impl<'a> RemapContext<'a> {
} }
if let Some(s) = m.memory_section() { if let Some(s) = m.memory_section() {
for i in 0..(s.entries().len() as u32) { 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); memories.push(nmemories);
nmemories += 1; nmemories += 1;
} else { } else {
@ -804,17 +811,20 @@ impl<'a> RemapContext<'a> {
fn remap_instruction(&self, i: &mut Instruction) { fn remap_instruction(&self, i: &mut Instruction) {
match *i { match *i {
Instruction::Block(ref mut b) | Instruction::Block(ref mut b)
Instruction::Loop(ref mut b) | | Instruction::Loop(ref mut b)
Instruction::If(ref mut b) => self.remap_block_type(b), | Instruction::If(ref mut b) => self.remap_block_type(b),
Instruction::Call(ref mut f) => self.remap_function_idx(f), Instruction::Call(ref mut f) => self.remap_function_idx(f),
Instruction::CallIndirect(ref mut t, _) => self.remap_type_idx(t), Instruction::CallIndirect(ref mut t, _) => self.remap_type_idx(t),
Instruction::GetGlobal(ref mut i) | Instruction::GetGlobal(ref mut i) | Instruction::SetGlobal(ref mut i) => {
Instruction::SetGlobal(ref mut i) => self.remap_global_idx(i), self.remap_global_idx(i)
Instruction::TableInit(ref mut i) | }
Instruction::TableDrop(ref mut i) => self.remap_element_idx(i), Instruction::TableInit(ref mut i) | Instruction::TableDrop(ref mut i) => {
Instruction::MemoryInit(ref mut i) | self.remap_element_idx(i)
Instruction::MemoryDrop(ref mut i) => self.remap_data_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; let mut next = ty.params().len() as u32;
for i in ty.params().len()..used.len() { for i in ty.params().len()..used.len() {
if !used[i] { if !used[i] {
continue continue;
} }
// We're using this local, so map it to the next index (the lowest). // 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 // Find all other locals with the same type and lump then into our
@ -999,13 +1009,12 @@ fn gc_body(
next += 1; 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() { for instr in body.code_mut().elements_mut() {
let get = |i: &u32| { let get = |i: &u32| map[*i as usize].unwrap();
map[*i as usize].unwrap()
};
match instr { match instr {
Instruction::GetLocal(i) => *i = get(i), Instruction::GetLocal(i) => *i = get(i),
Instruction::SetLocal(i) => *i = get(i), Instruction::SetLocal(i) => *i = get(i),

View File

@ -10,8 +10,8 @@ use std::io;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::{Command, Stdio}; use std::process::{Command, Stdio};
use rayon::prelude::*;
use parity_wasm::elements::Module; use parity_wasm::elements::Module;
use rayon::prelude::*;
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
struct Test { struct Test {
@ -31,13 +31,11 @@ fn find_tests(tests: &mut Vec<Test>, path: &Path) {
let path = entry.path(); let path = entry.path();
if entry.file_type().unwrap().is_dir() { if entry.file_type().unwrap().is_dir() {
find_tests(tests, &path); find_tests(tests, &path);
continue continue;
} }
if path.extension().and_then(|s| s.to_str()) == Some("wat") { if path.extension().and_then(|s| s.to_str()) == Some("wat") {
tests.push(Test { tests.push(Test { input: path });
input: path,
});
} }
} }
} }
@ -45,10 +43,9 @@ fn find_tests(tests: &mut Vec<Test>, path: &Path) {
fn run_tests(tests: &[Test]) { fn run_tests(tests: &[Test]) {
println!(""); println!("");
let results = tests.par_iter() let results = tests
.map(|test| { .par_iter()
run_test(test).map_err(|e| (test, e.to_string())) .map(|test| run_test(test).map_err(|e| (test, e.to_string())))
})
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let mut bad = false; let mut bad = false;
@ -81,7 +78,7 @@ fn run_test(test: &Test) -> Result<(), Box<Error>> {
.arg(f.path()) .arg(f.path())
.status()?; .status()?;
if !status.success() { 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())?; let wasm = fs::read(f.path())?;
@ -100,7 +97,7 @@ fn run_test(test: &Test) -> Result<(), Box<Error>> {
.stderr(Stdio::inherit()) .stderr(Stdio::inherit())
.output()?; .output()?;
if !status.status.success() { 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 = String::from_utf8(status.stdout)?;
let actual = actual.trim(); let actual = actual.trim();
@ -110,8 +107,7 @@ fn run_test(test: &Test) -> Result<(), Box<Error>> {
} else { } else {
if actual != expected { if actual != expected {
println!("{:?} {:?}", actual, expected); println!("{:?} {:?}", actual, expected);
return Err(io::Error::new(io::ErrorKind::Other, return Err(io::Error::new(io::ErrorKind::Other, "test failed").into());
"test failed").into())
} }
} }
@ -119,7 +115,8 @@ fn run_test(test: &Test) -> Result<(), Box<Error>> {
} }
fn extract_expected(input: &str) -> String { fn extract_expected(input: &str) -> String {
input.lines() input
.lines()
.filter(|l| l.starts_with(";; ")) .filter(|l| l.starts_with(";; "))
.skip_while(|l| !l.contains("STDOUT")) .skip_while(|l| !l.contains("STDOUT"))
.skip(1) .skip(1)
@ -130,7 +127,8 @@ fn extract_expected(input: &str) -> String {
} }
fn generate_blesssed(input: &str, actual: &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(";;")) .filter(|l| !l.starts_with(";;"))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join("\n") .join("\n")
@ -144,5 +142,5 @@ fn generate_blesssed(input: &str, actual: &str) -> String {
input.push_str("\n"); input.push_str("\n");
} }
input.push_str(";; STDOUT\n"); input.push_str(";; STDOUT\n");
return input return input;
} }

View File

@ -52,8 +52,14 @@ fn test() {
v.set_float64(0, 123456789.123456); v.set_float64(0, 123456789.123456);
assert_eq!(v.get_float64(0), 123456789.123456); assert_eq!(v.get_float64(0), 123456789.123456);
v.set_float64_endian(0, f64::from_bits(0x1122334411223344), true); v.set_float64_endian(0, f64::from_bits(0x1122334411223344), true);
assert_eq!(v.get_float64_endian(0, true), f64::from_bits(0x1122334411223344)); assert_eq!(
assert_eq!(v.get_float64_endian(0, false), f64::from_bits(0x4433221144332211)); 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); v.set_int8(0, 42);

View File

@ -30,19 +30,13 @@ fn try_iter_handles_iteration_protocol() {
assert!(try_iter(&get_not_iterable()).unwrap().is_none()); assert!(try_iter(&get_not_iterable()).unwrap().is_none());
assert!(try_iter(&get_symbol_iterator_throws()).is_err()); assert!(try_iter(&get_symbol_iterator_throws()).is_err());
assert!( assert!(try_iter(&get_symbol_iterator_not_function())
try_iter(&get_symbol_iterator_not_function())
.unwrap() .unwrap()
.is_none() .is_none());
); assert!(try_iter(&get_symbol_iterator_returns_not_object())
assert!(
try_iter(&get_symbol_iterator_returns_not_object())
.unwrap() .unwrap()
.is_none() .is_none());
); assert!(try_iter(&get_symbol_iterator_returns_object_without_next())
assert!(
try_iter(&get_symbol_iterator_returns_object_without_next())
.unwrap() .unwrap()
.is_none() .is_none());
);
} }

View File

@ -62,7 +62,8 @@ fn compile_valid() -> impl Future<Item = (), Error = JsValue> {
JsFuture::from(p) JsFuture::from(p)
.map(|module| { .map(|module| {
assert!(module.is_instance_of::<WebAssembly::Module>()); assert!(module.is_instance_of::<WebAssembly::Module>());
}).map_err(|_| unreachable!()) })
.map_err(|_| unreachable!())
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
@ -197,11 +198,9 @@ fn instantiate_streaming() -> impl Future<Item = (), Error = JsValue> {
let imports = get_imports(); let imports = get_imports();
let p = WebAssembly::instantiate_streaming(&response, &imports); let p = WebAssembly::instantiate_streaming(&response, &imports);
JsFuture::from(p).map(|obj| { JsFuture::from(p).map(|obj| {
assert!( assert!(Reflect::get(obj.as_ref(), &"instance".into())
Reflect::get(obj.as_ref(), &"instance".into())
.unwrap() .unwrap()
.is_instance_of::<WebAssembly::Instance>() .is_instance_of::<WebAssembly::Instance>());
);
}) })
} }

View File

@ -50,7 +50,8 @@ impl BindgenAttrs {
.filter_map(|a| match a { .filter_map(|a| match a {
BindgenAttr::Module(s) => Some(&s[..]), BindgenAttr::Module(s) => Some(&s[..]),
_ => None, _ => None,
}).next() })
.next()
} }
/// Whether the catch attribute is present /// Whether the catch attribute is present
@ -76,7 +77,8 @@ impl BindgenAttrs {
.filter_map(|a| match a { .filter_map(|a| match a {
BindgenAttr::StaticMethodOf(c) => Some(c), BindgenAttr::StaticMethodOf(c) => Some(c),
_ => None, _ => None,
}).next() })
.next()
} }
/// Whether the method attributes is present /// Whether the method attributes is present
@ -94,7 +96,8 @@ impl BindgenAttrs {
.filter_map(|a| match a { .filter_map(|a| match a {
BindgenAttr::JsNamespace(s) => Some(s), BindgenAttr::JsNamespace(s) => Some(s),
_ => None, _ => None,
}).next() })
.next()
} }
/// Get the first getter attribute /// Get the first getter attribute
@ -104,7 +107,8 @@ impl BindgenAttrs {
.filter_map(|a| match a { .filter_map(|a| match a {
BindgenAttr::Getter(g) => Some(g.clone()), BindgenAttr::Getter(g) => Some(g.clone()),
_ => None, _ => None,
}).next() })
.next()
} }
/// Get the first setter attribute /// Get the first setter attribute
@ -114,7 +118,8 @@ impl BindgenAttrs {
.filter_map(|a| match a { .filter_map(|a| match a {
BindgenAttr::Setter(s) => Some(s.clone()), BindgenAttr::Setter(s) => Some(s.clone()),
_ => None, _ => None,
}).next() })
.next()
} }
/// Whether the indexing getter attributes is present /// Whether the indexing getter attributes is present
@ -151,10 +156,13 @@ impl BindgenAttrs {
/// Whether the `final` attribute is present /// Whether the `final` attribute is present
fn final_(&self) -> Option<&Ident> { fn final_(&self) -> Option<&Ident> {
self.attrs.iter().filter_map(|a| match a { self.attrs
.iter()
.filter_map(|a| match a {
BindgenAttr::Final(i) => Some(i), BindgenAttr::Final(i) => Some(i),
_ => None, _ => None,
}).next() })
.next()
} }
/// Whether the readonly attributes is present /// Whether the readonly attributes is present
@ -172,7 +180,8 @@ impl BindgenAttrs {
.filter_map(|a| match a { .filter_map(|a| match a {
BindgenAttr::JsName(s, span) => Some((&s[..], *span)), BindgenAttr::JsName(s, span) => Some((&s[..], *span)),
_ => None, _ => None,
}).next() })
.next()
} }
/// Get the first js_class attribute /// Get the first js_class attribute
@ -182,7 +191,8 @@ impl BindgenAttrs {
.filter_map(|a| match a { .filter_map(|a| match a {
BindgenAttr::JsClass(s) => Some(&s[..]), BindgenAttr::JsClass(s) => Some(&s[..]),
_ => None, _ => None,
}).next() })
.next()
} }
/// Return the list of classes that a type extends /// Return the list of classes that a type extends
@ -281,7 +291,7 @@ impl Parse for BindgenAttr {
return Ok(BindgenAttr::Structural); return Ok(BindgenAttr::Structural);
} }
if attr == "final" { if attr == "final" {
return Ok(BindgenAttr::Final(attr)) return Ok(BindgenAttr::Final(attr));
} }
if attr == "readonly" { if attr == "readonly" {
return Ok(BindgenAttr::Readonly); return Ok(BindgenAttr::Readonly);
@ -386,7 +396,8 @@ impl<'a> ConvertToAst<BindgenAttrs> for &'a mut syn::ItemStruct {
); );
} }
let mut fields = Vec::new(); let mut fields = Vec::new();
let js_name = opts.js_name() let js_name = opts
.js_name()
.map(|s| s.0.to_string()) .map(|s| s.0.to_string())
.unwrap_or(self.ident.to_string()); .unwrap_or(self.ident.to_string());
if let syn::Fields::Named(names) = &mut self.fields { 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(), self.vis.clone(),
false, false,
None, None,
)?.0; )?
.0;
let catch = opts.catch(); let catch = opts.catch();
let variadic = opts.variadic(); let variadic = opts.variadic();
let js_ret = if catch { let js_ret = if catch {
@ -664,7 +676,8 @@ impl ConvertToAst<BindgenAttrs> for syn::ItemFn {
self.vis, self.vis,
false, false,
None, None,
)?.0) )?
.0)
} }
} }
@ -735,7 +748,8 @@ fn function_from_decl(
None None
} }
_ => panic!("arguments cannot be `self` or ignored"), _ => panic!("arguments cannot be `self` or ignored"),
}).collect::<Vec<_>>(); })
.collect::<Vec<_>>();
let ret = match output { let ret = match output {
syn::ReturnType::Default => None, syn::ReturnType::Default => None,
@ -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) { 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) fn macro_parse(
-> Result<(), Diagnostic> self,
{ program: &mut ast::Program,
impl_opts: &'a BindgenAttrs,
) -> Result<(), Diagnostic> {
let (class, item) = self; let (class, item) = self;
let method = match item { let method = match item {
syn::ImplItem::Method(ref mut m) => m, 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, true,
Some(class), Some(class),
)?; )?;
let js_class = impl_opts.js_class() let js_class = impl_opts
.js_class()
.map(|s| s.to_string()) .map(|s| s.to_string())
.unwrap_or(class.to_string()); .unwrap_or(class.to_string());
@ -1001,7 +1018,8 @@ impl MacroParse<()> for syn::ItemEnum {
name: v.ident.clone(), name: v.ident.clone(),
value, value,
}) })
}).collect::<Result<_, Diagnostic>>()?; })
.collect::<Result<_, Diagnostic>>()?;
let comments = extract_doc_comments(&self.attrs); let comments = extract_doc_comments(&self.attrs);
program.enums.push(ast::Enum { program.enums.push(ast::Enum {
name: self.ident, name: self.ident,
@ -1025,10 +1043,10 @@ impl MacroParse<BindgenAttrs> for syn::ItemConst {
.. ..
}) => { }) => {
program.typescript_custom_sections.push(litstr.value()); program.typescript_custom_sections.push(litstr.value());
}, }
_ => { _ => {
bail_span!(self, "Expected a string literal to be used with #[wasm_bindgen(typescript_custom_section)]."); bail_span!(self, "Expected a string literal to be used with #[wasm_bindgen(typescript_custom_section)].");
}, }
} }
Ok(()) Ok(())

View File

@ -6,8 +6,9 @@ pub const SCHEMA_VERSION: &str = env!("CARGO_PKG_VERSION");
#[macro_export] #[macro_export]
macro_rules! shared_api { macro_rules! shared_api {
($mac:ident) => ($mac! { ($mac:ident) => {
struct Program<'a> { $mac! {
struct Program<'a> {
exports: Vec<Export<'a>>, exports: Vec<Export<'a>>,
enums: Vec<Enum<'a>>, enums: Vec<Enum<'a>>,
imports: Vec<Import<'a>>, imports: Vec<Import<'a>>,
@ -15,104 +16,104 @@ struct Program<'a> {
typescript_custom_sections: Vec<&'a str>, typescript_custom_sections: Vec<&'a str>,
// version: &'a str, // version: &'a str,
// schema_version: &'a str, // schema_version: &'a str,
} }
struct Import<'a> { struct Import<'a> {
module: Option<&'a str>, module: Option<&'a str>,
js_namespace: Option<&'a str>, js_namespace: Option<&'a str>,
kind: ImportKind<'a>, kind: ImportKind<'a>,
} }
enum ImportKind<'a> { enum ImportKind<'a> {
Function(ImportFunction<'a>), Function(ImportFunction<'a>),
Static(ImportStatic<'a>), Static(ImportStatic<'a>),
Type(ImportType<'a>), Type(ImportType<'a>),
Enum(ImportEnum), Enum(ImportEnum),
} }
struct ImportFunction<'a> { struct ImportFunction<'a> {
shim: &'a str, shim: &'a str,
catch: bool, catch: bool,
variadic: bool, variadic: bool,
method: Option<MethodData<'a>>, method: Option<MethodData<'a>>,
structural: bool, structural: bool,
function: Function<'a>, function: Function<'a>,
} }
struct MethodData<'a> { struct MethodData<'a> {
class: &'a str, class: &'a str,
kind: MethodKind<'a>, kind: MethodKind<'a>,
} }
enum MethodKind<'a> { enum MethodKind<'a> {
Constructor, Constructor,
Operation(Operation<'a>), Operation(Operation<'a>),
} }
struct Operation<'a> { struct Operation<'a> {
is_static: bool, is_static: bool,
kind: OperationKind<'a>, kind: OperationKind<'a>,
} }
enum OperationKind<'a> { enum OperationKind<'a> {
Regular, Regular,
Getter(&'a str), Getter(&'a str),
Setter(&'a str), Setter(&'a str),
IndexingGetter, IndexingGetter,
IndexingSetter, IndexingSetter,
IndexingDeleter, IndexingDeleter,
} }
struct ImportStatic<'a> { struct ImportStatic<'a> {
name: &'a str, name: &'a str,
shim: &'a str, shim: &'a str,
} }
struct ImportType<'a> { struct ImportType<'a> {
name: &'a str, name: &'a str,
instanceof_shim: &'a str, instanceof_shim: &'a str,
vendor_prefixes: Vec<&'a str>, vendor_prefixes: Vec<&'a str>,
} }
struct ImportEnum {} struct ImportEnum {}
struct Export<'a> { struct Export<'a> {
class: Option<&'a str>, class: Option<&'a str>,
method: bool, method: bool,
consumed: bool, consumed: bool,
is_constructor: bool, is_constructor: bool,
function: Function<'a>, function: Function<'a>,
comments: Vec<&'a str>, comments: Vec<&'a str>,
} }
struct Enum<'a> { struct Enum<'a> {
name: &'a str, name: &'a str,
variants: Vec<EnumVariant<'a>>, variants: Vec<EnumVariant<'a>>,
comments: Vec<&'a str>, comments: Vec<&'a str>,
} }
struct EnumVariant<'a> { struct EnumVariant<'a> {
name: &'a str, name: &'a str,
value: u32, value: u32,
} }
struct Function<'a> { struct Function<'a> {
name: &'a str, name: &'a str,
} }
struct Struct<'a> { struct Struct<'a> {
name: &'a str, name: &'a str,
fields: Vec<StructField<'a>>, fields: Vec<StructField<'a>>,
comments: Vec<&'a str>, comments: Vec<&'a str>,
} }
struct StructField<'a> { struct StructField<'a> {
name: &'a str, name: &'a str,
readonly: bool, readonly: bool,
comments: Vec<&'a str>, comments: Vec<&'a str>,
} }
}) // end of mac case }
}; // end of mac case
} // end of mac definition } // end of mac definition
pub fn new_function(struct_name: &str) -> String { pub fn new_function(struct_name: &str) -> String {

View File

@ -74,7 +74,8 @@ pub fn wasm_bindgen_test(
#test_body #test_body
} }
} }
}).into_iter(), })
.into_iter(),
); );
tokens.extend(leading_tokens); tokens.extend(leading_tokens);

View File

@ -103,9 +103,7 @@ struct PassiveSegment {
len: u32, len: u32,
} }
fn switch_data_segments_to_passive(module: &mut Module) fn switch_data_segments_to_passive(module: &mut Module) -> Result<Vec<PassiveSegment>, Error> {
-> Result<Vec<PassiveSegment>, Error>
{
// If there's no data, nothing to make passive! // If there's no data, nothing to make passive!
let section = match module.data_section_mut() { let section = match module.data_section_mut() {
Some(section) => section, Some(section) => section,
@ -147,9 +145,7 @@ fn get_offset(offset: &mut InitExpr) -> Result<&mut i32, Error> {
} }
} }
fn import_memory_zero(module: &mut Module) fn import_memory_zero(module: &mut Module) -> Result<(), Error> {
-> Result<(), Error>
{
// If memory is exported, let's switch it to imported. If memory isn't // 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 // exported then there's nothing to do as we'll deal with importing it
// later. // 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 // Remove all memory sections as well as exported memory, we're switching to
// an import // an import
module.sections_mut().retain(|s| { module.sections_mut().retain(|s| match s {
match s {
Section::Memory(_) => false, Section::Memory(_) => false,
_ => true, _ => true,
}
}); });
if let Some(s) = module.export_section_mut() { if let Some(s) = module.export_section_mut() {
s.entries_mut().retain(|s| { s.entries_mut().retain(|s| match s.internal() {
match s.internal() {
Internal::Memory(_) => false, Internal::Memory(_) => false,
_ => true, _ => true,
}
}); });
} }
@ -215,14 +207,14 @@ fn maybe_add_import_section(module: &mut Module) -> usize {
_ => {} _ => {}
} }
pos = Some(i); pos = Some(i);
break break;
} }
let empty = ImportSection::with_entries(Vec::new()); let empty = ImportSection::with_entries(Vec::new());
let section = Section::Import(empty); let section = Section::Import(empty);
let len = module.sections().len(); let len = module.sections().len();
let pos = pos.unwrap_or_else(|| len - 1); let pos = pos.unwrap_or_else(|| len - 1);
module.sections_mut().insert(pos, section); module.sections_mut().insert(pos, section);
return pos return pos;
} }
fn share_imported_memory_zero(module: &mut Module, memory_max: u32) -> Result<(), Error> { 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)), Some(mem.limits().maximum().unwrap_or(memory_max / PAGE_SIZE)),
true, true,
); );
return Ok(()) return Ok(());
} }
panic!("failed to find an imported memory") 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 // https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#high-level-structure
for i in 0..module.sections().len() { for i in 0..module.sections().len() {
match &mut module.sections_mut()[i] { match &mut module.sections_mut()[i] {
Section::Type(_) | Section::Type(_)
Section::Import(_) | | Section::Import(_)
Section::Function(_) | | Section::Function(_)
Section::Table(_) | | Section::Table(_)
Section::Memory(_) => continue, | Section::Memory(_) => continue,
Section::Global(_) => return i, Section::Global(_) => return i,
_ => {} _ => {}
} }
pos = Some(i); pos = Some(i);
break break;
} }
let empty = GlobalSection::with_entries(Vec::new()); let empty = GlobalSection::with_entries(Vec::new());
let section = Section::Global(empty); let section = Section::Global(empty);
let len = module.sections().len(); let len = module.sections().len();
let pos = pos.unwrap_or_else(|| len - 1); let pos = pos.unwrap_or_else(|| len - 1);
module.sections_mut().insert(pos, section); module.sections_mut().insert(pos, section);
return pos return pos;
} }
fn inject_thread_id_counter(module: &mut Module) -> Result<u32, Error> { 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"), None => bail!("failed to find `__heap_base` for injecting thread id"),
}; };
exports.entries() exports
.entries()
.iter() .iter()
.filter(|e| e.field() == "__heap_base") .filter(|e| e.field() == "__heap_base")
.filter_map(|e| { .filter_map(|e| match e.internal() {
match e.internal() {
Internal::Global(idx) => Some(*idx), Internal::Global(idx) => Some(*idx),
_ => None, _ => None,
}
}) })
.next() .next()
}; };
@ -414,7 +405,8 @@ fn find_stack_pointer(module: &mut Module) -> Result<Option<u32>, Error> {
Some(s) => s, Some(s) => s,
None => bail!("failed to find the stack pointer"), None => bail!("failed to find the stack pointer"),
}; };
let candidates = globals.entries() let candidates = globals
.entries()
.iter() .iter()
.enumerate() .enumerate()
.filter(|(_, g)| g.global_type().content_type() == ValueType::I32) .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 // If there are no mutable i32 globals, assume this module doesn't even need
// a stack pointer! // a stack pointer!
if candidates.len() == 0 { if candidates.len() == 0 {
return Ok(None) return Ok(None);
} }
// Currently LLVM/LLD always use global 0 as the stack pointer, let's just // Currently LLVM/LLD always use global 0 as the stack pointer, let's just
// blindly assume that. // blindly assume that.
if candidates[0].0 == 0 { 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 \ bail!(
this wasm file not produced by LLD?") "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( 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 // Execute an atomic add to learn what our thread ID is
instrs.push(Instruction::I32Const(addr as i32)); instrs.push(Instruction::I32Const(addr as i32));
instrs.push(Instruction::I32Const(1)); 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)); instrs.push(Instruction::I32AtomicRmwAdd(mem));
// Store this thread ID into our thread ID global // Store this thread ID into our thread ID global
@ -531,13 +528,14 @@ fn start_with_init_memory(
}; };
// ... and also be sure to add its signature to the function section ... // ... and also be sure to add its signature to the function section ...
let type_idx = { let type_idx = {
let section = module.type_section_mut().expect("module has no type section"); let section = module
let pos = section.types() .type_section_mut()
.expect("module has no type section");
let pos = section
.types()
.iter() .iter()
.map(|t| { .map(|t| match t {
match t {
Type::Function(t) => t, Type::Function(t) => t,
}
}) })
.position(|t| t.params().is_empty() && t.return_type().is_none()); .position(|t| t.params().is_empty() && t.return_type().is_none());
match pos { 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") .expect("module has no function section")
.entries_mut() .entries_mut()
.push(Func::new(type_idx)); .push(Func::new(type_idx));
@ -566,21 +565,21 @@ fn update_start_section(module: &mut Module, start: u32) {
let mut pos = None; let mut pos = None;
for i in 0..module.sections().len() { for i in 0..module.sections().len() {
match &mut module.sections_mut()[i] { match &mut module.sections_mut()[i] {
Section::Type(_) | Section::Type(_)
Section::Import(_) | | Section::Import(_)
Section::Function(_) | | Section::Function(_)
Section::Table(_) | | Section::Table(_)
Section::Memory(_) | | Section::Memory(_)
Section::Global(_) | | Section::Global(_)
Section::Export(_) => continue, | Section::Export(_) => continue,
Section::Start(start_idx) => { Section::Start(start_idx) => {
*start_idx = start; *start_idx = start;
return return;
} }
_ => {} _ => {}
} }
pos = Some(i); pos = Some(i);
break break;
} }
let section = Section::Start(start); let section = Section::Start(start);
let len = module.sections().len(); let len = module.sections().len();
@ -588,28 +587,22 @@ fn update_start_section(module: &mut Module, start: u32) {
module.sections_mut().insert(pos, section); module.sections_mut().insert(pos, section);
} }
fn implement_thread_intrinsics( fn implement_thread_intrinsics(module: &mut Module, globals: &Globals) -> Result<(), Error> {
module: &mut Module,
globals: &Globals,
) -> Result<(), Error> {
let mut map = HashMap::new(); let mut map = HashMap::new();
{ {
let imports = match module.import_section() { let imports = match module.import_section() {
Some(i) => i, Some(i) => i,
None => return Ok(()), None => return Ok(()),
}; };
let entries = imports.entries() let entries = imports
.entries()
.iter() .iter()
.filter(|i| { .filter(|i| match i.external() {
match i.external() {
External::Function(_) => true, External::Function(_) => true,
_ => false, _ => false,
}
}) })
.enumerate() .enumerate()
.filter(|(_, entry)| { .filter(|(_, entry)| entry.module() == "__wbindgen_thread_xform__");
entry.module() == "__wbindgen_thread_xform__"
});
for (idx, entry) in entries { for (idx, entry) in entries {
let type_idx = match entry.external() { let type_idx = match entry.external() {
External::Function(i) => *i, External::Function(i) => *i,
@ -622,17 +615,13 @@ fn implement_thread_intrinsics(
// Validate the type for this intrinsic // Validate the type for this intrinsic
match entry.field() { match entry.field() {
"__wbindgen_thread_id" => { "__wbindgen_thread_id" => {
if !fty.params().is_empty() || if !fty.params().is_empty() || fty.return_type() != Some(ValueType::I32) {
fty.return_type() != Some(ValueType::I32)
{
bail!("__wbindgen_thread_id intrinsic has the wrong signature"); bail!("__wbindgen_thread_id intrinsic has the wrong signature");
} }
map.insert(idx as u32, Instruction::GetGlobal(globals.thread_id)); map.insert(idx as u32, Instruction::GetGlobal(globals.thread_id));
} }
"__wbindgen_tcb_get" => { "__wbindgen_tcb_get" => {
if !fty.params().is_empty() || if !fty.params().is_empty() || fty.return_type() != Some(ValueType::I32) {
fty.return_type() != Some(ValueType::I32)
{
bail!("__wbindgen_tcb_get intrinsic has the wrong signature"); bail!("__wbindgen_tcb_get intrinsic has the wrong signature");
} }
map.insert(idx as u32, Instruction::GetGlobal(globals.thread_tcb)); 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 body in module.code_section_mut().unwrap().bodies_mut() {
for instr in body.code_mut().elements_mut() { for instr in body.code_mut().elements_mut() {
let other = match instr { let other = match instr {
Instruction::Call(idx) => { Instruction::Call(idx) => match map.get(idx) {
match map.get(idx) {
Some(other) => other, Some(other) => other,
None => continue, None => continue,
} },
}
_ => continue, _ => continue,
}; };
*instr = other.clone(); *instr = other.clone();

View File

@ -93,7 +93,8 @@ fn build_function(
segments, segments,
}, },
}) })
}).collect::<Vec<_>>(); })
.collect::<Vec<_>>();
let mut ret_segments = syn::punctuated::Punctuated::new(); let mut ret_segments = syn::punctuated::Punctuated::new();
ret_segments.push(syn::PathSegment { ret_segments.push(syn::PathSegment {

View File

@ -262,10 +262,12 @@ impl Interpreter {
Instruction::I32Const(x) => Some((i, x as u32, entry)), Instruction::I32Const(x) => Some((i, x as u32, entry)),
_ => None, _ => None,
} }
}).find(|(_i, offset, entry)| { })
.find(|(_i, offset, entry)| {
*offset <= descriptor_table_idx *offset <= descriptor_table_idx
&& descriptor_table_idx < (*offset + entry.members().len() as u32) && 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 idx = (descriptor_table_idx - offset) as usize;
let descriptor_idx = entry.members()[idx]; let descriptor_idx = entry.members()[idx];
@ -300,7 +302,8 @@ impl Interpreter {
.map(|i| { .map(|i| {
assert_eq!(i.value_type(), ValueType::I32); assert_eq!(i.value_type(), ValueType::I32);
i.count() i.count()
}).unwrap_or(0); })
.unwrap_or(0);
let code_sig = sections.functions.entries()[code_idx].type_ref(); let code_sig = sections.functions.entries()[code_idx].type_ref();
let function_ty = match &sections.types.types()[code_sig as usize] { let function_ty = match &sections.types.types()[code_sig as usize] {

View File

@ -59,7 +59,8 @@ fn try_main() -> Result<(), failure::Error> {
.map(|mut p| { .map(|mut p| {
p.drain(0.."CARGO_FEATURE_".len()); p.drain(0.."CARGO_FEATURE_".len());
p p
}).collect::<HashSet<_>>(); })
.collect::<HashSet<_>>();
let mut allowed = Vec::new(); let mut allowed = Vec::new();
for feature in features.filter(|f| !f.starts_with("#") && !f.starts_with("[")) { for feature in features.filter(|f| !f.starts_with("#") && !f.starts_with("[")) {

View File

@ -11,7 +11,7 @@ extern "C" {
fn element() { fn element() {
/* Tests needed for: /* Tests needed for:
namespace_uri namespace_uri
*/ */
let element = new_div(); let element = new_div();
assert_eq!(element.prefix(), None, "Shouldn't have a prefix"); assert_eq!(element.prefix(), None, "Shouldn't have a prefix");
@ -52,8 +52,8 @@ fn element() {
"Should return nothing if removed" "Should return nothing if removed"
); );
/* Tests needed for: /* Tests needed for:
get_attribute_ns get_attribute_ns
*/ */
/*TODO should we enable toggle_attribute tests? (Firefox Nightly + Chrome canary only) /*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 // TODO toggle_attribute should permit a single argument when optional arguments are supported
@ -62,7 +62,7 @@ get_attribute_ns
assert!(element.has_attribute("disabled"), "Should be disabled"); 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.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("disabled"), "Should not be disabled");
*/ */
assert!(!element.has_attribute("title"), "Should not have a title"); assert!(!element.has_attribute("title"), "Should not have a title");
assert_eq!( assert_eq!(
@ -79,8 +79,8 @@ get_attribute_ns
); );
assert!(!element.has_attribute("title"), "Should not have a title"); assert!(!element.has_attribute("title"), "Should not have a title");
/* Tests needed for: /* Tests needed for:
set_attribute_ns set_attribute_ns
*/ */
assert!(!element.has_attributes(), "Should not have any attributes"); assert!(!element.has_attributes(), "Should not have any attributes");
assert_eq!( assert_eq!(
@ -95,10 +95,10 @@ set_attribute_ns
"Should return nothing if removed" "Should return nothing if removed"
); );
/* Tests needed for: /* Tests needed for:
remove_attribute_ns remove_attribute_ns
has_attribure_ns has_attribure_ns
closest closest
*/ */
assert_eq!( assert_eq!(
element.matches(".this-is-a-thing").unwrap(), element.matches(".this-is-a-thing").unwrap(),
@ -130,29 +130,29 @@ closest
// TODO non standard moz_matches_selector should we even support? // TODO non standard moz_matches_selector should we even support?
/* Tests needed for: /* Tests needed for:
insert_adjacent_element insert_adjacent_element
insert_adjacent_text insert_adjacent_text
set_pointer_capture set_pointer_capture
release_pointer_capture release_pointer_capture
has_pointer_capture has_pointer_capture
set_capture set_capture
release_capture release_capture
scroll_top scroll_top
set_scroll_top set_scroll_top
scroll_left scroll_left
set_scroll_left set_scroll_left
scroll_width scroll_width
scroll_height scroll_height
scroll, scroll,
scroll_to scroll_to
scroll_by scroll_by
client_top client_top
client_left client_left
client_width client_width
client_height client_height
scroll_top_max scroll_top_max
scroll_left_max scroll_left_max
*/ */
assert_eq!(element.inner_html(), "", "Should return no content"); assert_eq!(element.inner_html(), "", "Should return no content");
element.set_inner_html("<strong>Hey!</strong><em>Web!</em>"); element.set_inner_html("<strong>Hey!</strong><em>Web!</em>");
assert_eq!( assert_eq!(
@ -173,10 +173,10 @@ scroll_left_max
assert_eq!(element.inner_html(), "", "Should return no content"); assert_eq!(element.inner_html(), "", "Should return no content");
/* Tests needed for: /* Tests needed for:
outer_html outer_html
set_outer_html set_outer_html
insert_adjacent_html insert_adjacent_html
*/ */
assert!( assert!(
element.query_selector(".none-existant").unwrap().is_none(), element.query_selector(".none-existant").unwrap().is_none(),
@ -195,5 +195,5 @@ insert_adjacent_html
set_slot set_slot
request_fullscreen request_fullscreen
request_pointer_lock request_pointer_lock
*/ */
} }

View File

@ -75,7 +75,7 @@ fn test_html_element() {
None => assert!(true, "Shouldn't have a custom menu set"), None => assert!(true, "Shouldn't have a custom menu set"),
_ => assert!(false, "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). // TODO: This test is also broken in Chrome (but not Firefox).
// assert!(!element.spellcheck(), "Shouldn't be spellchecked"); // assert!(!element.spellcheck(), "Shouldn't be spellchecked");

View File

@ -56,7 +56,7 @@ fn test_input_element() {
assert!(!element.checked(), "Shouldn't be checked"); assert!(!element.checked(), "Shouldn't be checked");
element.set_checked(true); element.set_checked(true);
assert!(element.checked(), "Should be checked"); assert!(element.checked(), "Should be checked");
*/ */
assert!(!element.disabled(), "Shouldn't be disabled"); assert!(!element.disabled(), "Shouldn't be disabled");
element.set_disabled(true); element.set_disabled(true);
@ -114,29 +114,29 @@ fn test_input_element() {
assert!(!element.indeterminate(), "Shouldn't be indeterminate"); assert!(!element.indeterminate(), "Shouldn't be indeterminate");
*/ */
/*TODO add tests /*TODO add tests
pub fn indeterminate(&self) -> bool pub fn indeterminate(&self) -> bool
pub fn set_indeterminate(&self, indeterminate: bool) pub fn set_indeterminate(&self, indeterminate: bool)
pub fn input_mode(&self) -> String pub fn input_mode(&self) -> String
pub fn set_input_mode(&self, input_mode: &str) pub fn set_input_mode(&self, input_mode: &str)
pub fn list(&self) -> Option<HtmlElement> pub fn list(&self) -> Option<HtmlElement>
pub fn max(&self) -> String pub fn max(&self) -> String
pub fn set_max(&self, max: &str) pub fn set_max(&self, max: &str)
pub fn max_length(&self) -> i32 pub fn max_length(&self) -> i32
pub fn set_max_length(&self, max_length: i32) pub fn set_max_length(&self, max_length: i32)
pub fn min(&self) -> String pub fn min(&self) -> String
pub fn set_min(&self, min: &str) pub fn set_min(&self, min: &str)
pub fn min_length(&self) -> i32 pub fn min_length(&self) -> i32
pub fn set_min_length(&self, min_length: i32) pub fn set_min_length(&self, min_length: i32)
pub fn multiple(&self) -> bool pub fn multiple(&self) -> bool
pub fn set_multiple(&self, multiple: bool) pub fn set_multiple(&self, multiple: bool)
*/ */
assert_eq!(element.name(), "", "Should not have a name"); assert_eq!(element.name(), "", "Should not have a name");
element.set_name("namey"); element.set_name("namey");
assert_eq!(element.name(), "namey", "Should have a name"); assert_eq!(element.name(), "namey", "Should have a name");
/*TODO add tests /*TODO add tests
pub fn pattern(&self) -> String pub fn pattern(&self) -> String
pub fn set_pattern(&self, pattern: &str) pub fn set_pattern(&self, pattern: &str)
*/ */
assert_eq!(element.placeholder(), "", "Should not have a placeholder"); assert_eq!(element.placeholder(), "", "Should not have a placeholder");
element.set_placeholder("some text"); element.set_placeholder("some text");
assert_eq!( assert_eq!(
@ -153,30 +153,30 @@ pub fn set_pattern(&self, pattern: &str)
element.set_required(true); element.set_required(true);
assert!(element.required(), "Should be required"); assert!(element.required(), "Should be required");
/*TODO add tests /*TODO add tests
pub fn size(&self) -> u32 pub fn size(&self) -> u32
pub fn set_size(&self, size: u32) pub fn set_size(&self, size: u32)
*/ */
/*TODO fails in chrome /*TODO fails in chrome
element.set_type("image"); element.set_type("image");
assert_eq!(element.src(), "", "Should have no src"); assert_eq!(element.src(), "", "Should have no src");
element.set_value("hey.png"); element.set_value("hey.png");
assert_eq!(element.src(), "hey.png", "Should have a src"); assert_eq!(element.src(), "hey.png", "Should have a src");
*/ */
/*TODO add tests /*TODO add tests
pub fn src(&self) -> String pub fn src(&self) -> String
pub fn set_src(&self, src: &str) pub fn set_src(&self, src: &str)
pub fn step(&self) -> String pub fn step(&self) -> String
pub fn set_step(&self, step: &str) pub fn set_step(&self, step: &str)
pub fn type_(&self) -> String pub fn type_(&self) -> String
pub fn set_type(&self, type_: &str) pub fn set_type(&self, type_: &str)
pub fn default_value(&self) -> String pub fn default_value(&self) -> String
pub fn set_default_value(&self, default_value: &str) pub fn set_default_value(&self, default_value: &str)
*/ */
/*TODO fails in chrome /*TODO fails in chrome
assert_eq!(element.value(), "", "Should have no value"); assert_eq!(element.value(), "", "Should have no value");
element.set_value("hey!"); element.set_value("hey!");
assert_eq!(element.value(), "hey!", "Should have a value"); assert_eq!(element.value(), "hey!", "Should have a value");
*/ */
element.set_type("number"); element.set_type("number");
element.set_value("1"); element.set_value("1");
assert_eq!(element.value_as_number(), 1.0, "Should have 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.check_validity(), true, "Should be valid");
assert_eq!(element.report_validity(), true, "Should be valid"); assert_eq!(element.report_validity(), true, "Should be valid");
/*TODO add tests /*TODO add tests
pub fn labels(&self) -> Option<NodeList> pub fn labels(&self) -> Option<NodeList>
pub fn select(&self) pub fn select(&self)
pub fn selection_direction(&self) -> Result<Option<String>, JsValue> pub fn selection_direction(&self) -> Result<Option<String>, JsValue>
pub fn set_selection_direction( pub fn set_selection_direction(
&self, &self,
selection_direction: Option<&str> selection_direction: Option<&str>
) -> Result<(), JsValue> ) -> Result<(), JsValue>
pub fn set_range_text(&self, replacement: &str) -> Result<(), JsValue> pub fn set_range_text(&self, replacement: &str) -> Result<(), JsValue>
pub fn set_selection_range( pub fn set_selection_range(
&self, &self,
start: u32, start: u32,
end: u32, end: u32,
direction: &str direction: &str
) -> Result<(), JsValue> ) -> Result<(), JsValue>
*/ */
assert_eq!(element.align(), "", "Should have no align"); assert_eq!(element.align(), "", "Should have no align");
element.set_align("left"); element.set_align("left");
assert_eq!(element.align(), "left", "Should have an align"); assert_eq!(element.align(), "left", "Should have an align");
/*TODO add tests /*TODO add tests
pub fn use_map(&self) -> String pub fn use_map(&self) -> String
pub fn set_use_map(&self, use_map: &str) pub fn set_use_map(&self, use_map: &str)
pub fn text_length(&self) -> i32 pub fn text_length(&self) -> i32
pub fn webkitdirectory(&self) -> bool pub fn webkitdirectory(&self) -> bool
pub fn set_webkitdirectory(&self, webkitdirectory: bool) pub fn set_webkitdirectory(&self, webkitdirectory: bool)
pub fn set_focus_state(&self, a_is_focused: bool) pub fn set_focus_state(&self, a_is_focused: bool)
*/ */
} }

View File

@ -31,6 +31,7 @@ pub mod input_element;
//pub mod menu_element; //pub mod menu_element;
//pub mod menu_item_element; //pub mod menu_item_element;
pub mod dom_point; pub mod dom_point;
pub mod indexeddb;
pub mod location; pub mod location;
pub mod meta_element; pub mod meta_element;
pub mod meter_element; pub mod meter_element;
@ -55,7 +56,6 @@ pub mod style_element;
pub mod table_element; pub mod table_element;
pub mod title_element; pub mod title_element;
pub mod xpath_result; pub mod xpath_result;
pub mod indexeddb;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn deref_works() { fn deref_works() {

View File

@ -8,7 +8,8 @@ fn test_option_element() {
"option_value", "option_value",
false, false,
true, true,
).unwrap(); )
.unwrap();
option.set_disabled(true); option.set_disabled(true);
assert_eq!( assert_eq!(

View File

@ -312,8 +312,8 @@ impl<'src> FirstPass<'src, ()> for weedle::InterfaceDefinition<'src> {
interface_data.partial = false; interface_data.partial = false;
interface_data.superclass = self.inheritance.map(|s| s.identifier.0); interface_data.superclass = self.inheritance.map(|s| s.identifier.0);
interface_data.definition_attributes = self.attributes.as_ref(); interface_data.definition_attributes = self.attributes.as_ref();
interface_data.deprecated = util::get_rust_deprecated(&self.attributes) interface_data.deprecated =
.map(|s| s.to_string()); util::get_rust_deprecated(&self.attributes).map(|s| s.to_string());
} }
if let Some(attrs) = &self.attributes { if let Some(attrs) = &self.attributes {
for attr in attrs.body.list.iter() { for attr in attrs.body.list.iter() {

View File

@ -527,7 +527,8 @@ impl<'a> IdlType<'a> {
// it's up to users to dispatch and/or create instances // it's up to users to dispatch and/or create instances
// appropriately. // appropriately.
if let syn::Type::Path(path) = &inner { if let syn::Type::Path(path) = &inner {
if path.qself.is_none() && path if path.qself.is_none()
&& path
.path .path
.segments .segments
.last() .last()
@ -678,7 +679,8 @@ fn idl_type_flatten_test() {
Sequence(Box::new(Double),), Sequence(Box::new(Double),),
Interface("NodeList"), Interface("NodeList"),
])),), ])),),
]).flatten(), ])
.flatten(),
vec![ vec![
Interface("Node"), Interface("Node"),
Sequence(Box::new(Long)), Sequence(Box::new(Long)),
@ -710,5 +712,6 @@ fn clamped(t: syn::Type) -> syn::Type {
.into_iter() .into_iter()
.collect(), .collect(),
}, },
}.into() }
.into()
} }

View File

@ -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 { if let backend::ast::ImportKind::Type(t) = &mut import.kind {
t.extends.retain(|n| { t.extends.retain(|n| {
let ident = &n.segments.last().unwrap().value().ident; let ident = &n.segments.last().unwrap().value().ident;
first_pass_record.builtin_idents.contains(ident) || first_pass_record.builtin_idents.contains(ident) || filter(&ident.to_string())
filter(&ident.to_string())
}); });
} }
} }
@ -176,7 +175,8 @@ fn builtin_idents() -> BTreeSet<Ident> {
"Promise", "Promise",
"Function", "Function",
"Clamped", "Clamped",
].into_iter() ]
.into_iter()
.map(|id| proc_macro2::Ident::new(id, proc_macro2::Span::call_site())), .map(|id| proc_macro2::Ident::new(id, proc_macro2::Span::call_site())),
) )
} }
@ -240,7 +240,8 @@ fn compile_ast(mut ast: Program) -> String {
(quote! { (quote! {
pub mod #name { #m_tokens } pub mod #name { #m_tokens }
}).to_tokens(&mut tokens); })
.to_tokens(&mut tokens);
} }
tokens.to_string() tokens.to_string()
} }
@ -266,7 +267,8 @@ impl<'src> FirstPassRecord<'src> {
} else { } else {
rust_ident("None") rust_ident("None")
} }
}).collect(), })
.collect(),
variant_values: variants.iter().map(|v| v.0.to_string()).collect(), variant_values: variants.iter().map(|v| v.0.to_string()).collect(),
rust_attrs: vec![parse_quote!(#[derive(Copy, Clone, PartialEq, Debug)])], 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 // whitelist a few names that have known polyfills
match name { match name {
"AudioContext" => { "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 { let doc = match id {
OperationId::Operation(None) => Some(String::new()), OperationId::Operation(None) => Some(String::new()),
OperationId::Constructor(_) => { OperationId::Constructor(_) => Some(format!(
Some(format!("The `new {}(..)` constructor, creating a new \ "The `new {}(..)` constructor, creating a new \
instance of `{0}`\n\n{}", instance of `{0}`\n\n{}",
self_name, self_name,
mdn_doc(self_name, Some(self_name)))) mdn_doc(self_name, Some(self_name))
} )),
OperationId::Operation(Some(name)) => Some(format!( OperationId::Operation(Some(name)) => Some(format!(
"The `{}()` method\n\n{}", "The `{}()` method\n\n{}",
name, name,

View File

@ -30,7 +30,8 @@ pub(crate) fn shared_ref(ty: syn::Type, mutable: bool) -> syn::Type {
None None
}, },
elem: Box::new(ty), elem: Box::new(ty),
}.into() }
.into()
} }
/// Fix case of identifiers like `HTMLBRElement` or `texImage2D` /// Fix case of identifiers like `HTMLBRElement` or `texImage2D`
@ -174,7 +175,8 @@ pub(crate) fn slice_ty(t: syn::Type) -> syn::Type {
syn::TypeSlice { syn::TypeSlice {
bracket_token: Default::default(), bracket_token: Default::default(),
elem: Box::new(t), elem: Box::new(t),
}.into() }
.into()
} }
/// From `T` create `Vec<T>`. /// From `T` create `Vec<T>`.
@ -571,7 +573,8 @@ impl<'src> FirstPassRecord<'src> {
let structural = let structural =
force_structural || is_structural(signature.orig.attrs.as_ref(), container_attrs); force_structural || is_structural(signature.orig.attrs.as_ref(), container_attrs);
let catch = force_throws || throws(&signature.orig.attrs); let catch = force_throws || throws(&signature.orig.attrs);
let variadic = signature.args.len() == signature.orig.args.len() && signature let variadic = signature.args.len() == signature.orig.args.len()
&& signature
.orig .orig
.args .args
.last() .last()
@ -660,25 +663,20 @@ pub fn is_no_interface_object(ext_attrs: &Option<ExtendedAttributeList>) -> bool
has_named_attribute(ext_attrs.as_ref(), "NoInterfaceObject") has_named_attribute(ext_attrs.as_ref(), "NoInterfaceObject")
} }
pub fn get_rust_deprecated<'a>(ext_attrs: &Option<ExtendedAttributeList<'a>>) pub fn get_rust_deprecated<'a>(ext_attrs: &Option<ExtendedAttributeList<'a>>) -> Option<&'a str> {
-> Option<&'a str> ext_attrs
{ .as_ref()?
ext_attrs.as_ref()?
.body .body
.list .list
.iter() .iter()
.filter_map(|attr| { .filter_map(|attr| match attr {
match attr {
ExtendedAttribute::Ident(id) => Some(id), ExtendedAttribute::Ident(id) => Some(id),
_ => None, _ => None,
}
}) })
.filter(|attr| attr.lhs_identifier.0 == "RustDeprecated") .filter(|attr| attr.lhs_identifier.0 == "RustDeprecated")
.filter_map(|ident| { .filter_map(|ident| match ident.rhs {
match ident.rhs {
IdentifierOrString::String(s) => Some(s), IdentifierOrString::String(s) => Some(s),
IdentifierOrString::Identifier(_) => None, IdentifierOrString::Identifier(_) => None,
}
}) })
.next() .next()
.map(|s| s.0) .map(|s| s.0)

View File

@ -51,7 +51,8 @@ pub fn run() -> Promise {
let request = Request::new_with_str_and_init( let request = Request::new_with_str_and_init(
"https://api.github.com/repos/rustwasm/wasm-bindgen/branches/master", "https://api.github.com/repos/rustwasm/wasm-bindgen/branches/master",
&opts, &opts,
).unwrap(); )
.unwrap();
request request
.headers() .headers()
@ -67,10 +68,12 @@ pub fn run() -> Promise {
assert!(resp_value.is_instance_of::<Response>()); assert!(resp_value.is_instance_of::<Response>());
let resp: Response = resp_value.dyn_into().unwrap(); let resp: Response = resp_value.dyn_into().unwrap();
resp.json() resp.json()
}).and_then(|json_value: Promise| { })
.and_then(|json_value: Promise| {
// Convert this other `Promise` into a rust `Future`. // Convert this other `Promise` into a rust `Future`.
JsFuture::from(json_value) JsFuture::from(json_value)
}).and_then(|json| { })
.and_then(|json| {
// Use serde to parse the JSON into a struct. // Use serde to parse the JSON into a struct.
let branch_info: Branch = json.into_serde().unwrap(); let branch_info: Branch = json.into_serde().unwrap();

View File

@ -31,10 +31,7 @@ pub fn main() -> Result<(), JsValue> {
context.move_to(event.offset_x() as f64, event.offset_y() as f64); context.move_to(event.offset_x() as f64, event.offset_y() as f64);
pressed.set(true); pressed.set(true);
}) as Box<FnMut(_)>); }) as Box<FnMut(_)>);
canvas.add_event_listener_with_callback( canvas.add_event_listener_with_callback("mousedown", closure.as_ref().unchecked_ref())?;
"mousedown",
closure.as_ref().unchecked_ref(),
)?;
closure.forget(); closure.forget();
} }
{ {
@ -48,10 +45,7 @@ pub fn main() -> Result<(), JsValue> {
context.move_to(event.offset_x() as f64, event.offset_y() as f64); context.move_to(event.offset_x() as f64, event.offset_y() as f64);
} }
}) as Box<FnMut(_)>); }) as Box<FnMut(_)>);
canvas.add_event_listener_with_callback( canvas.add_event_listener_with_callback("mousemove", closure.as_ref().unchecked_ref())?;
"mousemove",
closure.as_ref().unchecked_ref(),
)?;
closure.forget(); 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.line_to(event.offset_x() as f64, event.offset_y() as f64);
context.stroke(); context.stroke();
}) as Box<FnMut(_)>); }) as Box<FnMut(_)>);
canvas.add_event_listener_with_callback( canvas.add_event_listener_with_callback("mouseup", closure.as_ref().unchecked_ref())?;
"mouseup",
closure.as_ref().unchecked_ref(),
)?;
closure.forget(); closure.forget();
} }

View File

@ -7,16 +7,16 @@ extern crate web_sys;
use std::cell::RefCell; use std::cell::RefCell;
use std::cmp; use std::cmp;
use std::rc::Rc; use std::rc::Rc;
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering::SeqCst};
use std::sync::atomic::ATOMIC_USIZE_INIT; use std::sync::atomic::ATOMIC_USIZE_INIT;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering::SeqCst};
use std::sync::{Arc, Mutex, MutexGuard}; use std::sync::{Arc, Mutex, MutexGuard};
use futures::Future;
use futures::sync::oneshot; use futures::sync::oneshot;
use js_sys::{Promise, Error, WebAssembly, Uint8ClampedArray, Array}; use futures::Future;
use wasm_bindgen::JsCast; use js_sys::{Array, Error, Promise, Uint8ClampedArray, WebAssembly};
use wasm_bindgen::prelude::*; 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}; use web_sys::{DedicatedWorkerGlobalScope, MessageEvent};
macro_rules! console_log { macro_rules! console_log {
@ -42,7 +42,8 @@ impl Scene {
pub fn new(object: &JsValue) -> Result<Scene, JsValue> { pub fn new(object: &JsValue) -> Result<Scene, JsValue> {
console_error_panic_hook::set_once(); console_error_panic_hook::set_once();
Ok(Scene { Ok(Scene {
inner: object.into_serde() inner: object
.into_serde()
.map_err(|e| JsValue::from(e.to_string()))?, .map_err(|e| JsValue::from(e.to_string()))?,
}) })
} }
@ -82,7 +83,7 @@ impl Scene {
Ok(false) => *slot = Some(data), Ok(false) => *slot = Some(data),
Err(e) => { Err(e) => {
*slot = Some(data); *slot = Some(data);
return Err(e) return Err(e);
} }
} }
} }
@ -145,10 +146,7 @@ impl WorkerPool {
workers.push(worker); workers.push(worker);
} }
Ok(WorkerPool { Ok(WorkerPool { workers, callback })
workers,
callback,
})
} }
} }
@ -211,7 +209,7 @@ struct Shared {
} }
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
type ImageData; type ImageData;
#[wasm_bindgen(constructor, catch)] #[wasm_bindgen(constructor, catch)]
@ -234,12 +232,12 @@ impl Render {
if let Some(id) = id.as_f64() { if let Some(id) = id.as_f64() {
if id == self.shared.id as f64 { if id == self.shared.id as f64 {
self.ctx.put_image_data(image.unchecked_ref(), 0.0, 0.0)?; 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); console_log!("unhandled message: {:?}", data);
return Ok(false) return Ok(false);
} }
console_log!("unhandled event: {}", event.type_()); console_log!("unhandled event: {}", event.type_());
@ -250,13 +248,10 @@ impl Render {
#[wasm_bindgen] #[wasm_bindgen]
pub fn child_entry_point(ptr: u32) -> Result<(), JsValue> { pub fn child_entry_point(ptr: u32) -> Result<(), JsValue> {
let ptr = unsafe { let ptr = unsafe { Arc::from_raw(ptr as *const Shared) };
Arc::from_raw(ptr as *const Shared)
};
assert_send(&ptr); assert_send(&ptr);
let global = js_sys::global() let global = js_sys::global().unchecked_into::<DedicatedWorkerGlobalScope>();
.unchecked_into::<DedicatedWorkerGlobalScope>();
ptr.work(&global)?; ptr.work(&global)?;
return Ok(()); return Ok(());
@ -288,7 +283,7 @@ impl Shared {
// If we're beyond the end then we're done! // If we're beyond the end then we're done!
let start = self.next_pixel.fetch_add(BLOCK, SeqCst); let start = self.next_pixel.fetch_add(BLOCK, SeqCst);
if start >= end { if start >= end {
break break;
} }
// Raytrace all our pixels synchronously, writing all the results // 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 // Ok, time to synchronize and commit this data back into the main
// image buffer for other threads and the main thread to see. // image buffer for other threads and the main thread to see.
let mut data = self.rgb_data.lock().unwrap(); let mut data = self.rgb_data.lock().unwrap();
data[start * 4..(start + len) * 4] data[start * 4..(start + len) * 4].copy_from_slice(&mut local_rgb[..len * 4]);
.copy_from_slice(&mut local_rgb[..len * 4]);
// As a "nifty feature" we try to have a live progressive rendering. // As a "nifty feature" we try to have a live progressive rendering.
// That means that we need to periodically send an `ImageData` to // 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 // 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! // image as this is the last chance we'll get!
if self.remaining.fetch_sub(1, SeqCst) == 1 { if self.remaining.fetch_sub(1, SeqCst) == 1 {
@ -341,19 +334,13 @@ impl Shared {
// JS array using `slice`. This means we can't use // JS array using `slice`. This means we can't use
// `web_sys::ImageData` right now but rather we have to use our own // `web_sys::ImageData` right now but rather we have to use our own
// binding. // binding.
let mem = wasm_bindgen::memory() let mem = wasm_bindgen::memory().unchecked_into::<WebAssembly::Memory>();
.unchecked_into::<WebAssembly::Memory>(); let mem = Uint8ClampedArray::new(&mem.buffer()).slice(
let mem = Uint8ClampedArray::new(&mem.buffer())
.slice(
data.as_ptr() as u32, data.as_ptr() as u32,
data.as_ptr() as u32 + data.len() as u32, data.as_ptr() as u32 + data.len() as u32,
); );
drop(data); // unlock the lock, we've copied the data now drop(data); // unlock the lock, we've copied the data now
let data = ImageData::new( let data = ImageData::new(&mem, self.scene.width as f64, self.scene.height as f64)?;
&mem,
self.scene.width as f64,
self.scene.height as f64,
)?;
let arr = Array::new(); let arr = Array::new();
arr.push(&data); arr.push(&data);
arr.push(&JsValue::from(done)); arr.push(&JsValue::from(done));

View File

@ -74,7 +74,6 @@ impl FmOsc {
// control the amount of modulation. // control the amount of modulation.
fm_osc.connect_with_audio_node(&fm_gain)?; fm_osc.connect_with_audio_node(&fm_gain)?;
// Connect the FM oscillator to the frequency parameter of the main // Connect the FM oscillator to the frequency parameter of the main
// oscillator, so that the FM node can modulate its frequency. // oscillator, so that the FM node can modulate its frequency.
fm_gain.connect_with_audio_param(&primary.frequency())?; fm_gain.connect_with_audio_param(&primary.frequency())?;

View File

@ -2,17 +2,16 @@ extern crate js_sys;
extern crate wasm_bindgen; extern crate wasm_bindgen;
extern crate web_sys; extern crate web_sys;
use js_sys::WebAssembly;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast; use wasm_bindgen::JsCast;
use web_sys::{WebGlProgram, WebGlRenderingContext, WebGlShader}; use web_sys::{WebGlProgram, WebGlRenderingContext, WebGlShader};
use js_sys::{WebAssembly};
#[wasm_bindgen] #[wasm_bindgen]
pub fn draw() -> Result<(), JsValue> { pub fn draw() -> Result<(), JsValue> {
let document = web_sys::window().unwrap().document().unwrap(); let document = web_sys::window().unwrap().document().unwrap();
let canvas = document.get_element_by_id("canvas").unwrap(); let canvas = document.get_element_by_id("canvas").unwrap();
let canvas: web_sys::HtmlCanvasElement = canvas let canvas: web_sys::HtmlCanvasElement = canvas.dyn_into::<web_sys::HtmlCanvasElement>()?;
.dyn_into::<web_sys::HtmlCanvasElement>()?;
let context = canvas let context = canvas
.get_context("webgl")? .get_context("webgl")?
@ -42,12 +41,12 @@ pub fn draw() -> Result<(), JsValue> {
context.use_program(Some(&program)); 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 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 vertices_location = vertices.as_ptr() as u32 / 4;
let vert_array = js_sys::Float32Array::new(&memory_buffer).subarray( let vert_array = js_sys::Float32Array::new(&memory_buffer)
vertices_location, .subarray(vertices_location, vertices_location + vertices.len() as u32);
vertices_location + vertices.len() as u32,
);
let buffer = context.create_buffer().ok_or("failed to create buffer")?; let buffer = context.create_buffer().ok_or("failed to create buffer")?;
context.bind_buffer(WebGlRenderingContext::ARRAY_BUFFER, Some(&buffer)); context.bind_buffer(WebGlRenderingContext::ARRAY_BUFFER, Some(&buffer));

View File

@ -86,7 +86,6 @@ impl JsValue {
_marker: marker::PhantomData, _marker: marker::PhantomData,
}; };
/// The `true` JS value constant. /// The `true` JS value constant.
pub const TRUE: JsValue = JsValue { pub const TRUE: JsValue = JsValue {
idx: JSIDX_TRUE, idx: JSIDX_TRUE,
@ -113,9 +112,7 @@ impl JsValue {
/// be owned by the JS garbage collector. /// be owned by the JS garbage collector.
#[inline] #[inline]
pub fn from_str(s: &str) -> JsValue { pub fn from_str(s: &str) -> JsValue {
unsafe { unsafe { JsValue::_new(__wbindgen_string_new(s.as_ptr(), s.len())) }
JsValue::_new(__wbindgen_string_new(s.as_ptr(), s.len()))
}
} }
/// Creates a new JS value which is a number. /// 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. /// allocated number) and returns a handle to the JS version of it.
#[inline] #[inline]
pub fn from_f64(n: f64) -> JsValue { pub fn from_f64(n: f64) -> JsValue {
unsafe { unsafe { JsValue::_new(__wbindgen_number_new(n)) }
JsValue::_new(__wbindgen_number_new(n))
}
} }
/// Creates a new JS value which is a boolean. /// 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. /// allocated boolean) and returns a handle to the JS version of it.
#[inline] #[inline]
pub fn from_bool(b: bool) -> JsValue { 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`. /// Creates a new JS value representing `undefined`.
@ -183,9 +182,7 @@ impl JsValue {
T: serde::ser::Serialize + ?Sized, T: serde::ser::Serialize + ?Sized,
{ {
let s = serde_json::to_string(t)?; let s = serde_json::to_string(t)?;
unsafe { unsafe { Ok(JsValue::_new(__wbindgen_json_parse(s.as_ptr(), s.len()))) }
Ok(JsValue::_new(__wbindgen_json_parse(s.as_ptr(), s.len())))
}
} }
/// Invokes `JSON.stringify` on this value and then parses the resulting /// Invokes `JSON.stringify` on this value and then parses the resulting
@ -588,9 +585,7 @@ impl<T: FromWasmAbi + 'static> Deref for JsStatic<T> {
// wasm, as the pointer will eventually be invalidated but you can get // wasm, as the pointer will eventually be invalidated but you can get
// `&'static T` from this interface. We... probably need to deprecate // `&'static T` from this interface. We... probably need to deprecate
// and/or remove this interface nowadays. // and/or remove this interface nowadays.
unsafe { unsafe { self.__inner.with(|ptr| &*(ptr as *const T)) }
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. /// may prevent your wasm module from building down the road.
#[doc(hidden)] #[doc(hidden)]
pub fn module() -> JsValue { pub fn module() -> JsValue {
unsafe { unsafe { JsValue::_new(__wbindgen_module()) }
JsValue::_new(__wbindgen_module())
}
} }
/// Returns a handle to this wasm instance's `WebAssembly.Memory` /// Returns a handle to this wasm instance's `WebAssembly.Memory`
pub fn memory() -> JsValue { pub fn memory() -> JsValue {
unsafe { unsafe { JsValue::_new(__wbindgen_memory()) }
JsValue::_new(__wbindgen_memory())
}
} }
#[doc(hidden)] #[doc(hidden)]

View File

@ -354,7 +354,6 @@ impl JsRename {
#[wasm_bindgen(js_name = classes_foo)] #[wasm_bindgen(js_name = classes_foo)]
pub fn foo() {} pub fn foo() {}
#[wasm_bindgen] #[wasm_bindgen]
pub struct AccessFieldFoo { pub struct AccessFieldFoo {
pub bar: AccessFieldBar, pub bar: AccessFieldBar,
@ -389,13 +388,10 @@ pub struct RenamedExport {
#[wasm_bindgen(js_class = JsRenamedExport)] #[wasm_bindgen(js_class = JsRenamedExport)]
impl RenamedExport { impl RenamedExport {
#[wasm_bindgen(constructor)] #[wasm_bindgen(constructor)]
pub fn new() -> RenamedExport{ pub fn new() -> RenamedExport {
RenamedExport { RenamedExport { x: 3 }
x: 3,
}
}
pub fn foo(&self) {
} }
pub fn foo(&self) {}
pub fn bar(&self, other: &RenamedExport) { pub fn bar(&self, other: &RenamedExport) {
drop(other); drop(other);

View File

@ -218,13 +218,17 @@ fn drop_drops() {
impl Drop for A { impl Drop for A {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { HIT = true; } unsafe {
HIT = true;
}
} }
} }
let a = A; let a = A;
let x: Closure<Fn()> = Closure::new(move || drop(&a)); let x: Closure<Fn()> = Closure::new(move || drop(&a));
drop(x); drop(x);
unsafe { assert!(HIT); } unsafe {
assert!(HIT);
}
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
@ -233,7 +237,9 @@ fn drop_during_call_ok() {
struct A; struct A;
impl Drop for A { impl Drop for A {
fn drop(&mut self) { 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()); drop(rc2.borrow_mut().take().unwrap());
// `A` should not have been destroyed as a result // `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` // allocate some heap memory to try to paper over our `3`
drop(String::from("1234567890")); drop(String::from("1234567890"));
@ -256,12 +264,18 @@ fn drop_during_call_ok() {
// make sure `A` is bound to our closure environment. // make sure `A` is bound to our closure environment.
drop(&a); drop(&a);
unsafe { assert!(!HIT); } unsafe {
assert!(!HIT);
}
}); });
drop_during_call_save(&x); drop_during_call_save(&x);
*rc.borrow_mut() = Some(x); *rc.borrow_mut() = Some(x);
drop(rc); drop(rc);
unsafe { assert!(!HIT); } unsafe {
assert!(!HIT);
}
drop_during_call_call(); drop_during_call_call();
unsafe { assert!(HIT); } unsafe {
assert!(HIT);
}
} }

View File

@ -181,7 +181,7 @@ fn dead_imports_not_generated() {
#[cfg(feature = "nightly")] #[cfg(feature = "nightly")]
fn import_inside_function_works() { fn import_inside_function_works() {
#[wasm_bindgen(module = "tests/wasm/imports.js")] #[wasm_bindgen(module = "tests/wasm/imports.js")]
extern { extern "C" {
fn import_inside_function_works(); fn import_inside_function_works();
} }
import_inside_function_works(); import_inside_function_works();
@ -199,7 +199,7 @@ mod private {
pub fn foo() { pub fn foo() {
#[wasm_bindgen(module = "tests/wasm/imports.js")] #[wasm_bindgen(module = "tests/wasm/imports.js")]
extern { extern "C" {
fn import_inside_private_module(); fn import_inside_private_module();
} }
import_inside_private_module(); import_inside_private_module();
@ -207,7 +207,7 @@ mod private {
} }
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
fn something_not_defined_in_the_environment(); fn something_not_defined_in_the_environment();
type TypeThatIsNotDefined; type TypeThatIsNotDefined;
@ -224,7 +224,7 @@ extern {
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn undefined_function_is_ok() { fn undefined_function_is_ok() {
if !should_call_undefined_functions() { if !should_call_undefined_functions() {
return return;
} }
something_not_defined_in_the_environment(); something_not_defined_in_the_environment();

View File

@ -132,7 +132,8 @@ fn serde() {
b: "foo".to_string(), b: "foo".to_string(),
c: None, c: None,
d: Bar { a: 1 }, d: Bar { a: 1 },
}).unwrap(), })
.unwrap(),
); );
let foo = ret.into_serde::<Foo>().unwrap(); let foo = ret.into_serde::<Foo>().unwrap();