tinygo-org / tinygo

Go compiler for small places. Microcontrollers, WebAssembly (WASM/WASI), and command-line tools. Based on LLVM.
https://tinygo.org
Other
15.16k stars 890 forks source link

Support compiling basic Vecty/Vugu examples to WASM #93

Closed johanbrandhorst closed 4 years ago

johanbrandhorst commented 5 years ago

This is just a tracking issue for any outstanding work required for us to compile a vecty-style web app into WASM with tinygo. I think this would be a fantastic milestone for this repo and the Go WASM community at large, so lets see what remains outstanding.

Would love to have @slimsag take a quick look at this if possible, but otherwise I think @bketelsen will know the best what is outstanding.

marwan-at-work commented 4 years ago

Hi there :wave:

Any updates on TinyGo working with Vecty? Thank you!

deadprogram commented 4 years ago

This was released with v0.14.0 so now closing. Please reopen if needed. Thanks!

marwan-at-work commented 4 years ago

@deadprogram thank you for the update!

Trying to compile my program with tinygo results in the following errors from encoding/json

tinygo build -o wasm.wasm -target=wasm main.go
# encoding/json
/usr/local/go/src/encoding/json/decode.go:160:15: cannot convert nil (untyped nil value) to reflect.Type
/usr/local/go/src/encoding/json/decode.go:235:26: cannot convert nil (untyped nil value) to reflect.Type
/usr/local/go/src/encoding/json/decode.go:252:30: cannot convert nil (untyped nil value) to reflect.Type
/usr/local/go/src/encoding/json/decode.go:532:8: v.NumMethod undefined (type reflect.Value has no field or method NumMethod)
/usr/local/go/src/encoding/json/decode.go:569:7: v.SetLen undefined (type reflect.Value has no field or method SetLen)
/usr/local/go/src/encoding/json/decode.go:606:6: v.SetLen undefined (type reflect.Value has no field or method SetLen)
/usr/local/go/src/encoding/json/decode.go:637:40: v.NumMethod undefined (type reflect.Value has no field or method NumMethod)
/usr/local/go/src/encoding/json/decode.go:658:16: PtrTo not declared by package reflect
/usr/local/go/src/encoding/json/decode.go:793:17: PtrTo not declared by package reflect
/usr/local/go/src/encoding/json/decode.go:938:9: v.NumMethod undefined (type reflect.Value has no field or method NumMethod)
/usr/local/go/src/encoding/json/decode.go:967:6: v.SetBytes undefined (type reflect.Value has no field or method SetBytes)
/usr/local/go/src/encoding/json/decode.go:974:9: v.NumMethod undefined (type reflect.Value has no field or method NumMethod)
/usr/local/go/src/encoding/json/decode.go:1007:9: v.NumMethod undefined (type reflect.Value has no field or method NumMethod)
/usr/local/go/src/encoding/json/decode.go:1031:23: v.OverflowFloat undefined (type reflect.Value has no field or method OverflowFloat)
/usr/local/go/src/encoding/json/encode.go:420:53: PtrTo not declared by package reflect
/usr/local/go/src/encoding/json/encode.go:426:53: PtrTo not declared by package reflect
/usr/local/go/src/encoding/json/encode.go:865:16: PtrTo not declared by package reflect

Here's a simple program to reproduce it:

package main

import "encoding/json"

type t struct {
    One string `json:"one"`
}

func main() {
    var t t
    json.Unmarshal([]byte(`{"one": "two"}`), &t)
}

@deadprogram I'm not sure if this is a known issue and if it's unrelated to compiling tiny go with vecty but thought I'd bring it up here since frontend applications will most likely use the json library for api calls.

Thanks!

ethanfrey commented 4 years ago

@marwan-at-work encoding/json does not work with TinyGo as it makes extensive use of the reflect package (which is not fully supported by TinyGo for various technical reasons).

@bradleypeabody made an amazing package https://github.com/vugu/vjson which provides TinyGo-compliant JSON parsing and unmarshalling.

marwan-at-work commented 4 years ago

@ethanfrey thank you! I will definitely check that library out.

Encoding/json aside, I tried compiling a basic Vecty app (without importing json) and got the following error:

root@05844ebaa1e7:/app# tinygo build -o wasm.wasm -target=wasm .
# github.com/gopherjs/vecty
/go/pkg/mod/github.com/gopherjs/vecty@v0.0.0-20200328200803-52636d1f7aba/dom_wasmjs_gopherjs.go: interp: unknown GEP

traceback:
github.com/gopherjs/vecty/<init>:41:24:
  %15 = call %runtime._interface @"github.com/gopherjs/vecty.wrapObject"([0 x %runtime.funcValue] %12, i64 %13, i64* %14, i8* undef, i8* undef), !dbg !216

Using this simple program:

package main

import (
    "github.com/gopherjs/vecty"
    "github.com/gopherjs/vecty/elem"
)

type comp struct {
    vecty.Core
}

func (c *comp) Render() vecty.ComponentOrHTML {
    return elem.Div(vecty.Text("hello"))
}

func main() {
    vecty.RenderBody(&comp{})
}

Again, not sure if it's a vecty specific issue or a tiny-go issue with reflect but thought I'd post it here and happy to report it anywhere else that needs to be.

Thanks again for the quick response and all the work on tiny go!

marwan-at-work commented 4 years ago

Should we re-open the issue in this case? Or make a new one to track the progress on whatever is needed to compile vecty programs? Thanks

deadprogram commented 4 years ago

I would suggest check out https://www.vugu.org/doc/tinygo for specifics.

marwan-at-work commented 4 years ago

@deadprogram FWIW, I was mainly talking about vecty not vugu, and the page you linked me is very vugu specific and doesn't offer any hints on how to make vecty work :)

The above program compiles with Go but it does not compile with TinyGo which makes me think it's probably more appropriate to file as a TinyGo bug rather than a Vecty bug.

I definitely understand that TinyGo still doesn't fully support reflection, but I was under the impression that this issue was to track its progress since it was what was missing for Vecty to compile with tiny go.

If that's the case, I'd be happy to re-open the issue, or maybe open a separate tracking issue.

Otherwise, I'm happy to go with the follow on whichever is the best way to solve this issue.

Thanks again and appreciate all of the work and help here!

johanbrandhorst commented 4 years ago

I think closing this issue is appropriate as it is now possible to use Vugu with TinyGo (:tada:). Vugu and TinyGo had to meet a bit in the middle on this, and I think it might be reasonable to expect the same thing from Vecty. Therefore, I think we should open a separate issue to track the outstanding work, if any, for supporting Vecty. We should port over the current errors (thanks @marwan-at-work for trying it!) so we know where the shortcomings are, and if we should tackle them in TinyGo or Vecty. I'd say the above error is a TinyGo one, but it's not unreasonable for Vecty to provide a less reflect-heavy implementation if it helps bridge the gap, like Vugu did.

How does that sound?

marwan-at-work commented 4 years ago

@johanbrandhorst done :)