From 132103eb065919ce71c8578d592e83e30a77d5d3 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Mon, 18 Jun 2018 13:48:57 -0700 Subject: [PATCH] cli-support: Ignore missing descriptor functions This can happen when a nested dependency crate exports things but the root crate doesn't use them. In these cases, it is fine to ignore the missing descriptor, because the thing it describes was removed as dead code. --- crates/cli-support/src/js/mod.rs | 31 +++++++++++++++++++++++-------- crates/cli-support/src/lib.rs | 19 ++++++++++++++----- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 9b8f1f60b..d5e7a7829 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -29,7 +29,7 @@ pub struct Context<'a> { pub imported_names: HashSet, pub exported_classes: HashMap, pub function_table_needed: bool, - pub run_descriptor: &'a Fn(&str) -> Vec, + pub run_descriptor: &'a Fn(&str) -> Option>, pub module_versions: Vec<(String, String)>, } @@ -474,7 +474,10 @@ impl<'a> Context<'a> { for field in class.fields.iter() { let wasm_getter = shared::struct_field_get(name, &field.name); let wasm_setter = shared::struct_field_set(name, &field.name); - let descriptor = self.describe(&wasm_getter); + let descriptor = match self.describe(&wasm_getter) { + None => continue, + Some(d) => d, + }; let set = { let mut cx = Js2Rust::new(&field.name, self); @@ -1393,10 +1396,9 @@ impl<'a> Context<'a> { Ok(()) } - fn describe(&self, name: &str) -> Descriptor { + fn describe(&self, name: &str) -> Option { let name = format!("__wbindgen_describe_{}", name); - let ret = (self.run_descriptor)(&name); - Descriptor::decode(&ret) + (self.run_descriptor)(&name).map(|d| Descriptor::decode(&d)) } fn global(&mut self, s: &str) { @@ -1474,7 +1476,12 @@ impl<'a, 'b> SubContext<'a, 'b> { if let Some(ref class) = export.class { return self.generate_export_for_class(class, export); } - let descriptor = self.cx.describe(&export.function.name); + + let descriptor = match self.cx.describe(&export.function.name) { + None => return Ok(()), + Some(d) => d, + }; + let (js, ts) = Js2Rust::new(&export.function.name, self.cx) .process(descriptor.unwrap_function())? .finish("function", &format!("wasm.{}", export.function.name)); @@ -1492,7 +1499,12 @@ impl<'a, 'b> SubContext<'a, 'b> { export: &shared::Export, ) -> Result<(), Error> { let wasm_name = shared::struct_function_export_name(class_name, &export.function.name); - let descriptor = self.cx.describe(&wasm_name); + + let descriptor = match self.cx.describe(&wasm_name) { + None => return Ok(()), + Some(d) => d, + }; + let (js, ts) = Js2Rust::new(&export.function.name, self.cx) .method(export.method) .process(descriptor.unwrap_function())? @@ -1603,7 +1615,10 @@ impl<'a, 'b> SubContext<'a, 'b> { import: &shared::ImportFunction) -> Result<(), Error> { - let descriptor = self.cx.describe(&import.shim); + let descriptor = match self.cx.describe(&import.shim) { + None => return Ok(()), + Some(d) => d, + }; let target = match import.class { Some(ref class) if import.js_new => { diff --git a/crates/cli-support/src/lib.rs b/crates/cli-support/src/lib.rs index 8f80a0870..092f8f2ce 100644 --- a/crates/cli-support/src/lib.rs +++ b/crates/cli-support/src/lib.rs @@ -140,11 +140,19 @@ impl Bindgen { module_versions: Default::default(), run_descriptor: &|name| { let mut v = MyExternals(Vec::new()); - let ret = instance - .invoke_export(name, &[], &mut v) - .expect("failed to run export"); - assert!(ret.is_none()); - v.0 + match instance.invoke_export(name, &[], &mut v) { + Ok(None) => Some(v.0), + Ok(Some(_)) => { + unreachable!( + "there is only one export, and we only return None from it" + ) + }, + // Allow missing exported describe functions. This can + // happen when a nested dependency crate exports things + // but the root crate doesn't use them. + Err(wasmi::Error::Function(_)) => None, + Err(e) => panic!("unexpected error running descriptor: {}", e), + } }, }; for program in programs.iter() { @@ -342,6 +350,7 @@ impl wasmi::ImportResolver for MyResolver { } struct MyExternals(Vec); + #[derive(Debug)] struct MyError(String);