I'd like to write some server-side AssemblyScript that uses the WASI interface to read a file and process the contents.
I know that AssemblyScript and the ByteCode Alliance have recently had a falling out over the "openness" of the WASI standard, but I was hoping that they would still play nicely together...
I've found several AssemblyScript tools/libraries that appear to bridge this gap, and the one that seems the simplest to use is as-wasi
. After following the installation instructions, I'm just trying to run the little demo app.
All the VSCode design time errors have disappeared, but the AssemblyScript compiler still barfs at the initial import
statement.
import "wasi"
import { Console, Environ } from "as-wasi/assembly";
// Create an environ instance
let env = new Environ();
// Get the HOME Environment variable
let home = env.get("HOME")!;
// Log the HOME string to stdout
Console.log(home);
Running npm run asbuild
gives.
$ npm run asbuild
> file_reader@1.0.0 asbuild
> npm run asbuild:debug && npm run asbuild:release
> file_reader@1.0.0 asbuild:debug
> asc assembly/index.ts --target debug
ERROR TS6054: File '~lib/wasi.ts' not found.
:
1 │ import "wasi"
│ ~~~~~~
└─ in assembly/index.ts(1,8)
FAILURE 1 parse error(s)
The file ~lib/wasi.ts
does not exist and creating this file as a softlink pointing to the index.ts
in the ./node_modules/as-wasi/assembly/
directory makes no difference.
Since the library is called as-wasi
and not wasi
, I've tried importing as-wasi
, but this also fails.
I've also tried adapting tsconfig.json
to include
{
"extends": "assemblyscript/std/assembly.json",
"include": [
"../node_modules/as-wasi/assembly/*.ts",
"./**/*.ts"
]
}
But this also has no effect.
What is causing asc
to think that the required library should be in the directory called ~lib/
and how should I point it to the correct place?
Thanks
Your question threw me in a bit of a rabbit hole, but I think I solved it.
So, apparently, after the wasi schism, AssemblyScript added the wasi-shim repository, that you have to install as well:
npm install --save wasi-shim
The import "wasi"
is no longer necessary after version 0.20 of AssemblyScript according to the same page, so you have to remove that import entirely. Also, be sure to add the extends
to your asconfig.json
, as recommended in the same wasi-shim
page. Mine looks like this:
{
"extends": "./node_modules/@assemblyscript/wasi-shim/asconfig.json",
"targets": {
"debug": {
"outFile": "build/debug.wasm",
"textFile": "build/debug.wat",
"sourceMap": true,
"debug": true
},
"release": {
"outFile": "build/release.wasm",
"textFile": "build/release.wat",
"sourceMap": true,
"optimizeLevel": 3,
"shrinkLevel": 0,
"converge": false,
"noAssert": false
}
},
"options": {
"bindings": "esm"
}
}
It is just the generated original asconfig.json
plus that extends
.
Now the things got interesting. I got a compilation error:
ERROR TS2300: Duplicate identifier 'wasi_abort'.
:
1100 │ export function wasi_abort(
│ ~~~~~~~~~~
└─ in ~lib/as-wasi/assembly/as-wasi.ts(1100,17)
:
19 │ export function wasi_abort(
│ ~~~~~~~~~~
└─ in ~lib/wasi_internal.ts(19,17)
So I investigated, and it seems that as-wasi
was exporting a symbol that was the same as a symbol exported by wasi_shim
. No biggie, I went into node_modules/as-wasi/
, and I renamed that function into as_wasi_abort
. I did this also with the invokations of the function, namely three instances found in the package.json
from as-wasi
:
{
"asbuild:untouched": "asc assembly/index.ts -b build/untouched.wasm -t build/untouched.wat --use abort=as_wasi_abort --debug",
"asbuild:small": "asc assembly/index.ts -b build/optimized.wasm -t build/optimized.wat --use abort=as_wasi_abort -O3z ",
"asbuild:optimized": "asc assembly/index.ts -b build/optimized.wasm -t build/optimized.wat --use abort=as_wasi_abort -O3",
}
Having done all this, the package compiled and the example from Wasm By Example finally worked.
Your code should compile now, and I will try to make a pull request to all the places necessary so that the examples are updated, the code in as-wasi
is updated, and so that nobody has to go through this again. Please comment if there are further problems.
Edit: It seems that I was right about the wasi_abort
function being a problem. It is actually removed on the as-wasi
repo, but the npm package is outdated. I asked in my pull request for it to be updated.