Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebAssembly support #45

Merged
merged 1 commit into from
Oct 21, 2018
Merged

WebAssembly support #45

merged 1 commit into from
Oct 21, 2018

Conversation

aykevl
Copy link
Member

@aykevl aykevl commented Oct 18, 2018

Work-in-progress (totally unfinished) branch for WebAssembly support.

TODO:

  • implement "append" builtin
  • generate .wasm depending on the extension
  • generate .wast depending on the extension
  • write to stdout (how?)
  • get time.Sleep / time.Now to work
  • implement runtime.alloc
  • generate glue JS/HTML
  • make sure Travis can run all tests automatically with a wasm interpreter (perhaps this one)

fixes #44

@aykevl aykevl changed the title wasm: WIP WebAssembly support Oct 18, 2018
@aykevl aykevl force-pushed the wasm branch 2 times, most recently from 2415138 to 5d87aed Compare October 19, 2018 12:42
@aykevl aykevl mentioned this pull request Oct 19, 2018
@justinclift
Copy link
Member

For the "write to stdout (how?)" item, @Xe has been developing a runtime environment for Wasm, so might be useful for implementation ideas/direction. 😄

@Xe
Copy link

Xe commented Oct 19, 2018

Oh hey!

I'd love to collaborate on this using https://github.com/Xe/olin as the runtime for server-side tinygo binaries. The host functions its tool cmd/cwa (which is the binary interface to runtime I have developed) exposes are documented here. The usage of its standard output (which was implemented for the HTTP support shown here) would be kinda like this wast:

(module
 ;; import functions from env
 (func $getStdio (import "cwa" "io_get_stdout") (result i32))
 (func $write (import "cwa" "resource_write") (param i32 i32 i32) (result i32))
 (func $close (import "cwa" "resource_close") (param i32))

 ;; memory
 (memory $mem 1)

 ;; constants
 (data (i32.const 230) "Hello, world!\n")

 (func $main (result i32)
       ;; $fd is the file descriptor of the file we're gonna open
       (local $fd i32)

       ;; $fd = $getStdio();
       (set_local $fd
                  (call $getStdio))

       ;; $write($fd, "Hello, World!\n", 14);
       (call $write
             (get_local $fd)
             (i32.const 230)
             (i32.const 14))
       (drop)

       ;; $close($fd);
       (call $close
             (get_local $fd))

       (i32.const 0))
 (export "cwa_main" (func $main)))

This also has time. I am more than willing to work with you for more runtime support, please just name what you want.

@aykevl
Copy link
Member Author

aykevl commented Oct 19, 2018

Looks like olin could be very useful for testing!
I just pushed a minimal working example of generated WebAssembly that actually runs. It gets two numbers from JavaScript, adds them in WebAssembly and returns the result to JavaScript.

The only missing thing I see so far is support for sleeping for a given duration, e.g. sleep(int64 nanoseconds). Also, the time precision isn't big enough, but I already commented on that upstream.

@justinclift
Copy link
Member

Out of curiosity, what's the file size of that minimal working example of WebAssembly?

With mainline Go... minimum file size of generated Wasm (so far) is ~2MB. 😉

@aykevl
Copy link
Member Author

aykevl commented Oct 19, 2018

Very small.

$ tinygo build -o wasm.wasm examples/wasm

$ ls -l wasm.wasm
-rwxrwxr-x 1 ayke ayke 927 okt 19 17:22 wasm.wasm*

$ tinygo build -o wasm.wasm -no-debug examples/wasm

$ ls -l wasm.wasm
-rwxrwxr-x 1 ayke ayke 221 okt 19 17:22 wasm.wasm*

(Not sure why debug info affects file size, I should investigate that one).

@justinclift
Copy link
Member

Holy crap. Whooo!!!!!

Again, you rock! 😄

@johanbrandhorst
Copy link
Member

@aykevl This is a super exciting development. Would you be interested in joining the Go WASM discussion on the Gophers Slack #webassembly channel? https://invite.slack.golangbridge.org/.

@aykevl
Copy link
Member Author

aykevl commented Oct 19, 2018

Thanks for letting me know! I've joined #webassembly.

Also, just fixed a tiny missed optimization in 3babdfd reducing .wasm size to 174 bytes (160 when compressed). But please note that this small file size is only because the entire runtime gets optimized away by LLVM as it isn't used - an equivalent C program compiled with Clang will probably end up with about the same filesize. A program that actually does something useful and needs some runtime support will probably end up in the range of a few kilobytes. A hello world perhaps half a kilobyte. The scheduler costs something like 2kB on ARM.

@deadprogram
Copy link
Member

Yeah, this is pretty incredibly awesome.

@justinclift
Copy link
Member

justinclift commented Oct 20, 2018

@aykevl With the wasm.html example, it might be better to remove the <!DOCTYPE html> as it seems to sometimes screw up Firefox with Wasm. No idea why yet though.

@aykevl
Copy link
Member Author

aykevl commented Oct 20, 2018

That's a standard DOCTYPE. If it screws up WebAssembly in Firefox, that's a bug in Firefox.

Can you give some more details on what exactly goes wrong and when?

@aykevl
Copy link
Member Author

aykevl commented Oct 20, 2018

Almost finished, I only need to get the tests to pass.

  • There appears to be an issue with Travis that I haven't investigated closely yet.
  • Locally, all tests pass except for the ones that print floats (output is garbled).

@justinclift
Copy link
Member

justinclift commented Oct 20, 2018

That's a standard DOCTYPE. If it screws up WebAssembly in Firefox, that's a bug in Firefox.

Can you give some more details on what exactly goes wrong and when?

Yeah, fully agree. I came across it when adding the files here:

That basic WebGL triangle (and it's counterpart rotating cube) seem like good intro examples for WebGL + Wasm. So I took a bit of time to get the needed bits in place to have GitHub pages serve them directly.

With my Firefox (60.2.x esr version) running on CentOS 7... the Wasm would 100% never be displayed when that doctype line was in the file, but would work fine with it removed. Was 100% repeatable every time (served locally via Caddy when developing), so I just removed it and made a mental note of the problem. Haven't investigated it any further, and wouldn't really know where to start. (nor all that interested really, I'm focused on other stuff 😉)

@justinclift
Copy link
Member

Oh as a data point, I'm pretty sure no error message was displayed on the javascript console either when it didn't work. That's the usual place to watch out for Wasm errors when executing in a browser.

@aykevl
Copy link
Member Author

aykevl commented Oct 20, 2018

Maybe leaving out the DOCTYPE triggers quirks mode which fixes a problem with the HTML or CSS?

I strongly prefer avoiding anything non-standard unless I know exactly why that is necessary - and currently I don't.
EDIT: and it works fine for me in Firefox?

@justinclift
Copy link
Member

justinclift commented Oct 21, 2018

EDIT: and it works fine for me in Firefox?

Yeah, not sure. I just noticed it at the time, and it was completely reproducible. So I made the alteration and moved on. If it crops up again, we can look into it then. 😉

@iwasaki-kenta
Copy link

iwasaki-kenta commented Nov 29, 2018

Is there any way to set func import names?

Example

//go:import _some_func
func someFunc()

@aykevl
Copy link
Member Author

aykevl commented Nov 29, 2018

Yes:

//go:linkname someFunc _some_func
func someFunc()

@iwasaki-kenta
Copy link

Yes:

//go:linkname someFunc _some_func
func someFunc()

It seems that the import would be prefixed by the package name (ex: main._some_func). Is there any way to get rid of that prefix?

Additionally, what about changing the import namespace?

@deadprogram deadprogram deleted the wasm branch January 13, 2019 14:00
ZauberNerd pushed a commit to ZauberNerd/tinygo that referenced this pull request Mar 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TinyGo and WebAssembly?
6 participants