diff options
author | Tobias Nießen <tniessen@tnie.de> | 2022-04-23 06:09:15 +0300 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2022-04-28 07:57:22 +0300 |
commit | b0f7c4c8f928597f2118dde73c98ac0fba8f01f9 (patch) | |
tree | 05d1cf273c607c243275988b2236a69b9607729f /lib | |
parent | c6c1dc58335f08b52139a0692502486bcb8b6ea0 (diff) |
lib,src: implement WebAssembly Web API
Refs: https://github.com/nodejs/node/pull/41749
Fixes: https://github.com/nodejs/node/issues/21130
PR-URL: https://github.com/nodejs/node/pull/42701
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/internal/bootstrap/pre_execution.js | 45 | ||||
-rw-r--r-- | lib/internal/errors.js | 1 |
2 files changed, 45 insertions, 1 deletions
diff --git a/lib/internal/bootstrap/pre_execution.js b/lib/internal/bootstrap/pre_execution.js index b64dfaf980f..e1b882b6dbe 100644 --- a/lib/internal/bootstrap/pre_execution.js +++ b/lib/internal/bootstrap/pre_execution.js @@ -5,6 +5,7 @@ const { ObjectDefineProperties, ObjectDefineProperty, ObjectGetOwnPropertyDescriptor, + PromiseResolve, SafeMap, SafeWeakMap, StringPrototypeStartsWith, @@ -24,7 +25,11 @@ const { } = require('internal/util'); const { Buffer } = require('buffer'); -const { ERR_MANIFEST_ASSERT_INTEGRITY } = require('internal/errors').codes; +const { + ERR_INVALID_ARG_TYPE, + ERR_MANIFEST_ASSERT_INTEGRITY, + ERR_WEBASSEMBLY_RESPONSE, +} = require('internal/errors').codes; const assert = require('internal/assert'); function prepareMainThreadExecution(expandArgv1 = false, @@ -215,6 +220,44 @@ function setupFetch() { Request: lazyInterface('Request'), Response: lazyInterface('Response'), }); + + // The WebAssembly Web API: https://webassembly.github.io/spec/web-api + internalBinding('wasm_web_api').setImplementation((streamState, source) => { + (async () => { + const response = await PromiseResolve(source); + if (!(response instanceof lazyUndici().Response)) { + throw new ERR_INVALID_ARG_TYPE( + 'source', ['Response', 'Promise resolving to Response'], response); + } + + const contentType = response.headers.get('Content-Type'); + if (contentType !== 'application/wasm') { + throw new ERR_WEBASSEMBLY_RESPONSE( + `has unsupported MIME type '${contentType}'`); + } + + if (!response.ok) { + throw new ERR_WEBASSEMBLY_RESPONSE( + `has status code ${response.status}`); + } + + if (response.bodyUsed !== false) { + throw new ERR_WEBASSEMBLY_RESPONSE('body has already been used'); + } + + // Pass all data from the response body to the WebAssembly compiler. + for await (const chunk of response.body) { + streamState.push(chunk); + } + })().then(() => { + // No error occurred. Tell the implementation that the stream has ended. + streamState.finish(); + }, (err) => { + // An error occurred, either because the given object was not a valid + // and usable Response or because a network error occurred. + streamState.abort(err); + }); + }); } // TODO(aduh95): move this to internal/bootstrap/browser when the CLI flag is diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 1dfa36e5f36..d5bb5023a79 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -1659,6 +1659,7 @@ E('ERR_VM_MODULE_NOT_MODULE', 'Provided module is not an instance of Module', Error); E('ERR_VM_MODULE_STATUS', 'Module status %s', Error); E('ERR_WASI_ALREADY_STARTED', 'WASI instance has already started', Error); +E('ERR_WEBASSEMBLY_RESPONSE', 'WebAssembly response %s', TypeError); E('ERR_WORKER_INIT_FAILED', 'Worker initialization failure: %s', Error); E('ERR_WORKER_INVALID_EXEC_ARGV', (errors, msg = 'invalid execArgv flags') => `Initiated Worker with ${msg}: ${ArrayPrototypeJoin(errors, ', ')}`, |