tinygo-org / tinygo

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

Trying to compile gopher-lua with TinyGo issues #742

Open thegrumpylion opened 4 years ago

thegrumpylion commented 4 years ago

I have forked and striped of any "os" dependencies this package https://github.com/yuin/gopher-lua (my fork https://github.com/thegrumpylion/gopher-lua) and i am trying to build this example https://github.com/thegrumpylion/tinygo/blob/lua/src/examples/lua/lua.go

tinygo build -target=pca10056 -o lua.hex ./src/examples/lua

But i hit this wall:

fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x28 pc=0x3810ac0]

runtime stack:
runtime.throw(0x3b8f74d, 0x2a)
        /home/nikolas/go/src/runtime/panic.go:774 +0x72
runtime.sigpanic()
        /home/nikolas/go/src/runtime/signal_unix.go:378 +0x47c

goroutine 1 [syscall]:
runtime.cgocall(0xcb0050, 0xc00c1dc850, 0xc00c1dc848)
        /home/nikolas/go/src/runtime/cgocall.go:128 +0x5b fp=0xc00c1dc820 sp=0xc00c1dc7e8 pc=0x92dafb
tinygo.org/x/go-llvm._Cfunc_LLVMGetConstOpcode(0x7f73582d5e88, 0x7f7300000000)
        _cgo_gotypes.go:5253 +0x49 fp=0xc00c1dc850 sp=0xc00c1dc820 pc=0xb48b99
tinygo.org/x/go-llvm.Value.Opcode.func1(0x7f73582d5e88, 0x8)
        /home/nikolas/golang/pkg/mod/tinygo.org/x/go-llvm@v0.0.0-20191113125529-bad6d01809e8/ir.go:872 +0x56 fp=0xc00c1dc888 sp=0xc00c1dc850 pc=0xb6a7c6
tinygo.org/x/go-llvm.Value.Opcode(0x7f73582d5e88, 0x60f0d50)
        /home/nikolas/golang/pkg/mod/tinygo.org/x/go-llvm@v0.0.0-20191113125529-bad6d01809e8/ir.go:872 +0x2b fp=0xc00c1dc8a8 sp=0xc00c1dc888 pc=0xb573bb
github.com/tinygo-org/tinygo/interp.(*MapValue).PutBinary(0xc0079f04d0, 0xc003334780, 0xc003c77d40)
        /home/nikolas/projects/tinygo/tinygo/interp/values.go:370 +0xc5 fp=0xc00c1dc940 sp=0xc00c1dc8a8 pc=0xc8fcc5
github.com/tinygo-org/tinygo/interp.(*frame).evalBasicBlock(0xc00c1dd4e0, 0x7f73290e3620, 0x7f73290e3220, 0x0, 0x0, 0x0, 0x0, 0xc00590d4f8, 0x1, 0x1, ...)
        /home/nikolas/projects/tinygo/tinygo/interp/frame.go:291 +0x78f7 fp=0xc00c1dd448 sp=0xc00c1dc940 pc=0xc88bd7
github.com/tinygo-org/tinygo/interp.(*Eval).function(0xc008011f80, 0x7f734c04ca28, 0xc00c1dd628, 0x2, 0x2, 0xc003870240, 0x23, 0x0, 0x0, 0x0, ...)
        /home/nikolas/projects/tinygo/tinygo/interp/interp.go:104 +0x208 fp=0xc00c1dd518 sp=0xc00c1dd448 pc=0xc8c038
github.com/tinygo-org/tinygo/interp.(*Eval).Function(...)
        /home/nikolas/projects/tinygo/tinygo/interp/interp.go:87
github.com/tinygo-org/tinygo/interp.Run(0x60eff30, 0x7fff00000000, 0x0, 0x0)
        /home/nikolas/projects/tinygo/tinygo/interp/interp.go:74 +0x6b2 fp=0xc00c1dd658 sp=0xc00c1dd518 pc=0xc8bac2
github.com/tinygo-org/tinygo/builder.Build(0x7fffcbff6c9c, 0x12, 0x7fffcbff6c94, 0x7, 0xc0000f73e0, 0xc00c1ddca8, 0x0, 0x0)
        /home/nikolas/projects/tinygo/tinygo/builder/build.go:49 +0x1f5 fp=0xc00c1ddc68 sp=0xc00c1dd658 pc=0xc95025
main.Build(0x7fffcbff6c9c, 0x12, 0x7fffcbff6c94, 0x7, 0xc00016e000, 0x0, 0x16)
        /home/nikolas/projects/tinygo/tinygo/main.go:83 +0xc5 fp=0xc00c1ddcd0 sp=0xc00c1ddc68 pc=0xca4745
main.main()
        /home/nikolas/projects/tinygo/tinygo/main.go:590 +0x192a fp=0xc00c1ddf60 sp=0xc00c1ddcd0 pc=0xca7dba
runtime.main()
        /home/nikolas/go/src/runtime/proc.go:203 +0x21e fp=0xc00c1ddfe0 sp=0xc00c1ddf60 pc=0x959efe
runtime.goexit()
        /home/nikolas/go/src/runtime/asm_amd64.s:1357 +0x1 fp=0xc00c1ddfe8 sp=0xc00c1ddfe0 pc=0x985181

goroutine 6 [syscall]:
os/signal.signal_recv(0x0)
        /home/nikolas/go/src/runtime/sigqueue.go:147 +0x9c
os/signal.loop()
        /home/nikolas/go/src/os/signal/signal_unix.go:23 +0x22
created by os/signal.init.0
        /home/nikolas/go/src/os/signal/signal_unix.go:29 +0x41

Any ideas what am i doing wrong?

thegrumpylion commented 4 years ago
$ uname -a
Linux nikolas-ThinkPad-T470p 5.0.0-36-generic #39~18.04.1-Ubuntu SMP Tue Nov 12 11:09:50 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
$ tinygo -version
tinygo version 0.10.0-dev linux/amd64 (using go version go1.13.1)
aykevl commented 4 years ago

I tried to build it but got the following error:

panic: interp: unknown GEP

Note that your fork of gopher-lua has not adjusted all import paths, maybe that's the issue? I made a symlink from github.com/yuin/gopher-lua (with your fork) to github.com/thegrumpylion/gopher-lua and then it compiled.

thegrumpylion commented 4 years ago

Have you built master of my fork? I forgot to mention that i am using another branch (https://github.com/thegrumpylion/gopher-lua/tree/tinygo)

I've pushed another commit to that branch that i have replaced all import paths to point to my fork, rebased the current dev of tinygo to the lua branch and i get the same error as above.

If it compiles for you, have you tried to run the example? It should print something over serial.

thegrumpylion commented 4 years ago

Ok, now also master is the same

aykevl commented 4 years ago

What I did:

  1. Checkout the tinygo branch of github.com/thegrumpylion/gopher-lua into $GOPATH/src/github/thegrumpylion/gopher-lua
  2. Copy lua.go from https://github.com/thegrumpylion/tinygo/blob/lua/src/examples/lua/lua.go
  3. Build with tinygo build -target=pca10056 -o lua.hex lua.go

Result:

panic: interp: unknown GEP
dgryski commented 1 year ago

In order to get the above example working on tinygo, I need a small patch to reflect and another to runtime. Note that I didn't need to modify gopher-lua at all.

~/go/src/github.com/tinygo-org/tinygo/src/reflect $ cat chan.go
package reflect

type SelectDir int

const (
    _             SelectDir = iota
    SelectSend              // case Chan <- Send
    SelectRecv              // case <-Chan:
    SelectDefault           // default
)

type SelectCase struct {
    Dir  SelectDir // direction of case
    Chan Value     // channel to use (for send or receive)
    Send Value     // value to send (for send)
}

func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
    panic("reflect.Select: unimplemented")
}

func (v Value) Send(x Value) {
    panic("reflect.Value.Send(): unimplemented")

}

func (v Value) Close() {
    panic("reflect.Value.Close(): unimplemented")

}
~/go/src/github.com/tinygo-org/tinygo/src/reflect $ git diff
diff --git a/src/runtime/mstats.go b/src/runtime/mstats.go
index 2699e08b..7a6f8e63 100644
--- a/src/runtime/mstats.go
+++ b/src/runtime/mstats.go
@@ -9,6 +9,11 @@ package runtime
 type MemStats struct {
        // General statistics.

+       // Alloc is bytes of allocated heap objects.
+       //
+       // This is the same as HeapAlloc (see below).
+       Alloc uint64
+
        // Sys is the total bytes of memory obtained from the OS.
        //
        // Sys is the sum of the XSys fields below. Sys measures the
@@ -18,6 +23,19 @@ type MemStats struct {

        // Heap memory statistics.

+       // HeapAlloc is bytes of allocated heap objects.
+       //
+       // "Allocated" heap objects include all reachable objects, as
+       // well as unreachable objects that the garbage collector has
+       // not yet freed. Specifically, HeapAlloc increases as heap
+       // objects are allocated and decreases as the heap is swept
+       // and unreachable objects are freed. Sweeping occurs
+       // incrementally between GC cycles, so these two processes
+       // occur simultaneously, and as a result HeapAlloc tends to
+       // change smoothly (in contrast with the sawtooth that is
+       // typical of stop-the-world garbage collectors).
+       HeapAlloc uint64
+
        // HeapSys is bytes of heap memory, total.
        //
        // In TinyGo unlike upstream Go, we make no distinction between
~/go/src/github.com/tinygo-org/tinygo/src/reflect $

I will come up with a PR to add these stubs.