Skip to content

Commit 46a44b3

Browse files
tniessenRafaelGSS
authored andcommitted
lib: move WebAssembly Web API into separate file
Refs: #42960 (comment) PR-URL: #42993 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com> Reviewed-By: Darshan Sen <raisinten@gmail.com>
1 parent 946f57c commit 46a44b3

File tree

3 files changed

+69
-46
lines changed

3 files changed

+69
-46
lines changed

lib/internal/bootstrap/pre_execution.js

+2-46
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ const {
55
ObjectDefineProperties,
66
ObjectDefineProperty,
77
ObjectGetOwnPropertyDescriptor,
8-
PromiseResolve,
98
SafeMap,
109
SafeWeakMap,
1110
StringPrototypeStartsWith,
@@ -26,9 +25,7 @@ const {
2625

2726
const { Buffer } = require('buffer');
2827
const {
29-
ERR_INVALID_ARG_TYPE,
3028
ERR_MANIFEST_ASSERT_INTEGRITY,
31-
ERR_WEBASSEMBLY_RESPONSE,
3229
} = require('internal/errors').codes;
3330
const assert = require('internal/assert');
3431

@@ -222,49 +219,8 @@ function setupFetch() {
222219
});
223220

224221
// The WebAssembly Web API: https://webassembly.github.io/spec/web-api
225-
internalBinding('wasm_web_api').setImplementation((streamState, source) => {
226-
(async () => {
227-
const response = await PromiseResolve(source);
228-
if (!(response instanceof lazyUndici().Response)) {
229-
throw new ERR_INVALID_ARG_TYPE(
230-
'source', ['Response', 'Promise resolving to Response'], response);
231-
}
232-
233-
const contentType = response.headers.get('Content-Type');
234-
if (contentType !== 'application/wasm') {
235-
throw new ERR_WEBASSEMBLY_RESPONSE(
236-
`has unsupported MIME type '${contentType}'`);
237-
}
238-
239-
if (!response.ok) {
240-
throw new ERR_WEBASSEMBLY_RESPONSE(
241-
`has status code ${response.status}`);
242-
}
243-
244-
if (response.bodyUsed !== false) {
245-
throw new ERR_WEBASSEMBLY_RESPONSE('body has already been used');
246-
}
247-
248-
if (response.url) {
249-
streamState.setURL(response.url);
250-
}
251-
252-
// Pass all data from the response body to the WebAssembly compiler.
253-
const { body } = response;
254-
if (body != null) {
255-
for await (const chunk of body) {
256-
streamState.push(chunk);
257-
}
258-
}
259-
})().then(() => {
260-
// No error occurred. Tell the implementation that the stream has ended.
261-
streamState.finish();
262-
}, (err) => {
263-
// An error occurred, either because the given object was not a valid
264-
// and usable Response or because a network error occurred.
265-
streamState.abort(err);
266-
});
267-
});
222+
const { wasmStreamingCallback } = require('internal/wasm_web_api');
223+
internalBinding('wasm_web_api').setImplementation(wasmStreamingCallback);
268224
}
269225

270226
// TODO(aduh95): move this to internal/bootstrap/browser when the CLI flag is

lib/internal/wasm_web_api.js

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
'use strict';
2+
3+
const {
4+
PromiseResolve,
5+
} = primordials;
6+
const {
7+
ERR_INVALID_ARG_TYPE,
8+
ERR_WEBASSEMBLY_RESPONSE,
9+
} = require('internal/errors').codes;
10+
11+
let undici;
12+
function lazyUndici() {
13+
return undici ??= require('internal/deps/undici/undici');
14+
}
15+
16+
// This is essentially an implementation of a v8::WasmStreamingCallback, except
17+
// that it is implemented in JavaScript because the fetch() implementation is
18+
// difficult to use from C++. See lib/internal/bootstrap/pre_execution.js and
19+
// src/node_wasm_web_api.cc that interact with this function.
20+
function wasmStreamingCallback(streamState, source) {
21+
(async () => {
22+
const response = await PromiseResolve(source);
23+
if (!(response instanceof lazyUndici().Response)) {
24+
throw new ERR_INVALID_ARG_TYPE(
25+
'source', ['Response', 'Promise resolving to Response'], response);
26+
}
27+
28+
const contentType = response.headers.get('Content-Type');
29+
if (contentType !== 'application/wasm') {
30+
throw new ERR_WEBASSEMBLY_RESPONSE(
31+
`has unsupported MIME type '${contentType}'`);
32+
}
33+
34+
if (!response.ok) {
35+
throw new ERR_WEBASSEMBLY_RESPONSE(
36+
`has status code ${response.status}`);
37+
}
38+
39+
if (response.bodyUsed !== false) {
40+
throw new ERR_WEBASSEMBLY_RESPONSE('body has already been used');
41+
}
42+
43+
if (response.url) {
44+
streamState.setURL(response.url);
45+
}
46+
47+
// Pass all data from the response body to the WebAssembly compiler.
48+
const { body } = response;
49+
if (body != null) {
50+
for await (const chunk of body) {
51+
streamState.push(chunk);
52+
}
53+
}
54+
})().then(() => {
55+
// No error occurred. Tell the implementation that the stream has ended.
56+
streamState.finish();
57+
}, (err) => {
58+
// An error occurred, either because the given object was not a valid
59+
// and usable Response or because a network error occurred.
60+
streamState.abort(err);
61+
});
62+
}
63+
64+
module.exports = {
65+
wasmStreamingCallback
66+
};

test/parallel/test-bootstrap-modules.js

+1
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ const expectedModules = new Set([
140140
'NativeModule internal/util/types',
141141
'NativeModule internal/validators',
142142
'NativeModule internal/vm/module',
143+
'NativeModule internal/wasm_web_api',
143144
'NativeModule internal/webstreams/adapters',
144145
'NativeModule internal/webstreams/compression',
145146
'NativeModule internal/webstreams/encoding',

0 commit comments

Comments
 (0)