Clang driver: can target wasm32 but can't look up symbols? (original) (raw)

Hi,

I am developing a library that compiles some basic C code before running it. It all works fine when targetting X86 and AArch64, but not when targetting wasm32. It looks like I am able to compile that basic C code for wasm32, but I am not able to look up its symbols and therefore to run it.

In my browser’s console, I am getting:

libopencor.js:8 >>> Compiler::function("initialiseVariables")
libopencor.js:8      - Looking up 'initialiseVariables'...
libopencor.js:8 LLVM ERROR: section already has a defining function: .text.initialiseVariables
put_char @ libopencor.js:8
libopencor.js:8 Aborted()
abort @ libopencor.js:8
libopencor.js:8 Uncaught (in promise) RuntimeError: Aborted(). Build with -sASSERTIONS for more info.
    at abort (libopencor.js:8:6013)
    at _abort (libopencor.js:8:133020)
    at libopencor.wasm:0x16693f
    at libopencor.wasm:0x2589f4e
    at libopencor.wasm:0xd66725
    at libopencor.wasm:0x25782f9
    at libopencor.wasm:0x1c426bf
    at libopencor.wasm:0x25c0cce
    at libopencor.wasm:0x296f2b6
    at libopencor.wasm:0x9d071b

I imagine that I must be doing something wrong (when compiling to wasm32), but I can’t tell what it is. I tried to google for some sample code that does what I am after, but to no avail.

So:

Cheers, Alan.

dschuff June 8, 2023, 5:06pm 2

Hi Alan,
If I’m interpreting your post and the code correctly, it looks like you’re trying to compile a JIT with emscripten. This is definitely not going to be as simple for a wasm environment as it is for a desktop OS on x86 or ARM. How it will work will depend a lot on which wasm embedding you’re targeting (for example since you seem to be using emscripten, I’m assuming it’s a JS or web environment; in that case, you’ll need to use the JS embedding API to actually load and run any wasm module you generate, and there are some particulars about emscripten’s wasm/JS interface that will affect how you generate the code). So, whatever mechanisms you’re using now to load code will have to change.
Which isn’t to say it’s not possible! There are other people trying this kind of thing too. Since most of the interesting bits here are more specific to emscripten/JS than to LLVM, probably this discussion would make the most sense on the emscripten mailing list, where there might be more expertise on those things.

agarny June 8, 2023, 10:46pm 3

Hi,

Yes, my library does indeed try to compile some code on the fly using a JIT and it all works fine when my library is built for X86 or AArch64, but not when it is built for wasm32.

The wasm32 version of my library is indeed built using Emscripten to generate an ES6 module (using EXPORT_ES6), making it possible to use my library from both Node.js and from a Web browser. It all works fine, except for the fact that I cannot look up symbols and therefore run code that was compiled on the fly.

I am not sure what you mean by “us[ing] the JS embedding API to actually load and run any wasm module [I] generate” since everything is done in memory. I mean, the code I am compiling on the fly doesn’t result in a physical WASM file.

Anyway, thanks for the suggestion, I am going to ask on the Emscripten mailing list.

Alan

dschuff June 8, 2023, 11:14pm 4

This is a case where wasm is quite different from those machine architectures. It’s a “virtual” architecture in the sense that the wasm instructions are not machine code, so once you generate the instructions, you need a way to ask the host VM to compile them and load them in a form where they can be called. So for example in x86 you can just generate code in memory and then jump into it, that’s not possible in wasm.
By “JS embedding API” I mean this. In a JS engine, you can generate a complete wasm module in memory, and then compile and load it using one of those APIs (e.g. WebAssembly.instantiate()). There are certain things you’ll need to do if you want it to work with emscripten’s JS support code (i.e. the syscalls that are included with the main module). The details of that are probably best discussed on emscripten-discuss.
(AFAIK nobody has tried to make LLVM’s JIT APIs have specific support for wasm; so if there are improvements there that make sense, we could certainly discuss those here).

agarny June 8, 2023, 11:54pm 5

Thanks a lot for the clarifications, I can now see that I can’t do for wasm32 what I did for X86 and AArch64. This is really too bad, but fair enough I am going to try what you suggested and see how it goes.