golang/go

all: WebAssembly ("wasm") support

bradfitz opened this issue Β· 147 comments

WebAssembly ("wasm") is similar to Native Client, but different notably in that other browsers plan to implement it.

http://webassembly.org/

This has been asked about a few times, so this is a tracking bug for it.

Whether we get it via cmd/compile, gccgo, or llvm-go, we can post updates here.

minux commented

From gopherjs/gopherjs#432:

However, it is not a technology that GopherJS can use. GopherJS compiles on the AST level, not on the machine code level.

WebAssembly could be used as a backend for the normal Go compiler

4ad commented

@minux The lack of threads or async i/o seems to be a bigger problem than the ABI workarounds we'd have to do because of wasm quirks.

@minux, @cherrymui
could you post somewhere in more details what you did and achieved?
as you may know the go-interpreter community is considering writing an interpreter based on either LLVM or wasm bytecode.
(we may even have a GSoC student working on the wasm bytecode interpreter [1], so, just the "bytecode consumption" part, not the "bytecode production via some Go-based toolchain" one)

minimizing the amount of duplicated efforts and impedance mismatch between various components would be great.

I highly recommend this as a strategic feature. Consider that in just a few years web programmers will flock in hordes to pick their language of choice to be compiled into web assembly. The sooner we join the race the better. Mozilla is pushing Rust hard as the web assembly language of choice...

I second what @RaananHadar said. It would be a pity if the spec didn't suit Go's needs, especially given how Go's runtime can be unique.

EDIT: Apologies for the MeToo nature of this comment :) Thanks for the pointer Brad.

The WebAssembly stack machine context consists of linear memory and an operation stack. IIUC, saving the VM context can possibly be done by saving the:

  1. Current PC, bytecode string
  2. Linear memory, and the
  3. Operation Stack

To a global list of saved contexts in the VM context struct, if any.

Thus, a setjump should simply restore these values, and continue with the interpreter loop as usual (This is similar to how the emacs bytecode VM implements signals: https://github.com/emacs-mirror/emacs/blob/master/src/bytecode.c#L785). An exception system can be implemented on the top of this, though I'm not sure how performant would this be.

Further, the webassembly spec mentions that the stack height at any moment in the bytecode is statically known, making all stack operations equivalent to operations on registers unique to each position on the stack. This paper describes a way to achieve such a stack -> register mapping for converting stack machine code to native code, allowing us to use setjmp/longjmp as usual.

Edit: What about using panic() and recover() with special WasmException{} values for signalling an exception? recover does the tough job of stack unwinding already, it shouldn't be hard to restore the interpreter loop after recovering from a caught exception.

minux commented

IIUC, you can completely discard the WASM stack (according to the spec). An extendable and copyable go stack is still something that needs to be investigated.

minux commented

@bradfitz @minux @vibhavp What is the current state of wasm in golang? Nothing has happened since March 13th ! will it be possible transform golang to wasm in the future? is there maybe any route-map of that?

if somebody will decide to implement wasm support I can offer my time for non-global tasks

@SerkanSipahi, nobody is working on this. This bug is marked LongTerm. If something starts happening, you'll see updates here.

A good roadmap ?

We have DELVE and GDLV for debugging golang with a GUI. It works well too on all Desktops and Perf is excellent.
https://github.com/derekparker/delve
https://github.com/aarzilli/gdlv

Now, GDLV is based on NUCULAR which is shiny with some nice abstractions.
https://github.com/aarzilli/nucular

SO i was thinking this would be a good basis to do what has already been done here:

There are 5 WASM go libaries now too:
https://github.com/search?l=Go&q=webassembly&ref=simplesearch&type=Repositories&utf8=%E2%9C%93

I believe that NaCl is used by various parts of the Go ecosystem. That is, it's not used only by Chrome. And in any case that blog announcement is about PNaCl, which, although it provides functionality similar to NaCl, is actually a completely different product based on a different technology. So removing NaCl support from Go is premature at present.

Any in any case whether or not we remove NaCl from Go has nothing to do with whether we add support for Web Assembly.

I would say that PNaCl is just an extension over NaCl to provide platform independent code https://developer.chrome.com/native-client/nacl-and-pnacl I asked about NaCl deprecation here - https://groups.google.com/d/topic/native-client-discuss/wgN2ketXybQ/discussion

If is possible to get list of those various parts of the Go ecosystem where NaCl is still used?
Going through it one by one will make transitioning to WebAssembly more interesting.

4ad commented

I would say that PNaCl is just an extension over NaCl

You can say whatever you want, but it doesn't mean you are right. They are completely different ISAs, NaCL is just the target ISA (x86/arm) with some restrictions, while PNaCl is a completely different ISA for an abstract machine.

Go has never supported PNaCL, and the Go NaCL port was never suitable for Chrome anyway. It had nothing to do with Chrome, it was not usable in the browser. Whether Chrome abandons NaCL or PNaCL has no relevance to Go whatsoever. Nada, nil, no relevance. How many more times this must be said? Of course, if NaCL is abandoned completely then Go will be forced at some point to abandon it too.

WebAssembly support in Go has absolutely nothing to do with NaCL. Go might or might not get WebAssembly support. If, or when it might get such support has no relevance to the state of the NaCL port.

Here is a very important part of the ecosystem where we use nacl: https://play.golang.org/p/MfJIq8wb5-

(that runs server-side, not nacl-in-a-browser)

Whether Chrome abandons NaCL or PNaCL has no relevance to Go whatsoever. Nada, nil, no relevance.

And who will support sandbox loader and toolchain then? It is imported from Chrome project, which switched efforts to WebAssembly. Wouldn't it be wise to follow and see if Go playground can already be ported from NaCl sandbox to WebAssembly sandbox? It can also be run server-side.

I think everybody is in favor of supporting WebAssembly.

The time to discuss moving away from NaCl is after WebAssembly is fully working. There's no point to discussing it before then.

@ianlancetaylor, can you clarify "after WebAssembly is fully working"?

At a glance, it appears webassembly.org says "the initial version of WebAssembly has reached cross-browser consensus" and wasm is available in current or future browser versions from all browser vendors.

@vine77 I mean after WebAssembly is fully working for Go programs, at least as well as NaCl works today.

So what is the next test that should pass for WebAssembly to work for Go programs?

@techtonik I feel like there is some confusion here. When we say that WebAssembly should work for Go programs, what we mean is that the Go compiler should generate WebAssembly code that can run in the browser. We mean that you should be able to write something like GOOS=wasm go build hello.go and get a program that can run inside a browser. We aren't even remotely close to that. We haven't even started. So there is no "next test." There is a lot of work to be done. And, as far as I know, nobody is actively working on it.

@ ianlancetaylor
There are 4 implementations out there for golang. One seriously impressive. See my previous comment for the links.

Boy this thread is like Chevy Chase car seen with the kids in the back seat screaming " are we there yet " :)

@joeblew99 : none of those links are things that can compile Go to WebAssembly.
They are things like a WebAssembly -> amd64 compiler written in Go.

I was afraid you would say that. Fair enough.
So what IS needed for the " bring up" ? So everyone knows...
Gopherjs kind of made the same mistake of not being at the right level in the compiler tool chain architecture / code generation ?

There's a long list. Most have to do with garbage collection, one way or another.

  • Generate WebAssembly code in the SSA backend. The backend is used to register machines, adapting to WebAssembly's stack machine will take some work.
  • What's a pointer? WebAssembly doesn't have a pointer type.
  • How do we introspect the stack? We'd need this for garbage collection, certainly, but also panic/recover, traceback printing, etc.
  • How do we suspend/resume a goroutine?
  • How can we lay out the heap? WebAssembly provides only essentially sbrk. We need more general address space layout. Where do we store information about spans, ptr/nonptr bits, etc.?
  • Multithreading. WebAssembly has no notion of threads at the moment, which we would need to, for example, do concurrent GC. We'd also need locks and maybe atomic operations.
  • How do we provide access to the outside world for packages like os and net?
  • WebAssembly doesn't have support for "goto".

That's probably not a complete list.

When we say that WebAssembly should work for Go programs, what we mean is that the Go compiler should generate WebAssembly code that can run in the browser.

@ianlancetaylor would it be easier to target non-web first? NaCl was also designed to be run in browser first, but then got browser-independent loader, which Go currently uses. WebAseembly without browser - http://webassembly.org/docs/non-web/ - and it speaks about minimal shells for testing.

@randall77 is it possible to bring an actionable checklist out of this list? Like a master issue with links to issues that research each aspect in detail further?

@techtonik wrt non-web: @vibhavp is working on that in the context of the GSoC internship I was alluding to a few posts above.
it's over there: https://github.com/go-interpreter/wagon

@techtonik: I think the right place for such a checklist is a proposal document about supporting wasm. Once such a proposal is accepted and/or people are actively working on it, they could use issues for individual tasks, sure. That's premature at this point - I know of no one actively working on either (a proposal or code).

I agree about a proposal doc.
All the I do / contradictions are in this thread and just needs it wrapped together, with a roadmap that lets stages the risk / reward balance.

I would also like to see it address graphics too as it's sticking out like a sore thumb for me.

I'm the author of GopherJS, a compiler from Go to JavaScript. I have written that project because I strongly believe that there should be alternatives to using JavaScript in the browser, alternatives like Go and others. I have decent knowledge on compilers, SSA, machine architecture etc., but I'm probably missing a lot of details, since I haven't written a compiler backend for machine code yet. This is why I don't feel qualified to write a full proposal doc. Still, I'd love to get some critical feedback on my thoughts about Go and WebAssembly.

While looking at WebAssembly, it strikes me as being very different to the usual machine code targets like x86 or arm. For example its architecture is a stack machine instead of a register machine. This means that it isn't immediately suitable as simply yet another target at the last stage of the Go compiler next to x86 and friends. One solution might be to not put it there, but instead have a significantly different approach on generating WebAssembly. The code for this approach would need to live besides the existing compiler stages, which would be not nice at all. One might even consider a fork of the compiler in this scenario. In short: I don't see this happening.

There might be an alternative: Emulate what we need. We may use the stack machine to emulate a register machine and hopefully do so in a reasonably performant way. WebAssembly has linear memory with load and store instructions, which is good. We would not use WebAssembly's call instruction at all and instead roll our own stack management and call mechanism. Stacks would live on that linear memory and be managed by the Go runtime. The stackpointer would be a global variable. All code would live in a single WebAssembly function. The toplevel would be a giant switch statement (or WebAssembly's br_table based equivalent) with one branch for each function. Each function would have another switch statement with one branch per SSA basic block. There are some details that I'm omitting here, but in the big picture this looks like a decent register machine to me. Of course the performance of this heavily depends on how well WebAssembly can transform these constructs into actual machine code.

So please tell me: Am I completely naive and nuts? Then I'm happy to postpone my thoughts until I've learned more. If not, then this may serve as a starting point for some actual proposal doc. Thanks.

In addition to all the work needed on the Go side, there are some things WebAssembly may need before the Go runtime can target it.

WebAssembly doesn't yet have threads, but it's on the roadmap and there is a spec. https://github.com/WebAssembly/threads

Regarding garbage collection, it sounds like there could be multiple options in the future, based on Lin Clark's talk https://youtu.be/HktWin_LPf4?t=28m31s

28:31
So, today, you can ship down your own garbage collector with code if you want to but is
slow for a few reasons and the community group is making it possible for WebAssembly code
to be used with just the built-in GC which is a highly optimised one that the browsers
have been working on, so it will run fast and you will have that integration.

As with gomobile, there is the language bridge to figure out.

@randall77 also mentioned threads as a requirement for the GC. Is this really a hard requirement for the first version? Concurrency can also be done in a single thread.

Regarding the implementation of GC my personal opinion is that I don't believe in the one GC to rule them all. I'd rather prefer for Go to have a Go-specific GC and for Python to have a Python-specific GC. By completely managing our own heap and stacks on WebAssembly's linear memory we should be able to use the GC that Go already has, as far as I can currently see.

@neelance Yes multiple real WebAssembly threads are a nice-to-have, not a strict requirement.

The GC proposal for WebAssembly is still a work in progress. Interested parties can participate here:

https://github.com/WebAssembly/gc

@neelance, I know nothing about compilers, SSA, machine architecture, etc. Can you please tell how what you've described would affect binary size? If I'm understanding correctly the size efficiency was one of the high level goals of WebAssembly. It should be one of the priorities for this Go->WebAssembly compiler as well, right?

@alxkchr My experience is that the repetition due to code-gen boilerplate can be compensated a lot by applying gzip. Still, my proposal is not the most efficient solution with respect to binary size. Still, some solution that can be implemented in a reasonable amount of time is better than no solution, right? ;-) Also for me personally, binary size is not one of the first priorities.

fyi: I have started implementing this.

@neelance best news ever :) do you follow the spec? (i hope)

The Go spec? It is a new backend/target for the normal Go compiler, so the spec is already in there. ;)

i mean wasm spec :)

cznic commented

@neelance

fyi: I have started implementing this.

Can you please share what approach will be used to address

Our current conclusion is that there is no efficient way to implement
setjmp/longjmp functionality currently, therefore it's not a viable target
of a gc port. We need to wait until it gets real stack unwinding and
exception handling support.

(#18892 (comment))

@neelance: I know it's still early days, but I think it would be wiser to name the wasm GOARCH wasm32 (ditto for the packages)

@sbinet It's worth considering that the ARM architectures/packages are named arm and arm64 (similarly mips and mips64) rather than arm32 and arm64. However, I don't know whether that should be considered a good or bad example.

@SerkanSipahi I'm initially targeting V8 (nodejs/chrome) and using https://webassembly.github.io/spec/ as documentation on what to do.

@stuart-warren Yes, my WIP is on that branch. However, don't try to use it yet, it can't be easily built right now and it is full of copied code and stubs/hacks. I'll announce it here when it reaches some alpha state.

@cznic As written above, I am not using wasm's call instruction at all, I'm managing my own stack on the linear memory. Thus setjmp/longjmp can be implemented.

@sbinet Actually it will be a 64 bit architecture since wasm has 64 bit operations.

@neelance not entirely. The WebAssembly spec only supports 32 bit address spaces for now, a wasm64 spec is planned for later.

Interesting, thanks for the link. We may want to revisit this later. Currently I store everything in 64 bit variables, so int, uint and uintptr all have a size of 64 bits. However, only the first 32 bits are used for addressing memory. This is easier to implement at first.

It sounds like wasm64p32 then (to follow the nacl naming), or something
similar.

I don't think there is a point in having two numbers, because there will only be one architecture (with a choice of address space size). From webassembly.org:

wasm32 and wasm64 are both just modes of WebAssembly, to be selected by a flag in a module header, and don’t imply any semantics differences outside of how linear memory is handled.

I don't think there is a point in having two numbers, because there will only be one architecture (with a choice of address space size). From webassembly.org:

wasm32 and wasm64 are both just modes of WebAssembly, to be selected by a flag in a module header, and don’t imply any semantics differences outside of how linear memory is handled.

That's an aspirational statement. It might turn out to be true, but the WebAssembly CG / WG haven't explored wasm64 sufficiently for me to be confident that the statement is accurate.

Let's let @neelance work. Names are easy to change later.

I know Go is compiled directly to machine instructions (AFAIK), but am wondering to myself if someone has ever compiled Go to C. Would be interesting to try Go --> C --> wasm (though not very efficient).

@TomerHeber it can be possible in form of translation to C++, not compilation, but probably this will be more work than compilation to wasm itself

Hi everyone. Here's an update on my work: I'm making very good progress, which is very much due to the great work of the Go team and contributors so far. Most of the code is shared between architectures/platforms, so there wasn't as much as I expected that needed to be implemented.

Here's a list of some things that are already working fine:

  • running the generated wasm code in browsers and in Node.js
  • basic operations, conversions, etc.
  • interfaces
  • goroutines & channels
  • defer/panic/rescue
  • reading files form disk when using Node.js
  • tests of the following packages are passing: bytes, container/heap, container/list, container/ring, encoding/ascii85, encoding/asn1, encoding/base32, encoding/binary, encoding/csv, encoding/hex, errors, flag, hash/adler32, hash/crc32, hash/crc64, hash/fnv, html, image, image/color, index/suffixarray, math, math/bits, path, sort, strconv, strings, text/scanner, text/tabwriter, unicode, unicode/utf8, unicode/utf16

Some things that still need work:

  • reflection
  • growing the stack of goroutines
  • garbage collection
  • performance optimizations
  • wasm file size optimizations
  • a nice JS interop layer
  • many other issues to make more package tests pass

I am very happy about the progress in a month and a half, and only in my spare time. I think there is a good chance that we could get this into Go 1.11. Expect my next update in January, since I'll be on vacation and then there are the holidays.

Can some of those tasks be parallelized? Some bits seems interesting for holidays hack.

Feel free to look into it and create a PR on my fork. You can also find me on the Gophers Slack.

One area of investigation might be optimizing the usage of the stack. Right now, the register allocation phase allocates registers (local variables in wasm) for every operation. get_local and set_local are always used before and after every operation. This is unnecessary if the value could simply stay on the stack to be used by some later operation. I suggest adding a pseudo register REG_STACK and make the instruction generator skip get_local and set_local if this register is used. Then make regalloc use this register when appropriate.

Re:

a nice JS interop layer

Is there a sane way to implement this for wasm currently? I thought Dom/js interop was a ways out with wasm still. If this is possible, that would be huge!

You can import and export functions which can have float64 and int32 arguments and you have the shared linear memory. Everything else can be built around that. Only garbage collection would not be that nice.

(I have been trying to post this on your (@neelance) repo but I couldn't figure out how to post issues...)

would it be possible to use the wabt toolchain instead of calling/importing js.foo ?
I've found it easier to interact with wabt instead of a full nodejs installation :)

(I am also trying to interpret a simple main.go program, translated to a.wasm here: go-interpreter/wagon#36...)

I have enabled issues on my fork, feel free to post there.

I don't really understand your question. Are you talking about wasm-interp? Something needs to compile&run the wasm bytecode and you need some JS environment to interact with the rest of the system, e.g. for printing to console.

This is great. For those wanting to try your hand in compiling and executing Go to wasm -

  1. Create a simple hello world program which prints to console.
  2. GOOS=js GOARCH=wasm ./bin/go build -o out.wasm wasm.go
  3. ./misc/wasm/go_js_wasm_exec out.wasm

Enjoy !

If you link go_js_wasm_exec into your PATH, then you can even use go run. ;-)

Hey guys, how's the garbage collection situation with Go for WASM? We started talking about bringing Crystal over and it appears that Crystal likely shares the same problems that Go has currently with GC. Would there be any way that we could collaborate or help the WebAssembly working group with this situation?

Please feel free to chime in on the thread noted above or let us know where we could perhaps chat / possibly collaborate on this issue.

It may be that the Opal path is the more sane approach for now until WASM matures in this area, but it would be good to know that for sure before going down that path.

Hey folks, I wanted to share what I've been working the last few months since I think a lot of the underlying code is relevant: https://github.com/matthewmueller/joy

I'm targeting JS (ES3) right now, but the compiler implements a dependency graph for all the declarations (funcs, variables, etc.). It then sorts the graph and translates only the declarations that are used in the program.

I don't think it would be too difficult to use this graph and target WebAssembly. I'm eager to help and collaborate in anyway that I can.

For more information here are some relevant links:

Regarding the GC issue for Crystal above, this might also have application for Go, note @kripken's remarks and the following discussion here: WebAssembly/binaryen#1312 (comment)

Potentially we'll want to update https://github.com/AppCypher/webassemblylanguages?

I hope everyone had nice holidays. Here's the promised update:

Since my last update, I managed to get reflection, stack-growing and the garbage collection up and running. Additional improvements got it to the point that the tests of 104 out of 136 stdlib packages are passing now. Also, many of the compiler tests are green. Good progress!

Please keep in mind that I am currently focusing on feature support and correctness. I haven't done any optimizations for performance or output size yet.

I applaud the experiment (and @neelance ty so much for GopherJS for the superior goroutines as compared to Promise, you probably rescued me from C++!), so the following is merely at an attempt to add potentially useful information and perhaps even maybe to raise awareness of the incongruence between Go and a WASM target. Also potentially to clarify the issue for some readers. Also because I wanted some appropriate place to dump the following @rossberg quote I found when I was independently thinking about how to compile something like gorountines to WASM.

@neelance replied:

@cznic replied:

@neelance wrote:

We would not use WebAssembly's call instruction at all and instead roll our own stack management and call mechanism. Stacks would live on that linear memory and be managed by the Go runtime. The stackpointer would be a global variable. All code would live in a single WebAssembly function. The toplevel would be a giant switch statement (or WebAssembly's br_table based equivalent) with one branch for each function. Each function would have another switch statement with one branch per SSA basic block.

Can you please share what approach will be used to address:

@minux wrote:

Our current conclusion is that there is no efficient way to implement
setjmp/longjmp functionality currently, therefore it's not a viable target
of a gc port. We need to wait until it gets real stack unwinding and
exception handling support.

@cznic As written above, I am not using wasm's call instruction at all, I'm managing my own stack on the linear memory. Thus setjmp/longjmp can be implemented.

According to the β€œco-designer” and β€œspec author” of WASM, the limitations on call, which make it inappropriate for Go, have something to do with security/safety:

@rossberg wrote:

You can't easily "replace" the call stack, as there is no way to reify return addresses (*). However, you can implement a shadow stack for your local variables in linear memory if you need to.

In fact, WebAssembly does not currently expose any notion of built-in "stack" at all. Like a number of other design decisions, that's important: because Wasm is running on the Web, it has to be "safe". That's why it's typed, has no undefined behaviour, code is separated from memory (and not addressable), casts over function types are checked, etc. Having an explicit concept of function also enables other benefits, such as effective register allocation, parallel or lazy compilation, useful debug tools, etc.

Control-flow indeed is semi-structured: branches are really only breaks and continues, so that you cannot construct irreducible control flow. That's a feature as well.

[…]

(*) You could presumably emulate explicit return addresses with indices into a giant table jump, by compiling your whole program into a single looping function. But that would probably be pretty slow and defeat much of the WebAssembly ecosystem.

So the performance and interoperability with the WASM ecosystem of what @neelance is attempting will probably be suboptimal?

Citing @neelance’s skill optimizing the performance of GopherJS.

I don't know what you mean by "interoperability with the WASM ecosystem", so I can't comment on that. Regarding performance I can tell you this:

Yes, the current approach is not the most optimal way to express control flow in WebAssembly, but it works today. Maybe it will be possible in the future to use WebAssembly's call instruction more, but for that, WebAssembly would need to add a few more features and it would need much more work on the Go side to be compatible with that. I'd rather have something with 80% of the performance that actually works than something that has 100% but is only hypothetical. ;-)

If you're interested in more technical details, talk to me on #webassembly at https://invite.slack.golangbridge.org/.

I don't know what you mean by "interoperability with the WASM ecosystem", so I can't comment on that.

Perhaps what @rossberg is referring to with β€œdefeat much of the WebAssembly ecosystem”, is interoperability with tools and other languages in the ecosystem which are not side-stepping call and the protected call stack by essentially emulating your own continuations employing switch tables?

but for that, WebAssembly would need to add a few more features

I hope that WASM would better accommodate languages with goroutines (green threads), because afaics they’re unarguably superior to the stack unwinding JavaScript Promise model.

I'd rather have something with 80% of the performance that actually works than something that has 100% but is only hypothetical. ;-)

Oh I entirely agree which is why I made sure I prefaced my prior post with my applause for your prolific efforts.

The more popular on the web/WASM, we can make Go or other languages that have green threads, then perhaps the better chance we have of getting better WASM primitives (e.g. analogous to gcc’s -fsplit-stack?) for better performance eventually.

If your implementation truly achieves 80% of the optimal performance within the current limitations of WASM, I will be pleasantly surprised. If the performance outcome is excessively bad, then it might limit the demonstration of the popularity of green threads versus JavaScript Promise callback based model (the potential of the irony of β€œdefeat much of the WebAssembly ecosystem” if we presume it’s design has been driven by a priority on optimizing JavaScript :-) .

Note also that I’m contemplating (no firm decision yet) adding typeclass generics to Go as a transpiler (and providing my analysis of the generics proposal for Go 2), so I’m also potentially involved in doing my part to try to increase popularity.

@shelby3 Please stop using formatting that makes your text so small that is not readable. If you consider that something is not worth for people to read, don't write it in the first place. Making it unreadable without giving a hint to what is hidden make readers spend twice (or more) time trying to decypher it. I think it is the opposite of your original intent.

@shelby3 I’ve edited your posts to stop using the small text formatting. Please stop doing that.

Change https://golang.org/cl/102835 mentions this issue: go/build, cmd/dist: add js/wasm architecture

Change https://golang.org/cl/103255 mentions this issue: wasm: add scripts for running WebAssembly binaries

Change https://golang.org/cl/103256 mentions this issue: cmd/compile: add SSA config options noAvg and noHmul

Change https://golang.org/cl/103275 mentions this issue: cmd/compile/internal/gc: factor out beginning of SSAGenState.Call

Change https://golang.org/cl/103295 mentions this issue: cmd/compile: add wasm architecture

Change https://golang.org/cl/103535 mentions this issue: cmd/compile: wasm stack optimization

Change https://golang.org/cl/103795 mentions this issue: cmd/link: add wasm architecture

Change https://golang.org/cl/103877 mentions this issue: runtime: add js/wasm architecture

Change https://golang.org/cl/103915 mentions this issue: internal/bytealg: add wasm architecture

Ok, looks like a lot of CLs are starting to fly by.
How are we doing with respect to the porting policy: https://github.com/golang/go/wiki/PortingPolicy ?
In particular, what will the builders look like?
I assume @neelance that you're signing up for maintaining the port?
(My apologies if one of the CLs spells all this out, I haven't read all of them.)

Yes, I'm going to maintain the port. @bradfitz is currently looking into setting up the builder.

Change https://golang.org/cl/106995 mentions this issue: sync/atomic: add wasm architecture

Change https://golang.org/cl/106996 mentions this issue: math: add wasm architecture

Change https://golang.org/cl/106997 mentions this issue: time: add wasm architecture

Change https://golang.org/cl/106998 mentions this issue: mime: add wasm architecture

Change https://golang.org/cl/109195 mentions this issue: syscall/js: add package

Change https://golang.org/cl/109976 mentions this issue: syscall: enable some nacl code to be shared with js/wasm

Change https://golang.org/cl/109977 mentions this issue: os: add js/wasm architecture

Change https://golang.org/cl/109995 mentions this issue: net: add js/wasm architecture

Change https://golang.org/cl/110095 mentions this issue: crypto: add js/wasm architecture

Change https://golang.org/cl/110096 mentions this issue: all: skip unsupported tests for js/wasm

Change https://golang.org/cl/112736 mentions this issue: env/js-wasm, dashboard: add start of a js-wasm builder