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

Open
wants to merge 3 commits into
base: master
from

Conversation

Projects
None yet
4 participants
@damz
Contributor

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

This comment has been minimized.

Show comment
Hide comment
@slimsag

slimsag Oct 3, 2018

Member

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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@damz

damz Oct 3, 2018

Contributor

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

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@damz

damz Oct 3, 2018

Contributor

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

Contributor

damz commented Oct 3, 2018

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

@slimsag

This comment has been minimized.

Show comment
Hide comment
@slimsag

slimsag Oct 3, 2018

Member

@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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@dmitshur

dmitshur Oct 3, 2018

Member

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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@damz

damz Oct 3, 2018

Contributor

@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.

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@damz

damz Oct 4, 2018

Contributor

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

Contributor

damz commented Oct 4, 2018

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

@gedw99 gedw99 referenced this pull request Oct 5, 2018

Open

WebAssembly support #211

@slimsag

This comment has been minimized.

Show comment
Hide comment
@slimsag

slimsag Oct 14, 2018

Member

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?

Member

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

This comment has been minimized.

Show comment
Hide comment
@progrium

progrium 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.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment