Merge pull request #274 from fitzgen/js-sys

Expose objects and functions from the JavaScript global scope
This commit is contained in:
Nick Fitzgerald
2018-06-19 10:42:04 -07:00
committed by GitHub
10 changed files with 297 additions and 15 deletions

View File

@ -29,7 +29,7 @@ pub struct Context<'a> {
pub imported_names: HashSet<String>,
pub exported_classes: HashMap<String, ExportedClass>,
pub function_table_needed: bool,
pub run_descriptor: &'a Fn(&str) -> Vec<u32>,
pub run_descriptor: &'a Fn(&str) -> Option<Vec<u32>>,
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<Descriptor> {
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.method {
Some(shared::MethodData { class, kind, getter, setter }) => {

View File

@ -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<u32>);
#[derive(Debug)]
struct MyError(String);