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

Add support for WebAssembly #215

Closed
wants to merge 3 commits into from
Closed

Add support for WebAssembly #215

wants to merge 3 commits into from

Conversation

damz
Copy link
Contributor

@damz damz commented Oct 3, 2018

This is a fully working implementation of WebAssembly support in Vecty.

The really nice thing here is that a given code base can be compiled to JavaScript or to WebAssembly with barely any change (the only thing absolutely necessary is to add a select {} at the end of main for the WebAssembly version).

But there are a number of obvious problems for discussion:

  • This replaces github.com/gopherjs/gopherjs/js with github.com/gopherjs/gopherwasm/js, and as a consequence introduces a large BC break;
  • The new-style javascript interface (syscall/js and github.com/gopherjs/gopherwasm/js) does not have a way to call a Callback synchronously, which the test suite hacks around by sleeping for 10ms (runtime.Gosched() is not enough);
  • github.com/gopherjs/gopherwasm/js doesn't have the minimum support for native (i.e. non-gopherjs and non-wasm) builds, so the test suite fails under go test (but it passes under both GOOS=js GOARCH=wasm go test and under gopherjs test).

@slimsag
Copy link
Member

@slimsag slimsag commented Oct 3, 2018

Nice, thanks for sending this! Hoping I'll have time to review this soon (midnight here, and quite busy in general at work).

One thing that immediately pops out to me: I think instead of using github.com/gopherjs/gopherwasm/js we should probably use build tags instead to avoid breaking existing GopherJS users and at the same time support WASM users.

@damz
Copy link
Contributor Author

@damz damz commented Oct 3, 2018

@slimsag That's is unfortunately not going to help, given that the code base already references "github.com/gopherjs/gopherjs/js".Object explicitly.

@damz
Copy link
Contributor Author

@damz damz commented Oct 3, 2018

(Note that gopherjs test is currently broken in Travis CI because of gopherjs/gopherjs#865.)

@slimsag
Copy link
Member

@slimsag slimsag commented Oct 3, 2018

@damz I am aware that Node returns a js.Object explicitly. My point is that with build tags, that could remain the case for GopherJS and not the case for wasm.

@dmitshur
Copy link
Contributor

@dmitshur dmitshur commented Oct 3, 2018

My point is that with build tags, that could remain the case for GopherJS and not the case for wasm.

That would mean the vecty API is different for GopherJS and Wasm, so users would need to change their code (how they use vecty) depending on whether they want to compile with GopherJS or Wasm. That wouldn't be great.

It works best when when the package API is pure Go, and github.com/gopherjs/gopherjs/js, syscall/js packages are not a part of that API surface. That way, it's an implementation difference that stays completely internal to your package.

I don't know if it's viable to achieve that with vecty, but I just wanted to share these observations. In the case of honnef.co/go/js/dom, we could only do it by changing its API.

@damz
Copy link
Contributor Author

@damz damz commented Oct 3, 2018

@dmitshur Agreed, even examples/todomvc inside the repository relies on HTML.Node(). This probably wants to become an interface somehow, but note that the "github.com/gopherjs/gopherjs/js".Object have additional magic (notably the struct tagging) that the new "syscall/js".Value do not have.

@damz
Copy link
Contributor Author

@damz damz commented Oct 4, 2018

FWIW, I uploaded a demo of the Markdown example compiled to WebAssembly.

@ghost ghost mentioned this pull request Oct 5, 2018
@slimsag
Copy link
Member

@slimsag slimsag commented Oct 14, 2018

That would mean the vecty API is different for GopherJS and Wasm, so users would need to change their code (how they use vecty) depending on whether they want to compile with GopherJS or Wasm. That wouldn't be great.

@dmitshur I am aware this would be the case. I am approaching this with the assumption that mid to long term, everyone will be switching over to Go's native WebAssembly support and away from GopherJS, but I suppose that could be an invalid assumption on my part.

One fact that will likely always be true is that Vecty must expose some sort of access to the underlying DOM nodes, i.e. our public API will always have some way to get a js.Object.

If my assumption is right and GopherJS will eventually go away, I think exposing something like gopherwasm through our API makes Vecty less pure in the sense that it will try to support both GopherJS and WebAssembly. In this situation, I would rather offer what I consider to be a more clean API without using gopherwasm.

If my assumption is wrong and GopherJS will stay around e.g. even once Go 2 comes out, I think exposing gopherwasm would be the right choice (or, GopherJS should eventually just hook the syscall/js package and Vecty could expose that, kind of like how net/http works in GopherJS).

So I think the deciding answer for me boils down to the question: What is the future of GopherJS vs. WebAssembly?

@progrium
Copy link

@progrium progrium commented Oct 14, 2018

As somebody that was intrigued by GopherJS, I never actually wanted to use it. With WebAssembly, I'm all over it. There are obviously differences in the details that I'm sure GopherJS people might prefer it, but from my point of view as a GopherJS outsider, with WebAssembly there is no reason for GopherJS. In fact, it's possible with some of the work we've been doing on top of the WebAssembly port, Vecty will become more popular focusing on WebAssembly.

@slimsag
Copy link
Member

@slimsag slimsag commented Oct 18, 2018

@dmitshur @damz any thoughts / opinions here given my last message? (I am aiming to land WebAssembly support over the weekend, if possible, due to high demand for it in general)

@myitcv
Copy link

@myitcv myitcv commented Oct 18, 2018

@slimsag you might like to consider waiting for https://go-review.googlesource.com/c/go/+/142004 to land first?

@slimsag
Copy link
Member

@slimsag slimsag commented Oct 20, 2018

@myitcv thanks for the link. Yeah, I agree, given that is likely to change our implementation significantly. It also seems others here haven't quite had a chance to give input on my last message (or they don't wish to); I'll wait a bit longer for now.

I am still currently leaning towards "GopherJS will one day go away (so we should expose a pure non-gopherjswasm API)"

@ghost
Copy link

@ghost ghost commented Dec 13, 2018

To answer your call for responses.
I would prefer ecty to run inside wasm.
In effect allowing me to output html directly over post message to the window thread.
I don't want vecty running in gopherjs.
This gets things much faster and make the window a single plain of html with a little bit of js for any interactivity.

The conceptual model relies on accepting a wasm web worker being a Server, and the window being the client.
The wasm worker is doing everything and streaming out html through the post message !
Now the multi threading is formalised in that the window has its own thread. I know that the wasm and golang wasm have some significant architecture problems but that's another problem outside of vecty.

The question as to if gopherjs can be used in the window should be addressed. I am finding it useful for small interactive things like gathering form data etc or special UX effects.

@slimsag
Copy link
Member

@slimsag slimsag commented Jan 20, 2019

It's been a while (too long) and I think the correct decision is likely to be supporting WebAssembly and GopherJS under separate build tags for the reasons outlined in my prior comment. I will work on adding support for WebAssembly using this approach.

Also, I don't know for certain yet, but I suspect my prior statement to be more true given recent discussion around sunsetting GopherJS here: gopherjs/gopherjs#855 (comment)

Some of this sparks questions for me about whether or not Vecty should live under the GopherJS organization long-term, file #230 for discussing that.

@slimsag
Copy link
Member

@slimsag slimsag commented Jan 21, 2019

I've sent #232 which will supersede this PR by implementing the alternative approach I mentioned in my comments above.

@slimsag slimsag closed this Jan 21, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants