I found this project https://mbbill.github.io/JSC.js/ that is a web assembly compilation of javascript core. It only has a few functions that I think I can pull out of the c++(code at https://github.com/mbbill/JSC.js/tree/master/Source/JavaScriptCore) the main functions that I need. So I think I have the wasm and the js that I’d need to run the thing(basically it pushes a js string into the engine, executes it, and reads out the results with a couple of memory allocation functions along the way.). I think those are js_eval, stackAlloc, stackRestore, stackSave…maybe some others.
I understand that this is a terrible idea, and that running a js engine on top of wasm defeats the point of having a wasm engine…but I want to try it anyway just so that I can say that I can. There is a lot of js code out there and it might be interesting to push out canisters that do needed things without having to do a rewrite.
Anyway the function signatures look pretty simple…basically just char* and integers of various sizes, but I don’t really have any clue where to start with the candid files and what is/isn’t important to implement. Any suggestions? Anyone want to help me with it?
To interoperate on the Internet Computer, the canister needs to understand the system API and the Candid serialization format. It cannot run an arbitrary Wasm module. To get started, I would recommend checking out the reverse example in C: https://github.com/dfinity/examples/blob/master/c/reverse/reverse.c
It contains the minimal bindings needed to reverse a string from a canister. Your Wasm module needs to somehow embed these APIs as well in order to run on the Internet Computer.
So made some progress on this and decided to try to go with the duktape project to try to get something to work. I’m using the basic reverse.c example but I moved over the duktape.h and duktape.c files into the directory and changed the function to try to call something out of this. It turns out that the reason it can’t compile is that it can’t see the standard libraries for some reason.
root@ad0ec66809cb:/usr/src/examples/c/reverse# wcc reverse.c
In file included from reverse.c:1:
In file included from ./duktape.h:196:
./duk_config.h:865:10: fatal error: 'time.h' file not found
#include <time.h>
^~~~~~~~
1 error generated.
time.h is in /usr/include. Do I need to do something to tell the compiler to look there?
I’m currently running clang-11 --target=wasm32 -c -O reverse.c
So a bit of progress! I got things to compile, but when trying to install the canister I get the following:
Installing code for canister reverse, with canister_id 75hes-oqbaa-aaaaa-aaaaa-aaaaa-aaaaa-aaaaa-q
Replica error (code 5): IC0504: Canister 75hes-oqbaa-aaaaa-aaaaa-aaaaa-aaaaa-aaaaa-q violated contract: Module imports function ‘duk_create_heap’ from ‘env’ that is not exported by the runtime.
I’m guessing what I need is to better understand what all of these do:
I’m guessing I need to import the duk_create_heap function to some other different name and call it that way? But I’ve tried this a couple different ways and received the compiler error:
reverse.c:23:16: error: initializing ‘duk_context *’ (aka ‘struct duk_hthread *’) with an expression of incompatible type ‘void’
duk_context *ctx = dfx_js_create_heap_default();
This error means duk_create_heap is not linked in the Wasm module, so it expects the system to provide the imports, which doesn’t exist.
I don’t know how duktape works, but the problem is probably that they are not compiled properly in Wasm. I suggest you first try to compile a wasm module that can be instantiated in browser or WASI, then try to port it to IC. The porting to IC would be similar to the reverse.c example, where it puts wasm_import and candid bindings.