Skip to content

Commit d6a55af

Browse files
committed
wasm: add instantiateStreaming support
This commit adds InstantiateStreaming support to allow for some compatability with Web browser environments. Refs: nodejs#21130
1 parent 0257fd7 commit d6a55af

File tree

5 files changed

+66
-0
lines changed

5 files changed

+66
-0
lines changed

src/env.h

+2
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ struct PackageConfig {
194194
V(message_port_string, "messagePort") \
195195
V(message_port_constructor_string, "MessagePort") \
196196
V(minttl_string, "minttl") \
197+
V(module_string, "Module") \
197198
V(modulus_string, "modulus") \
198199
V(name_string, "name") \
199200
V(netmask_string, "netmask") \
@@ -288,6 +289,7 @@ struct PackageConfig {
288289
V(valid_from_string, "valid_from") \
289290
V(valid_to_string, "valid_to") \
290291
V(value_string, "value") \
292+
V(webassembly_string, "WebAssembly") \
291293
V(verify_error_string, "verifyError") \
292294
V(version_string, "version") \
293295
V(weight_string, "weight") \

src/node.cc

+32
Original file line numberDiff line numberDiff line change
@@ -3732,6 +3732,37 @@ bool AllowWasmCodeGenerationCallback(
37323732
return wasm_code_gen->IsUndefined() || wasm_code_gen->IsTrue();
37333733
}
37343734

3735+
void WasmCreateModule(const FunctionCallbackInfo<Value>& info) {
3736+
Environment* env = Environment::GetCurrent(info.GetIsolate());
3737+
Local<Context> context = env->context();
3738+
Local<Value> buffer = info[0];
3739+
CHECK(!buffer.IsEmpty());
3740+
3741+
Local<Object> wasm = Local<Object>::Cast(
3742+
context->Global()->Get(context, env->webassembly_string())
3743+
.ToLocalChecked());
3744+
Local<Function> module = Local<Function>::Cast(wasm->Get(context,
3745+
env->module_string()).ToLocalChecked());
3746+
Local<Value> args[] = {buffer};
3747+
Local<Value> module_instance = module->NewInstance(context, 1, args)
3748+
.ToLocalChecked();
3749+
info.GetReturnValue().Set(module_instance);
3750+
}
3751+
3752+
void WasmInstantiateStreamingCallback(const FunctionCallbackInfo<Value>& info) {
3753+
Environment* env = Environment::GetCurrent(info.GetIsolate());
3754+
Local<Context> context = env->context();
3755+
CHECK(!info[0]->IsUndefined());
3756+
CHECK(info[0]->IsPromise());
3757+
Local<Promise> buffer_promise = info[0].As<Promise>();
3758+
3759+
Local<Function> create_module = Function::New(context, WasmCreateModule)
3760+
.ToLocalChecked();
3761+
Local<Promise> module_promise = buffer_promise->Then(context, create_module)
3762+
.ToLocalChecked();
3763+
info.GetReturnValue().Set(module_promise);
3764+
}
3765+
37353766
Isolate* NewIsolate(ArrayBufferAllocator* allocator) {
37363767
Isolate::CreateParams params;
37373768
params.array_buffer_allocator = allocator;
@@ -3748,6 +3779,7 @@ Isolate* NewIsolate(ArrayBufferAllocator* allocator) {
37483779
isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
37493780
isolate->SetFatalErrorHandler(OnFatalError);
37503781
isolate->SetAllowWasmCodeGenerationCallback(AllowWasmCodeGenerationCallback);
3782+
isolate->SetWasmCompileStreamingCallback(WasmInstantiateStreamingCallback);
37513783

37523784
return isolate;
37533785
}
56 Bytes
Binary file not shown.
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
;; $ wat2wasm instantiate_streaming.wat -o instantiate_streaming.wasm
2+
(module
3+
(func $add (import "test" "add") (param i32) (param i32) (result i32))
4+
(func (export "add") (param i32) (param i32) (result i32)
5+
get_local 0
6+
get_local 1
7+
call $add
8+
)
9+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'use strict';
2+
3+
// This test verifies that instantiateStreaming can be used with node.
4+
5+
require('../common');
6+
const assert = require('assert');
7+
const fixtures = require('../common/fixtures');
8+
const fs = require('fs');
9+
10+
const promise = fs.promises.readFile(
11+
fixtures.path('instantiate_streaming.wasm'));
12+
13+
// Using an import object just to verify that this works without anything
14+
// needed to be specifically implemented for it to work.
15+
const importObject = {
16+
test: {
17+
add: (arg1, arg2) => arg1 + arg2
18+
},
19+
}
20+
21+
WebAssembly.instantiateStreaming(promise, importObject).then((results) => {
22+
assert.strictEqual(results.instance.exports.add(2, 3), 5);
23+
});

0 commit comments

Comments
 (0)