assemblyscript
assemblyscript copied to clipboard
`env` module isn't imported, using `moduleImports` and `--importMemory` together
Bug description
moduleImpors(cases where @external
or declare
are used) together with the --importMemory
flag, the glue code does not include the imports of the env
module.
e.g. build assembly/index.ts
with the following settings in asconfig.json
.
{
"targets": {
"release": {
"outFile": "build/release.wasm",
"textFile": "build/release.wat",
"sourceMap": true,
"converge": false,
"noAssert": true
}
},
"options": {
"bindings": "raw",
"runtime": "minimal",
"importMemory": true
}
}
@external("app", "add")
declare function add(a: i32, b: i32): i32;
export function run(): void {
add(1, 2);
}
Wasm expects imports for app.add
and env.memory
, but in the actual generated build/release.js
, only the app
module is imported, and the import for the env
module is missing.
(module
(type $0 (func (param i32 i32) (result i32)))
(type $1 (func))
(import "env" "memory" (memory $0 0))
(import "app" "add" (func $assembly/index/add (param i32 i32) (result i32)))
(table $0 1 1 funcref)
(elem $0 (i32.const 1))
(export "run" (func $assembly/index/run))
(export "memory" (memory $0))
(func $assembly/index/run
i32.const 1
i32.const 2
call $assembly/index/add
drop
)
)
export async function instantiate(module, imports = {}) {
const __module0 = imports.app;
const adaptedImports = {
app: __module0,
};
const { exports } = await WebAssembly.instantiate(module, adaptedImports);
return exports;
}
While changing app.add
to env.add
can circumvent this issue, the desired outcome is to control the size of the memory from outside Wasm.
So, the expectation is for code similar to the following to be generated.
export async function instantiate(module, imports = {}) {
const __module0 = imports.app;
const adaptedImports = {
app: __module0,
+ env: Object.assign(Object.create(globalThis), imports.env || {}),
};
const { exports } = await WebAssembly.instantiate(module, adaptedImports);
return exports;
}
Steps to reproduce
asconfig.json
{
"targets": {
"release": {
"outFile": "build/release.wasm",
"textFile": "build/release.wat",
"sourceMap": true,
"converge": false,
"noAssert": true
}
},
"options": {
"bindings": "raw",
"runtime": "minimal",
"importMemory": true
}
}
assembly/index.ts
@external("app", "add")
declare function add(a: i32, b: i32): i32;
export function run(): void {
add(1, 2);
}
index.js
import { instantiate } from "./build/release.js";
const exports = await instantiate(await WebAssembly.compileStreaming(fetch(new URL("./build/release.wasm", import.meta.url))), {
app: {
add(a: number, b: number) {
return a + b;
},
},
env: {
memory: new WebAssembly.Memory({
initial: 1,
maximum: 1,
}),
},
});
exports.run();
[!CAUTION]
error: Uncaught (in promise) TypeError: WebAssembly.instantiate(): Import #1 module="env": module is not an object or function const { exports } = await WebAssembly.instantiate(module, adaptedImports); ^
AssemblyScript version
v0.27.24