tinygo icon indicating copy to clipboard operation
tinygo copied to clipboard

Building WASM artifacts with a tinygo library?

Open simar7 opened this issue 4 years ago • 12 comments

Is it possible to build a wasm module through a library method? In other words:

Current scenario:

tinygo build -o wasm/sum.wasm -target wasm wasm/sum.go

Ideal Scenario:

mod, _ := tinygo.BuildWasm("wasm/sum.go")

Where mod is a []bytes that can be used.

simar7 avatar Jul 29 '21 02:07 simar7

I suspect that running tinygo as a library would be a bridge too far (too much work) due to the dependency on LLVM.

codefromthecrypt avatar Sep 07 '22 08:09 codefromthecrypt

This is certainly possible, but would mean some amount of refactoring. @simar7 can you explain why you want to do this?

aykevl avatar Sep 08 '22 15:09 aykevl

Sorry it's been a while, but my original motivation was to programmatically build stuff rather than exec a tinygo process.

Let me know if there's any interest in pursuing this. If so, happy to contribute if shown the ropes on how to do so.

simar7 avatar Sep 08 '22 19:09 simar7

FWIW its worth I'm also interested in a go -> wasi embeddable compiler that can be used within an application. LLVM wasn't a huge concern.

I have a few projects where I want a plugin system that can be language agnostic (yay wasi) but need a way to compile source to wasm; ideally without external dependencies.

james-lawrence avatar Sep 10 '22 14:09 james-lawrence

"ideally without external dependencies." I guess that means post any artifacts/shared libs implied by LLVM, wasi-libc, etc as attachments to a release tag (*arch/os) like how wasmtime includes their 45-70MB shared libs, right? https://github.com/bytecodealliance/wasmtime-go/commit/be70ab331d28cb63d2118c80d5293157e01534c0

codefromthecrypt avatar Sep 11 '22 23:09 codefromthecrypt

@codefromthecrypt sorry that was a confusing comment. I didn't mean in my application I mean for the code running in the wasi environment provided by my application.

james-lawrence avatar Sep 12 '22 01:09 james-lawrence

Gotcha, but let me make sure.

You have a wasm+wasi runner defined in Go. Right now, it depends on offline compilation of wasm (or forking a tinygo process). You'd prefer to use tinygo as a library in the runner, so it can compile source to wasm on-demand.

Is that right?

codefromthecrypt avatar Sep 12 '22 01:09 codefromthecrypt

precisely.

james-lawrence avatar Sep 12 '22 01:09 james-lawrence

cool, so I think unless my technical assessment is off (often is) the runner (wasm host) would import a tinygo library, but in doing so need to somehow get access to some non-go artifacts to work, and one way is to attach them to a release. That said, if a feature like this is developed, those developing it can defer details like this until the idea works in general.

codefromthecrypt avatar Sep 12 '22 01:09 codefromthecrypt

@simar7 can you explain why you need it to be a library rather than an external command?

aykevl avatar Sep 14 '22 13:09 aykevl

@simar7 can you explain why you need it to be a library rather than an external command?

There's nothing wrong with running an external command. In fact that's what I ended up doing for the time being to get traction.

From a security POV, I just find a little less appealing to shell out an external process. If ran through a library call at least I can be somewhat sure that someone will not swap the code that actually gets run under the rug, such as with an exec.

Of course nothing is perfectly safe, library dependencies can be hijacked too.

The other aspect would be testability of code. Injecting test doubles for a library based code base is subjectively easier than one that touches the system with external calls.

Just my 2¥

simar7 avatar Sep 15 '22 00:09 simar7

Right, I see. Thank you for the clarification.

From a security POV, I just find a little less appealing to shell out an external process. If ran through a library call at least I can be somewhat sure that someone will not swap the code that actually gets run under the rug, such as with an exec.

Unfortunately, that wouldn't help you here. TinyGo itself also runs external commands, for various reasons:

  • It runs itself for linking and for compiling C code, because Clang and LLD do sometimes use global state (yuck!). By invoking itself as a separate process, this use of global state does not lead to crashes.
  • It runs wasm-opt to optimize WebAssembly code and for Asyncify.

aykevl avatar Sep 15 '22 09:09 aykevl