mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
lib,src: use Response URL as WebAssembly location
As per Section 3 of the WebAssembly Web API spec. PR-URL: https://github.com/nodejs/node/pull/42842 Refs: https://github.com/nodejs/node/pull/42701 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This commit is contained in:
parent
f54bf2839b
commit
4f9bc41f1e
@ -245,6 +245,10 @@ function setupFetch() {
|
|||||||
throw new ERR_WEBASSEMBLY_RESPONSE('body has already been used');
|
throw new ERR_WEBASSEMBLY_RESPONSE('body has already been used');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (response.url) {
|
||||||
|
streamState.setURL(response.url);
|
||||||
|
}
|
||||||
|
|
||||||
// Pass all data from the response body to the WebAssembly compiler.
|
// Pass all data from the response body to the WebAssembly compiler.
|
||||||
for await (const chunk of response.body) {
|
for await (const chunk of response.body) {
|
||||||
streamState.push(chunk);
|
streamState.push(chunk);
|
||||||
|
@ -29,6 +29,7 @@ Local<Function> WasmStreamingObject::Initialize(Environment* env) {
|
|||||||
t->InstanceTemplate()->SetInternalFieldCount(
|
t->InstanceTemplate()->SetInternalFieldCount(
|
||||||
WasmStreamingObject::kInternalFieldCount);
|
WasmStreamingObject::kInternalFieldCount);
|
||||||
|
|
||||||
|
env->SetProtoMethod(t, "setURL", SetURL);
|
||||||
env->SetProtoMethod(t, "push", Push);
|
env->SetProtoMethod(t, "push", Push);
|
||||||
env->SetProtoMethod(t, "finish", Finish);
|
env->SetProtoMethod(t, "finish", Finish);
|
||||||
env->SetProtoMethod(t, "abort", Abort);
|
env->SetProtoMethod(t, "abort", Abort);
|
||||||
@ -75,6 +76,17 @@ void WasmStreamingObject::New(const FunctionCallbackInfo<Value>& args) {
|
|||||||
new WasmStreamingObject(env, args.This());
|
new WasmStreamingObject(env, args.This());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WasmStreamingObject::SetURL(const FunctionCallbackInfo<Value>& args) {
|
||||||
|
WasmStreamingObject* obj;
|
||||||
|
ASSIGN_OR_RETURN_UNWRAP(&obj, args.Holder());
|
||||||
|
CHECK(obj->streaming_);
|
||||||
|
|
||||||
|
CHECK_EQ(args.Length(), 1);
|
||||||
|
CHECK(args[0]->IsString());
|
||||||
|
Utf8Value url(Environment::GetCurrent(args)->isolate(), args[0]);
|
||||||
|
obj->streaming_->SetUrl(url.out(), url.length());
|
||||||
|
}
|
||||||
|
|
||||||
void WasmStreamingObject::Push(const FunctionCallbackInfo<Value>& args) {
|
void WasmStreamingObject::Push(const FunctionCallbackInfo<Value>& args) {
|
||||||
WasmStreamingObject* obj;
|
WasmStreamingObject* obj;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&obj, args.Holder());
|
ASSIGN_OR_RETURN_UNWRAP(&obj, args.Holder());
|
||||||
|
@ -33,6 +33,7 @@ class WasmStreamingObject final : public BaseObject {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
|
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
|
static void SetURL(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
static void Push(const v8::FunctionCallbackInfo<v8::Value>& args);
|
static void Push(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
static void Finish(const v8::FunctionCallbackInfo<v8::Value>& args);
|
static void Finish(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
static void Abort(const v8::FunctionCallbackInfo<v8::Value>& args);
|
static void Abort(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
|
BIN
test/fixtures/crash.wasm
vendored
Normal file
BIN
test/fixtures/crash.wasm
vendored
Normal file
Binary file not shown.
1
test/fixtures/crash.wat
vendored
Normal file
1
test/fixtures/crash.wat
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
(module (func (export "crash") unreachable))
|
@ -19,7 +19,7 @@ async function testRequest(handler) {
|
|||||||
const server = createServer((_, res) => handler(res)).unref().listen(0);
|
const server = createServer((_, res) => handler(res)).unref().listen(0);
|
||||||
await events.once(server, 'listening');
|
await events.once(server, 'listening');
|
||||||
const { port } = server.address();
|
const { port } = server.address();
|
||||||
return fetch(`http://127.0.0.1:${port}/`);
|
return fetch(`http://127.0.0.1:${port}/foo.wasm`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Runs the given function both with the promise itself and as a continuation
|
// Runs the given function both with the promise itself and as a continuation
|
||||||
@ -223,4 +223,25 @@ function testCompileStreamingRejectionUsingFetch(responseCallback, rejection) {
|
|||||||
name: 'TypeError',
|
name: 'TypeError',
|
||||||
message: /terminated/
|
message: /terminated/
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Test "Developer-Facing Display Conventions" described in the WebAssembly
|
||||||
|
// Web API specification.
|
||||||
|
await testCompileStreaming(() => testRequest((res) => {
|
||||||
|
// Respond with a WebAssembly module that only exports a single function,
|
||||||
|
// which only contains an 'unreachable' instruction.
|
||||||
|
res.setHeader('Content-Type', 'application/wasm');
|
||||||
|
res.end(fixtures.readSync('crash.wasm'));
|
||||||
|
}), async (modPromise) => {
|
||||||
|
// Call the WebAssembly function and check that the error stack contains the
|
||||||
|
// correct "WebAssembly location" as per the specification.
|
||||||
|
const mod = await modPromise;
|
||||||
|
const instance = new WebAssembly.Instance(mod);
|
||||||
|
assert.throws(() => instance.exports.crash(), (err) => {
|
||||||
|
const stack = err.stack.split(/\n/g);
|
||||||
|
assert.strictEqual(stack[0], 'RuntimeError: unreachable');
|
||||||
|
assert.match(stack[1],
|
||||||
|
/^\s*at http:\/\/127\.0\.0\.1:\d+\/foo\.wasm:wasm-function\[0\]:0x22$/);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
});
|
||||||
})().then(common.mustCall());
|
})().then(common.mustCall());
|
||||||
|
Loading…
Reference in New Issue
Block a user