Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving the code generation for catch #2098

Merged
merged 5 commits into from
Apr 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions crates/cli-support/src/js/binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ pub struct JsFunction {
pub ts_arg_tys: Vec<String>,
pub ts_ret_ty: Option<String>,
pub might_be_optional_field: bool,
pub catch: bool,
pub log_error: bool,
}

impl<'a, 'b> Builder<'a, 'b> {
Expand Down Expand Up @@ -201,7 +203,6 @@ impl<'a, 'b> Builder<'a, 'b> {

if self.catch {
js.cx.expose_handle_error()?;
call = format!("try {{\n{}}} catch (e) {{\n handleError(e)\n}}\n", call);
}

// Generate a try/catch block in debug mode which handles unexpected and
Expand All @@ -210,7 +211,6 @@ impl<'a, 'b> Builder<'a, 'b> {
// elsewhere.
if self.log_error {
js.cx.expose_log_error();
call = format!("try {{\n{}}} catch (e) {{\n logError(e)\n}}\n", call);
}

code.push_str(&call);
Expand All @@ -235,6 +235,8 @@ impl<'a, 'b> Builder<'a, 'b> {
ts_arg_tys,
ts_ret_ty,
might_be_optional_field,
catch: self.catch,
log_error: self.log_error,
})
}

Expand Down
74 changes: 55 additions & 19 deletions crates/cli-support/src/js/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1666,9 +1666,16 @@ impl<'a> Context<'a> {
let add = self.expose_add_to_anyref_table(table, alloc)?;
self.global(&format!(
"
function handleError(e) {{
const idx = {}(e);
wasm.{}(idx);
function handleError(f) {{
return function () {{
try {{
return f.apply(this, arguments);

}} catch (e) {{
const idx = {}(e);
wasm.{}(idx);
}}
}};
}}
",
add, store,
Expand All @@ -1678,8 +1685,15 @@ impl<'a> Context<'a> {
self.expose_add_heap_object();
self.global(&format!(
"
function handleError(e) {{
wasm.{}(addHeapObject(e));
function handleError(f) {{
return function () {{
try {{
return f.apply(this, arguments);

}} catch (e) {{
wasm.{}(addHeapObject(e));
}}
}};
}}
",
store,
Expand All @@ -1695,20 +1709,27 @@ impl<'a> Context<'a> {
}
self.global(
"\
function logError(e) {
let error = (function () {
function logError(f) {
return function () {
try {
return e instanceof Error \
? `${e.message}\\n\\nStack:\\n${e.stack}` \
: e.toString();
} catch(_) {
return \"<failed to stringify thrown value>\";
return f.apply(this, arguments);

} catch (e) {
let error = (function () {
try {
return e instanceof Error \
? `${e.message}\\n\\nStack:\\n${e.stack}` \
: e.toString();
} catch(_) {
return \"<failed to stringify thrown value>\";
}
}());
console.error(\"wasm-bindgen: imported JS function that \
was not marked as `catch` threw an error:\", \
error);
throw e;
}
}());
console.error(\"wasm-bindgen: imported JS function that \
was not marked as `catch` threw an error:\", \
error);
throw e;
};
}
",
);
Expand Down Expand Up @@ -2183,6 +2204,8 @@ impl<'a> Context<'a> {
js_doc,
code,
might_be_optional_field,
catch,
log_error,
} = builder
.process(&adapter, instrs, arg_names)
.with_context(|| match kind {
Expand All @@ -2201,6 +2224,9 @@ impl<'a> Context<'a> {
// on what's being exported.
match kind {
Kind::Export(export) => {
assert_eq!(catch, false);
assert_eq!(log_error, false);

let ts_sig = match export.generate_typescript {
true => Some(ts_sig.as_str()),
false => None,
Expand Down Expand Up @@ -2257,10 +2283,20 @@ impl<'a> Context<'a> {
}
}
Kind::Import(core) => {
self.wasm_import_definitions
.insert(core, format!("function{}", code));
let code = if catch {
format!("handleError(function{})", code)
} else if log_error {
format!("logError(function{})", code)
} else {
format!("function{}", code)
};

self.wasm_import_definitions.insert(core, code);
}
Kind::Adapter => {
assert_eq!(catch, false);
assert_eq!(log_error, false);

self.globals.push_str("function ");
self.globals.push_str(&self.adapter_name(id));
self.globals.push_str(&code);
Expand Down
23 changes: 13 additions & 10 deletions crates/cli/tests/reference/anyref-import-catch.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,26 @@ function addToAnyrefTable0(obj) {
return idx;
}

function handleError(e) {
const idx = addToAnyrefTable0(e);
wasm.__wbindgen_exn_store(idx);
function handleError(f) {
return function () {
try {
return f.apply(this, arguments);

} catch (e) {
const idx = addToAnyrefTable0(e);
wasm.__wbindgen_exn_store(idx);
}
};
}
/**
*/
export function exported() {
wasm.exported();
}

export const __wbg_foo_8d66ddef0ff279d6 = function() {
try {
foo();
} catch (e) {
handleError(e)
}
};
export const __wbg_foo_8d66ddef0ff279d6 = handleError(function() {
foo();
});

export const __wbindgen_throw = function(arg0, arg1) {
throw new Error(getStringFromWasm0(arg0, arg1));
Expand Down
21 changes: 12 additions & 9 deletions crates/cli/tests/reference/import-catch.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,15 @@ function addHeapObject(obj) {
return idx;
}

function handleError(e) {
wasm.__wbindgen_exn_store(addHeapObject(e));
function handleError(f) {
return function () {
try {
return f.apply(this, arguments);

} catch (e) {
wasm.__wbindgen_exn_store(addHeapObject(e));
}
};
}
/**
*/
Expand All @@ -42,13 +49,9 @@ export const __wbindgen_object_drop_ref = function(arg0) {
takeObject(arg0);
};

export const __wbg_foo_8d66ddef0ff279d6 = function() {
try {
foo();
} catch (e) {
handleError(e)
}
};
export const __wbg_foo_8d66ddef0ff279d6 = handleError(function() {
foo();
});

export const __wbindgen_rethrow = function(arg0) {
throw takeObject(arg0);
Expand Down