Closed eric-hemasystems closed 1 year ago
Made some progress. There is a example execution of Spidermonkey in JS here. This seems very similar to the Ruby example here.
Also I found wasmer inspect
will list the exports and really the only export that isn't mangled is _start
and main
which leads me further to think that is the right path.
It looks like my problem before was the failure to get the wasi version to create an import object and then use that to create the instance. Once I did that I could load the wasm just fine. Furthermore calling _start
seemed to boot the Spidermonkey repl right up!
Now the problem I am having is I don't want an interactive prompt but be able to have it run a JS script. Based on the JS example I have constructed an environment with the following:
wasi_env =
Wasmer::Wasi::StateBuilder.new('js.wasm')
.arguments(%w[-f /input.js])
.map_directory('/', '.')
.finalize
There is a file in the current directory that just has 1+1
. But despite this it always seems to still give me the repl and I don't think it is executing my script. I've also tried just using the wasmer CLI to see if I can load up the spidermonkey wasm file and give it arguments to run a script but there too I always get the repl. Feels like I'm still missing something.
I'm almost there. I found there there is some difference between the Spidermonkey wasm file on WAPM vs the one the JS demo uses. It's about twice the size, the prompt is REPL prompt is different and furthermore it actually processes the arguments. If I set my environment up with:
wasi_env =
Wasmer::Wasi::StateBuilder.new('js.wasm')
.arguments(%w[-e console.log(1+1)])
.finalize
It correctly outputs 2!. Obviously I don't want to pass my script as an inline argument so want to move back to the -f
option and map a directory in. If my current directory has a script called input.js
and I run my previous environment on the new wasm file I get this:
Error: can't open /input.js: Invalid argument
js.rb:66:in `call': RuntimeError: WASI exited with code: 3 (RuntimeError)
from js.rb:66:in `<main>'
That first line is stderr from the interpreter which tells me it is seeing my argument correctly but obviously it cannot find the file even though I think I'm mapping the directory in correctly.
Any pointers are appreciated.
Nevermind. My JS file wasn't called input.js
but test.js
. Just a dumb mistake on my part. Closing this issue as it's all just me babbling but maybe if someone else in the future wants to run JS from Ruby in a sandbox this might be useful to them.
In case anybody else comes across this in the future and wants to avoid the learning curve I had a code spike of my strategy to run JS in a sandbox from Ruby can be seen at:
https://gist.github.com/eric-hemasystems/1694a226af9058c40dd4a96a94da9402
Summary
My end goal is to be able to execute JavaScript code, server-side in a sandbox from Ruby.
I'm thinking that wasi is a good approach as that offers the sandbox. There is also multiple Javascript engines that have been compiled to wasi modules on wapm such as Spidermonkey (Firefox's JS engine), QuickJS, and duktape.
When I try to load any of these wasi modules I get an error it seems related to the FS API.
Spidermonkey
Duktape
QuickJS
Am I just doing it wrong?