mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-03-16 02:00:51 +00:00
Fix generated shims if APIs don't exist
This commit fixes instantiation of the wasm module even if some of the improted APIs don't exist. This extends the functionality initially added in #409 to attempt to gracefully allow importing values from the environment which don't actually exist in all contexts. In addition to nonexistent methods being handled now entire nonexistent types are now also handled. I suspect that eventually we'll add a CLI flag to `wasm-bindgen` to say "I assert everything exists, don't check it" to trim out the extra JS glue generated here. In the meantime though this'll pave the way for a wasm-bindgen shim to be instantiated in both a web worker and the main thread, while using DOM-like APIs only on the main thread.
This commit is contained in:
parent
e03e40451e
commit
13cac2d0c4
@ -1542,7 +1542,7 @@ impl<'a> Context<'a> {
|
||||
if (desc) return desc;
|
||||
obj = Object.getPrototypeOf(obj);
|
||||
}
|
||||
throw new Error(`descriptor for id='${id}' not found`);
|
||||
return {}
|
||||
}
|
||||
",
|
||||
);
|
||||
@ -1956,29 +1956,26 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
),
|
||||
}
|
||||
} else {
|
||||
let (location, binding) = if op.is_static {
|
||||
("", format!(".bind({})", class))
|
||||
} else {
|
||||
(".prototype", "".into())
|
||||
};
|
||||
|
||||
match &op.kind {
|
||||
let target = format!("typeof {0} === 'undefined' ? null : {}{}",
|
||||
class,
|
||||
if op.is_static { "" } else { ".prototype" });
|
||||
let (mut target, name) = match &op.kind {
|
||||
shared::OperationKind::Regular => {
|
||||
format!("{}{}.{}{}", class, location, import.function.name, binding)
|
||||
(format!("{}.{}", target, import.function.name), &import.function.name)
|
||||
}
|
||||
shared::OperationKind::Getter(g) => {
|
||||
self.cx.expose_get_inherited_descriptor();
|
||||
format!(
|
||||
"GetOwnOrInheritedPropertyDescriptor({}{}, '{}').get{}",
|
||||
class, location, g, binding,
|
||||
)
|
||||
(format!(
|
||||
"GetOwnOrInheritedPropertyDescriptor({}, '{}').get",
|
||||
target, g,
|
||||
), g)
|
||||
}
|
||||
shared::OperationKind::Setter(s) => {
|
||||
self.cx.expose_get_inherited_descriptor();
|
||||
format!(
|
||||
"GetOwnOrInheritedPropertyDescriptor({}{}, '{}').set{}",
|
||||
class, location, s, binding,
|
||||
)
|
||||
(format!(
|
||||
"GetOwnOrInheritedPropertyDescriptor({}, '{}').set",
|
||||
target, s,
|
||||
), s)
|
||||
}
|
||||
shared::OperationKind::IndexingGetter => {
|
||||
panic!("indexing getter should be structural")
|
||||
@ -1989,24 +1986,20 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
shared::OperationKind::IndexingDeleter => {
|
||||
panic!("indexing deleter should be structural")
|
||||
}
|
||||
};
|
||||
target.push_str(&format!(" || function() {{
|
||||
throw new Error(`wasm-bindgen: {}.{} does not exist`);
|
||||
}}", class, name));
|
||||
if op.is_static {
|
||||
target.insert(0, '(');
|
||||
target.push_str(").bind(");
|
||||
target.push_str(&class);
|
||||
target.push_str(")");
|
||||
}
|
||||
target
|
||||
};
|
||||
|
||||
let fallback = if import.structural {
|
||||
"".to_string()
|
||||
} else {
|
||||
format!(
|
||||
" || function() {{
|
||||
throw new Error(`wasm-bindgen: {} does not exist`);
|
||||
}}",
|
||||
target
|
||||
)
|
||||
};
|
||||
|
||||
self.cx.global(&format!(
|
||||
"const {}_target = {}{};",
|
||||
import.shim, target, fallback
|
||||
));
|
||||
self.cx.global(&format!("const {}_target = {};", import.shim, target));
|
||||
Ok(format!(
|
||||
"{}_target{}",
|
||||
import.shim,
|
||||
|
@ -104,3 +104,4 @@ exports.assert_dead_import_not_generated = function() {
|
||||
|
||||
exports.import_inside_function_works = function() {};
|
||||
exports.import_inside_private_module = function() {};
|
||||
exports.should_call_undefined_functions = () => false;
|
||||
|
@ -50,6 +50,7 @@ extern "C" {
|
||||
|
||||
fn unused_import();
|
||||
fn assert_dead_import_not_generated();
|
||||
fn should_call_undefined_functions() -> bool;
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
@ -204,3 +205,30 @@ mod private {
|
||||
import_inside_private_module();
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
fn something_not_defined_in_the_environment();
|
||||
|
||||
type TypeThatIsNotDefined;
|
||||
#[wasm_bindgen(constructor)]
|
||||
fn new() -> TypeThatIsNotDefined;
|
||||
#[wasm_bindgen(method)]
|
||||
fn method(this: &TypeThatIsNotDefined);
|
||||
#[wasm_bindgen(method, getter)]
|
||||
fn property(this: &TypeThatIsNotDefined) -> u32;
|
||||
#[wasm_bindgen(method, setter)]
|
||||
fn set_property(this: &TypeThatIsNotDefined, val: u32);
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn undefined_function_is_ok() {
|
||||
if !should_call_undefined_functions() {
|
||||
return
|
||||
}
|
||||
something_not_defined_in_the_environment();
|
||||
|
||||
let x = TypeThatIsNotDefined::new();
|
||||
x.method();
|
||||
x.set_property(x.property());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user