Skip to content

Commit ad82694

Browse files
tniessentargos
authored andcommitted
lib,src: use Response URL as WebAssembly location
As per Section 3 of the WebAssembly Web API spec. PR-URL: #42842 Refs: #42701 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent 7b70144 commit ad82694

File tree

6 files changed

+40
-1
lines changed

6 files changed

+40
-1
lines changed

lib/internal/bootstrap/pre_execution.js

+4
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,10 @@ function setupFetch() {
245245
throw new ERR_WEBASSEMBLY_RESPONSE('body has already been used');
246246
}
247247

248+
if (response.url) {
249+
streamState.setURL(response.url);
250+
}
251+
248252
// Pass all data from the response body to the WebAssembly compiler.
249253
for await (const chunk of response.body) {
250254
streamState.push(chunk);

src/node_wasm_web_api.cc

+12
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Local<Function> WasmStreamingObject::Initialize(Environment* env) {
2929
t->InstanceTemplate()->SetInternalFieldCount(
3030
WasmStreamingObject::kInternalFieldCount);
3131

32+
env->SetProtoMethod(t, "setURL", SetURL);
3233
env->SetProtoMethod(t, "push", Push);
3334
env->SetProtoMethod(t, "finish", Finish);
3435
env->SetProtoMethod(t, "abort", Abort);
@@ -75,6 +76,17 @@ void WasmStreamingObject::New(const FunctionCallbackInfo<Value>& args) {
7576
new WasmStreamingObject(env, args.This());
7677
}
7778

79+
void WasmStreamingObject::SetURL(const FunctionCallbackInfo<Value>& args) {
80+
WasmStreamingObject* obj;
81+
ASSIGN_OR_RETURN_UNWRAP(&obj, args.Holder());
82+
CHECK(obj->streaming_);
83+
84+
CHECK_EQ(args.Length(), 1);
85+
CHECK(args[0]->IsString());
86+
Utf8Value url(Environment::GetCurrent(args)->isolate(), args[0]);
87+
obj->streaming_->SetUrl(url.out(), url.length());
88+
}
89+
7890
void WasmStreamingObject::Push(const FunctionCallbackInfo<Value>& args) {
7991
WasmStreamingObject* obj;
8092
ASSIGN_OR_RETURN_UNWRAP(&obj, args.Holder());

src/node_wasm_web_api.h

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class WasmStreamingObject final : public BaseObject {
3333

3434
private:
3535
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
36+
static void SetURL(const v8::FunctionCallbackInfo<v8::Value>& args);
3637
static void Push(const v8::FunctionCallbackInfo<v8::Value>& args);
3738
static void Finish(const v8::FunctionCallbackInfo<v8::Value>& args);
3839
static void Abort(const v8::FunctionCallbackInfo<v8::Value>& args);

test/fixtures/crash.wasm

36 Bytes
Binary file not shown.

test/fixtures/crash.wat

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
(module (func (export "crash") unreachable))

test/parallel/test-wasm-web-api.js

+22-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ async function testRequest(handler) {
1919
const server = createServer((_, res) => handler(res)).unref().listen(0);
2020
await events.once(server, 'listening');
2121
const { port } = server.address();
22-
return fetch(`http://127.0.0.1:${port}/`);
22+
return fetch(`http://127.0.0.1:${port}/foo.wasm`);
2323
}
2424

2525
// Runs the given function both with the promise itself and as a continuation
@@ -223,4 +223,25 @@ function testCompileStreamingRejectionUsingFetch(responseCallback, rejection) {
223223
name: 'TypeError',
224224
message: /terminated/
225225
});
226+
227+
// Test "Developer-Facing Display Conventions" described in the WebAssembly
228+
// Web API specification.
229+
await testCompileStreaming(() => testRequest((res) => {
230+
// Respond with a WebAssembly module that only exports a single function,
231+
// which only contains an 'unreachable' instruction.
232+
res.setHeader('Content-Type', 'application/wasm');
233+
res.end(fixtures.readSync('crash.wasm'));
234+
}), async (modPromise) => {
235+
// Call the WebAssembly function and check that the error stack contains the
236+
// correct "WebAssembly location" as per the specification.
237+
const mod = await modPromise;
238+
const instance = new WebAssembly.Instance(mod);
239+
assert.throws(() => instance.exports.crash(), (err) => {
240+
const stack = err.stack.split(/\n/g);
241+
assert.strictEqual(stack[0], 'RuntimeError: unreachable');
242+
assert.match(stack[1],
243+
/^\s*at http:\/\/127\.0\.0\.1:\d+\/foo\.wasm:wasm-function\[0\]:0x22$/);
244+
return true;
245+
});
246+
});
226247
})().then(common.mustCall());

0 commit comments

Comments
 (0)