Update with list IR from walrus

This commit updates `wasm-bindgen` to the latest version of `walrus`
which transforms all internal IR representations to a list-based IR
instead of a tree-based IR. This isn't a major change other than
cosmetic for `wasm-bindgen` itself, but involves a lot of changes to the
threads/anyref passes.

This commit also updates our CI configuration to actually run all the
anyref tests on CI. This is done by downloading a nightly build of
node.js which is theorized to continue to be there for awhile until the
full support makes its way into releases.
This commit is contained in:
Alex Crichton
2019-08-12 10:49:00 -07:00
parent 1d0c333a2b
commit ad34fa29d8
8 changed files with 323 additions and 371 deletions

View File

@ -18,9 +18,9 @@ log = "0.4"
rustc-demangle = "0.1.13"
serde_json = "1.0"
tempfile = "3.0"
walrus = "0.10.0"
walrus = "0.11.0"
wasm-bindgen-anyref-xform = { path = '../anyref-xform', version = '=0.2.48' }
wasm-bindgen-shared = { path = "../shared", version = '=0.2.48' }
wasm-bindgen-threads-xform = { path = '../threads-xform', version = '=0.2.48' }
wasm-bindgen-wasm-interpreter = { path = "../wasm-interpreter", version = '=0.2.48' }
wasm-webidl-bindings = "0.3.0"
wasm-webidl-bindings = "0.4.0"

View File

@ -14,9 +14,8 @@ use crate::descriptor::{Closure, Descriptor};
use failure::Error;
use std::borrow::Cow;
use std::collections::{HashMap, HashSet};
use std::mem;
use walrus::ImportId;
use walrus::{CustomSection, FunctionId, LocalFunction, Module, TypedCustomSectionId};
use walrus::{CustomSection, FunctionId, Module, TypedCustomSectionId};
use wasm_bindgen_wasm_interpreter::Interpreter;
#[derive(Default, Debug)]
@ -112,19 +111,16 @@ impl WasmBindgenDescriptorsSection {
let mut element_removal_list = HashSet::new();
let mut func_to_descriptor = HashMap::new();
for (id, local) in module.funcs.iter_local() {
let entry = local.entry_block();
let mut find = FindDescribeClosure {
func: local,
wbindgen_describe_closure,
cur: entry.into(),
call: None,
found: false,
};
find.visit_block_id(&entry);
if let Some(call) = find.call {
dfs_in_order(&mut find, local, local.entry_block());
if find.found {
let descriptor = interpreter
.interpret_closure_descriptor(id, module, &mut element_removal_list)
.unwrap();
func_to_descriptor.insert(id, (call, Descriptor::decode(descriptor)));
func_to_descriptor.insert(id, Descriptor::decode(descriptor));
}
}
@ -150,7 +146,7 @@ impl WasmBindgenDescriptorsSection {
// freshly manufactured import. Save off the type of this import in
// ourselves, and then we're good to go.
let ty = module.funcs.get(wbindgen_describe_closure).ty();
for (func, (call_instr, descriptor)) in func_to_descriptor {
for (func, descriptor) in func_to_descriptor {
let import_name = format!("__wbindgen_closure_wrapper{}", func.index());
let (id, import_id) =
module.add_import_func("__wbindgen_placeholder__", &import_name, ty);
@ -160,37 +156,42 @@ impl WasmBindgenDescriptorsSection {
walrus::FunctionKind::Local(l) => l,
_ => unreachable!(),
};
let call = local.get_mut(call_instr).unwrap_call_mut();
assert_eq!(call.func, wbindgen_describe_closure);
call.func = id;
let entry = local.entry_block();
dfs_pre_order_mut(
&mut UpdateDescribeClosure {
wbindgen_describe_closure,
replacement: id,
},
local,
entry,
);
self.closure_imports
.insert(import_id, descriptor.unwrap_closure());
}
return Ok(());
struct FindDescribeClosure<'a> {
func: &'a LocalFunction,
struct FindDescribeClosure {
wbindgen_describe_closure: FunctionId,
cur: ExprId,
call: Option<ExprId>,
found: bool,
}
impl<'a> Visitor<'a> for FindDescribeClosure<'a> {
fn local_function(&self) -> &'a LocalFunction {
self.func
}
fn visit_expr_id(&mut self, id: &ExprId) {
let prev = mem::replace(&mut self.cur, *id);
id.visit(self);
self.cur = prev;
}
impl<'a> Visitor<'a> for FindDescribeClosure {
fn visit_call(&mut self, call: &Call) {
call.visit(self);
if call.func == self.wbindgen_describe_closure {
assert!(self.call.is_none());
self.call = Some(self.cur);
self.found = true;
}
}
}
struct UpdateDescribeClosure {
wbindgen_describe_closure: FunctionId,
replacement: FunctionId,
}
impl<'a> VisitorMut for UpdateDescribeClosure {
fn visit_call_mut(&mut self, call: &mut Call) {
if call.func == self.wbindgen_describe_closure {
call.func = self.replacement;
}
}
}

View File

@ -644,10 +644,9 @@ impl<'a> Context<'a> {
self.module.start = Some(match self.module.start {
Some(prev_start) => {
let mut builder = walrus::FunctionBuilder::new();
let call_init = builder.call(import, Box::new([]));
let call_prev = builder.call(prev_start, Box::new([]));
builder.finish(ty, Vec::new(), vec![call_init, call_prev], self.module)
let mut builder = walrus::FunctionBuilder::new(&mut self.module.types, &[], &[]);
builder.func_body().call(import).call(prev_start);
builder.finish(Vec::new(), &mut self.module.funcs)
}
None => import,
});
@ -827,11 +826,9 @@ impl<'a> Context<'a> {
// because the start function currently only shows up when it's injected
// through thread/anyref transforms. These injected start functions need
// to happen before user code, so we always schedule them first.
let mut builder = walrus::FunctionBuilder::new();
let call1 = builder.call(prev_start, Box::new([]));
let call2 = builder.call(id, Box::new([]));
let ty = self.module.funcs.get(id).ty();
let new_start = builder.finish(ty, Vec::new(), vec![call1, call2], self.module);
let mut builder = walrus::FunctionBuilder::new(&mut self.module.types, &[], &[]);
builder.func_body().call(prev_start).call(id);
let new_start = builder.finish(Vec::new(), &mut self.module.funcs);
self.module.start = Some(new_start);
Ok(())
}