1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-12 00:54:02 -05:00

feat: Show the URL of streaming WASM modules in stack traces (#12268)

WebAssembly modules compiled through `WebAssembly.compile()` and similar
non-streaming APIs don't have a URL associated to them, because they
have been compiled from a buffer source. In stack traces, V8 will use
a URL such as `wasm://wasm/d1c677ea`, with a hash of the module.

However, wasm modules compiled through streaming APIs, like
`WebAssembly.compileStreaming()`, do have a known URL, which can be
obtained from the `Response` object passed into the streaming APIs. And
as per the developer-facing display conventions in the WebAssembly
Web API spec, this URL should be used in stack traces. This change
implements that.
This commit is contained in:
Andreu Botella 2021-10-10 07:03:23 -07:00 committed by GitHub
parent 6ac0337165
commit 5edd277161
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 46 additions and 47 deletions

View file

@ -856,11 +856,18 @@ itest!(wasm_async {
});
itest!(wasm_unreachable {
args: "run wasm_unreachable.js",
args: "run --allow-read wasm_unreachable.js",
output: "wasm_unreachable.out",
exit_code: 1,
});
itest!(wasm_url {
args: "run --quiet --allow-net=localhost:4545 wasm_url.js",
output: "wasm_url.out",
exit_code: 1,
http_server: true,
});
itest!(weakref {
args: "run --quiet --reload weakref.ts",
output: "weakref.ts.out",

BIN
cli/tests/testdata/unreachable.wasm vendored Normal file

Binary file not shown.

View file

@ -1,50 +1,9 @@
// WebAssembly module containing a single function with an unreachable instruction
const binary = Uint8Array.from([
0x00,
0x61,
0x73,
0x6d,
0x01,
0x00,
0x00,
0x00,
0x01,
0x04,
0x01,
0x60,
0x00,
0x00,
0x03,
0x02,
0x01,
0x00,
0x07,
0x0f,
0x01,
0x0b,
0x75,
0x6e,
0x72,
0x65,
0x61,
0x63,
0x68,
0x61,
0x62,
0x6c,
0x65,
0x00,
0x00,
0x0a,
0x05,
0x01,
0x03,
0x00,
0x00,
0x0b,
]);
const binary = await Deno.readFile("./unreachable.wasm");
const module = new WebAssembly.Module(binary);
const instance = new WebAssembly.Instance(module);
// Compare the stack trace with wasm_url.js, which compiles the WASM module with
// streaming APIs.
instance.exports.unreachable();

View file

@ -1,3 +1,3 @@
error: Uncaught RuntimeError: unreachable
at <anonymous> (wasm://wasm/[WILDCARD])
error: Uncaught (in promise) RuntimeError: unreachable
at <anonymous> (wasm://wasm/d1c677ea:1:41)
at [WILDCARD]/wasm_unreachable.js:[WILDCARD]

8
cli/tests/testdata/wasm_url.js vendored Normal file
View file

@ -0,0 +1,8 @@
const module = await WebAssembly.compileStreaming(
fetch("http://localhost:4545/unreachable.wasm"),
);
const instance = new WebAssembly.Instance(module);
// Compare the stack trace with wasm_unreachable.js, which compiles the WASM
// module with synchronous APIs.
instance.exports.unreachable();

3
cli/tests/testdata/wasm_url.out vendored Normal file
View file

@ -0,0 +1,3 @@
error: Uncaught (in promise) RuntimeError: unreachable
at <anonymous> (http://localhost:4545/unreachable.wasm:1:41)
at [WILDCARD]/wasm_url.js:[WILDCARD]

View file

@ -63,6 +63,8 @@ declare namespace Deno {
* compiler. Takes the rid and a `Uint8Array`.
* - `op_wasm_streaming_abort`. Aborts the wasm compilation. Takes the rid
* and an exception. Invalidates the resource.
* - `op_wasm_streaming_set_url`. Sets a source URL for the wasm module.
* Takes the rid and a string.
* - To indicate the end of the resource, use `Deno.core.close()` with the
* rid.
*/

View file

@ -26,6 +26,10 @@ pub(crate) fn init_builtins() -> Extension {
("op_resources", op_sync(op_resources)),
("op_wasm_streaming_feed", op_sync(op_wasm_streaming_feed)),
("op_wasm_streaming_abort", op_sync(op_wasm_streaming_abort)),
(
"op_wasm_streaming_set_url",
op_sync(op_wasm_streaming_set_url),
),
])
.build()
}
@ -137,3 +141,16 @@ pub fn op_wasm_streaming_abort(
Ok(())
}
pub fn op_wasm_streaming_set_url(
state: &mut OpState,
rid: ResourceId,
url: String,
) -> Result<(), AnyError> {
let wasm_streaming =
state.resource_table.get::<WasmStreamingResource>(rid)?;
wasm_streaming.0.borrow_mut().set_url(&url);
Ok(())
}

View file

@ -526,6 +526,9 @@
throw new TypeError(`HTTP status code ${res.status}`);
}
// Pass the resolved URL to v8.
core.opSync("op_wasm_streaming_set_url", rid, res.url);
// 2.6.
// Rather than consuming the body as an ArrayBuffer, this passes each
// chunk to the feed as soon as it's available.