Merge pull request #959 from alexcrichton/moreundef

Fix generated shims if APIs don't exist
This commit is contained in:
Nick Fitzgerald 2018-10-12 10:18:44 -07:00 committed by GitHub
commit aac8696d05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 32 deletions

View File

@ -1542,7 +1542,7 @@ impl<'a> Context<'a> {
if (desc) return desc; if (desc) return desc;
obj = Object.getPrototypeOf(obj); 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 { } else {
let (location, binding) = if op.is_static { let target = format!("typeof {0} === 'undefined' ? null : {}{}",
("", format!(".bind({})", class)) class,
} else { if op.is_static { "" } else { ".prototype" });
(".prototype", "".into()) let (mut target, name) = match &op.kind {
};
match &op.kind {
shared::OperationKind::Regular => { shared::OperationKind::Regular => {
format!("{}{}.{}{}", class, location, import.function.name, binding) (format!("{}.{}", target, import.function.name), &import.function.name)
} }
shared::OperationKind::Getter(g) => { shared::OperationKind::Getter(g) => {
self.cx.expose_get_inherited_descriptor(); self.cx.expose_get_inherited_descriptor();
format!( (format!(
"GetOwnOrInheritedPropertyDescriptor({}{}, '{}').get{}", "GetOwnOrInheritedPropertyDescriptor({}, '{}').get",
class, location, g, binding, target, g,
) ), g)
} }
shared::OperationKind::Setter(s) => { shared::OperationKind::Setter(s) => {
self.cx.expose_get_inherited_descriptor(); self.cx.expose_get_inherited_descriptor();
format!( (format!(
"GetOwnOrInheritedPropertyDescriptor({}{}, '{}').set{}", "GetOwnOrInheritedPropertyDescriptor({}, '{}').set",
class, location, s, binding, target, s,
) ), s)
} }
shared::OperationKind::IndexingGetter => { shared::OperationKind::IndexingGetter => {
panic!("indexing getter should be structural") panic!("indexing getter should be structural")
@ -1989,24 +1986,20 @@ impl<'a, 'b> SubContext<'a, 'b> {
shared::OperationKind::IndexingDeleter => { shared::OperationKind::IndexingDeleter => {
panic!("indexing deleter should be structural") 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 { self.cx.global(&format!("const {}_target = {};", import.shim, target));
"".to_string()
} else {
format!(
" || function() {{
throw new Error(`wasm-bindgen: {} does not exist`);
}}",
target
)
};
self.cx.global(&format!(
"const {}_target = {}{};",
import.shim, target, fallback
));
Ok(format!( Ok(format!(
"{}_target{}", "{}_target{}",
import.shim, import.shim,

View File

@ -104,3 +104,4 @@ exports.assert_dead_import_not_generated = function() {
exports.import_inside_function_works = function() {}; exports.import_inside_function_works = function() {};
exports.import_inside_private_module = function() {}; exports.import_inside_private_module = function() {};
exports.should_call_undefined_functions = () => false;

View File

@ -50,6 +50,7 @@ extern "C" {
fn unused_import(); fn unused_import();
fn assert_dead_import_not_generated(); fn assert_dead_import_not_generated();
fn should_call_undefined_functions() -> bool;
} }
#[wasm_bindgen] #[wasm_bindgen]
@ -204,3 +205,30 @@ mod private {
import_inside_private_module(); 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());
}