summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGus Caplan <me@gus.host>2022-04-23 19:23:18 -0500
committerGus Caplan <me@gus.host>2022-04-23 19:23:18 -0500
commit9627235c1325ed03eb170a3f339104e5ae72cef5 (patch)
treef1f0dd2ed74a4ba1f0d0987f59a8f33a594d934b
parentf9e0c4d5d22bb9a1bc2455c6f862e045381d2b7c (diff)
downloadnode-new-feature/wasm-streaming-handler.tar.gz
-rw-r--r--doc/api/v8.md25
-rw-r--r--lib/internal/bootstrap/pre_execution.js11
-rw-r--r--src/node_wasm_web_api.cc6
3 files changed, 36 insertions, 6 deletions
diff --git a/doc/api/v8.md b/doc/api/v8.md
index 03c8e0e957..f0210fc483 100644
--- a/doc/api/v8.md
+++ b/doc/api/v8.md
@@ -600,6 +600,31 @@ added: v8.0.0
A subclass of [`Deserializer`][] corresponding to the format written by
[`DefaultSerializer`][].
+## `v8.setWasmStreamingHandler(handler)`
+
+* `handler` {object}
+ * `get` {function}
+ * `url` {string}
+ * `set` {function}
+ * `url` {string}
+ * `buffer` {ArrayBuffer}
+ * `delete` {function}
+ * `url`
+
+```js
+import { setWasmStreamingHandler } from 'node:v8';
+import * as fs from 'node:fs/promises';
+
+setWasmStreamingHandler({
+ get: (url) => fs.readFile(`./${url}.cache`),
+ set: (url, buffer) => fs.writeFile(`./${url}.cache`, buffer),
+ delete: (url) => fs.unlink(`./${url}.cache`),
+});
+
+WebAssembly.instantiateStreaming(fetch('https://example.com/some.wasm'))
+ .then(() => {});
+```
+
## Promise hooks
The `promiseHooks` interface can be used to track promise lifecycle events.
diff --git a/lib/internal/bootstrap/pre_execution.js b/lib/internal/bootstrap/pre_execution.js
index 3724e9fb9a..08cc5807b4 100644
--- a/lib/internal/bootstrap/pre_execution.js
+++ b/lib/internal/bootstrap/pre_execution.js
@@ -246,12 +246,12 @@ function setupFetch() {
}
const handler = require('internal/v8').getWasmStreamingHandler();
- const cached = handler?.get(response.url);
+ const cached = await handler?.get(response.url);
if (cached !== undefined && cache !== null) {
if (streamState.setCompiledModuleBytes(cached)) {
return;
} else {
- handler.delete(response.url);
+ await handler.delete(response.url);
}
}
@@ -270,8 +270,13 @@ function setupFetch() {
}, (url, buffer) => {
const handler = require('internal/v8').getWasmStreamingHandler();
try {
- handler?.set(url, buffer);
+ Promise.resolve(handler?.set(url, buffer))
+ .catch((e) => {
+ const { triggerUncaughtException } = internalBinding('errors');
+ triggerUncaughtException(e, true);
+ });
} catch (e) {
+ const { triggerUncaughtException } = internalBinding('errors');
triggerUncaughtException(e, false);
}
});
diff --git a/src/node_wasm_web_api.cc b/src/node_wasm_web_api.cc
index 9a5adc0db5..ab1a3802a3 100644
--- a/src/node_wasm_web_api.cc
+++ b/src/node_wasm_web_api.cc
@@ -170,12 +170,12 @@ void WasmStreamingObject::SetCompiledModuleBytes(
size_t offset;
size_t size;
- if (LIKELY(chunk->IsArrayBufferView())) {
+ if (chunk->IsArrayBufferView()) {
Local<ArrayBufferView> view = chunk.As<ArrayBufferView>();
bytes = view->Buffer()->GetBackingStore()->Data();
offset = view->ByteOffset();
size = view->ByteLength();
- } else if (LIKELY(chunk->IsArrayBuffer())) {
+ } else if (chunk->IsArrayBuffer()) {
Local<ArrayBuffer> buffer = chunk.As<ArrayBuffer>();
bytes = buffer->GetBackingStore()->Data();
offset = 0;
@@ -183,7 +183,7 @@ void WasmStreamingObject::SetCompiledModuleBytes(
} else {
return node::THROW_ERR_INVALID_ARG_TYPE(
Environment::GetCurrent(args),
- "chunk must be an ArrayBufferView or an ArrayBuffer");
+ "buffer must be an ArrayBufferView or an ArrayBuffer");
}
bool bytes_used = obj->streaming_->SetCompiledModuleBytes(