Tinygo: Interp attempts to insert a non-constant value

Created on 16 Nov 2019  路  10Comments  路  Source: tinygo-org/tinygo

tinygo version 0.9.0 linux/amd64 (using go version go1.12.10)

I'm compiling a larger project, about 10k lines of code into a WASM module. I have not compiled with TinyGo in some time (I switched to normal Go to do some testing). But after implementing many changes TinyGo's build is now failing with a hex dump.

It seems to be failing on the TinyGo -> LLVM level.

I will attempt to track down the problem by pealing away at my changes and isolating the error:

tinygo: /home/circleci/project/llvm-project/llvm/include/llvm/Support/Casting.h:255: typename cast_retty<X, Y *>::ret_type llvm::cast(Y *) [X = llvm::Constant, Y = llvm::Value]: Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
SIGABRT: abort
PC=0x7f4014f4ee97 m=0 sigcode=18446744073709551610

goroutine 0 [idle]:
runtime: unknown pc 0x7f4014f4ee97
stack: frame={sp:0x7ffd71b863b0, fp:0x0} stack=[0x7ffd713876e8,0x7ffd71b86720)
00007ffd71b862b0:  00007ffd71b86660  00007f401629770a 
00007ffd71b862c0:  0000000000000037  00000000042f4e62 
00007ffd71b862d0:  00000000000000ff  0000000003e97a3c 
00007ffd71b862e0:  0000000003e97a84  0000000000000064 
00007ffd71b862f0:  0000000700000000  c9b56584ff0c0300 
00007ffd71b86300:  0000000000000070  000000000961cfe0 
00007ffd71b86310:  00007f40152fbc40  000000000961d120 
00007ffd71b86320:  0000000000000000  0000000000000110 
00007ffd71b86330:  0000000000000140  00007f4014fa579e 
00007ffd71b86340:  0000000000000000  000000770000007c 
00007ffd71b86350:  000000000961cff0  0000000000000102 
00007ffd71b86360:  000000000961cfe0  0000000000000102 
00007ffd71b86370:  0000000000000110  00007f4014fa8f9b 
00007ffd71b86380:  35353240150c77d8  00007f40152fbc40 
00007ffd71b86390:  00007ffd71b863d0  0000000000000101 
00007ffd71b863a0:  0000000000000101  00007ffd71b86610 
00007ffd71b863b0: <0000000000000000  000000000961cff0 
00007ffd71b863c0:  0000000000000200  00007f4014f985e0 
00007ffd71b863d0:  00000000fbad8000  000000000961cff0 
00007ffd71b863e0:  000000000961d055  000000000961cff0 
00007ffd71b863f0:  000000000961cff0  000000000961d0f1 
00007ffd71b86400:  000000000961d11c  000000000961cff0 
00007ffd71b86410:  000000000961d11c  0000000000000000 
00007ffd71b86420:  0000000000000000  0000000000000000 
00007ffd71b86430:  fffffffe7fffffff  ffffffffffffffff 
00007ffd71b86440:  ffffffffffffffff  ffffffffffffffff 
00007ffd71b86450:  ffffffffffffffff  ffffffffffffffff 
00007ffd71b86460:  ffffffffffffffff  ffffffffffffffff 
00007ffd71b86470:  ffffffffffffffff  ffffffffffffffff 
00007ffd71b86480:  ffffffffffffffff  ffffffffffffffff 
00007ffd71b86490:  ffffffffffffffff  ffffffffffffffff 
00007ffd71b864a0:  ffffffffffffffff  ffffffffffffffff 
runtime: unknown pc 0x7f4014f4ee97
stack: frame={sp:0x7ffd71b863b0, fp:0x0} stack=[0x7ffd713876e8,0x7ffd71b86720)
00007ffd71b862b0:  00007ffd71b86660  00007f401629770a 
00007ffd71b862c0:  0000000000000037  00000000042f4e62 
00007ffd71b862d0:  00000000000000ff  0000000003e97a3c 
00007ffd71b862e0:  0000000003e97a84  0000000000000064 
00007ffd71b862f0:  0000000700000000  c9b56584ff0c0300 
00007ffd71b86300:  0000000000000070  000000000961cfe0 
00007ffd71b86310:  00007f40152fbc40  000000000961d120 
00007ffd71b86320:  0000000000000000  0000000000000110 
00007ffd71b86330:  0000000000000140  00007f4014fa579e 
00007ffd71b86340:  0000000000000000  000000770000007c 
00007ffd71b86350:  000000000961cff0  0000000000000102 
00007ffd71b86360:  000000000961cfe0  0000000000000102 
00007ffd71b86370:  0000000000000110  00007f4014fa8f9b 
00007ffd71b86380:  35353240150c77d8  00007f40152fbc40 
00007ffd71b86390:  00007ffd71b863d0  0000000000000101 
00007ffd71b863a0:  0000000000000101  00007ffd71b86610 
00007ffd71b863b0: <0000000000000000  000000000961cff0 
00007ffd71b863c0:  0000000000000200  00007f4014f985e0 
00007ffd71b863d0:  00000000fbad8000  000000000961cff0 
00007ffd71b863e0:  000000000961d055  000000000961cff0 
00007ffd71b863f0:  000000000961cff0  000000000961d0f1 
00007ffd71b86400:  000000000961d11c  000000000961cff0 
00007ffd71b86410:  000000000961d11c  0000000000000000 
00007ffd71b86420:  0000000000000000  0000000000000000 
00007ffd71b86430:  fffffffe7fffffff  ffffffffffffffff 
00007ffd71b86440:  ffffffffffffffff  ffffffffffffffff 
00007ffd71b86450:  ffffffffffffffff  ffffffffffffffff 
00007ffd71b86460:  ffffffffffffffff  ffffffffffffffff 
00007ffd71b86470:  ffffffffffffffff  ffffffffffffffff 
00007ffd71b86480:  ffffffffffffffff  ffffffffffffffff 
00007ffd71b86490:  ffffffffffffffff  ffffffffffffffff 
00007ffd71b864a0:  ffffffffffffffff  ffffffffffffffff 

goroutine 1 [syscall]:
runtime.cgocall(0xc32f10, 0xc00662a568, 0x7f3ff0a4bf88)
    /usr/local/go/src/runtime/cgocall.go:128 +0x5b fp=0xc00662a538 sp=0xc00662a500 pc=0x8b8beb
tinygo.org/x/go-llvm._Cfunc_LLVMConstInsertValue(0x7f3ff0a4aef0, 0x961cf38, 0xc006bd1978, 0x2, 0x0)
    _cgo_gotypes.go:3201 +0x4e fp=0xc00662a568 sp=0xc00662a538 pc=0xa8efde
tinygo.org/x/go-llvm.ConstInsertValue.func1(0x7f3ff0a4aef0, 0x961cf38, 0xc006bd1978, 0x2, 0x7f3ff0a4bf88)
    /go/pkg/mod/tinygo.org/x/[email protected]/ir.go:989 +0xa2 fp=0xc00662a5a0 sp=0xc00662a568 pc=0xab50c2
tinygo.org/x/go-llvm.ConstInsertValue(0x7f3ff0a4aef0, 0x961cf38, 0xc006bd1978, 0x2, 0x2, 0x0)
    /go/pkg/mod/tinygo.org/x/[email protected]/ir.go:989 +0x4e fp=0xc00662a5d8 sp=0xc00662a5a0 pc=0xaa193e
github.com/tinygo-org/tinygo/interp.(*LocalValue).Store(0xc006bcdd70, 0x961cf38)
    /home/circleci/project/interp/values.go:86 +0x19e fp=0xc00662a640 sp=0xc00662a5d8 pc=0xbf5b5e
github.com/tinygo-org/tinygo/interp.(*frame).evalBasicBlock(0xc00662b1e0, 0x7f3ff0a4c5b0, 0x7f3ff0a4c160, 0x0, 0x0, 0x0, 0x0, 0xc006bc62f0, 0x1, 0x1, ...)
    /home/circleci/project/interp/frame.go:113 +0x1a77 fp=0xc00662b148 sp=0xc00662a640 pc=0xbeaf97
github.com/tinygo-org/tinygo/interp.(*Eval).function(0xc0049b8f30, 0x7f400403b0d8, 0xc00662b328, 0x2, 0x2, 0xc006ba79c0, 0x18, 0x0, 0x0, 0x0, ...)
    /home/circleci/project/interp/interp.go:104 +0x208 fp=0xc00662b218 sp=0xc00662b148 pc=0xbf4308
github.com/tinygo-org/tinygo/interp.(*Eval).Function(...)
    /home/circleci/project/interp/interp.go:87
github.com/tinygo-org/tinygo/interp.Run(0x74619a0, 0x7ffd00000000, 0x0, 0x0)
    /home/circleci/project/interp/interp.go:74 +0x6b2 fp=0xc00662b358 sp=0xc00662b218 pc=0xbf3d92
main.Compile(0x7ffd71b8723a, 0x10, 0x7ffd71b87220, 0x19, 0xc00000c1e0, 0xc00662be98, 0xc00662bc68, 0x0, 0x0)
    /home/circleci/project/main.go:152 +0xc5b fp=0xc00662bc20 sp=0xc00662b358 pc=0xc1e5bb
main.Build(0x7ffd71b8723a, 0x10, 0x7ffd71b87220, 0x19, 0x7ffd71b87218, 0x4, 0xc0000fbe98, 0xc00005e410, 0x8cd78e)
    /home/circleci/project/main.go:343 +0xe2 fp=0xc00662bc90 sp=0xc00662bc20 pc=0xc219d2
main.main()
    /home/circleci/project/main.go:836 +0x128d fp=0xc00662bf60 sp=0xc00662bc90 pc=0xc248bd
runtime.main()
    /usr/local/go/src/runtime/proc.go:203 +0x21e fp=0xc00662bfe0 sp=0xc00662bf60 pc=0x8e4fee
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1357 +0x1 fp=0xc00662bfe8 sp=0xc00662bfe0 pc=0x910271

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

rax    0x0
rbx    0x0
rcx    0x7f4014f4ee97
rdx    0x0
rdi    0x2
rsi    0x7ffd71b863b0
rbp    0x7f40150c77d8
rsp    0x7ffd71b863b0
r8     0x0
r9     0x7ffd71b863b0
r10    0x8
r11    0x246
r12    0x3e97a3c
r13    0x3e97a84
r14    0xff
r15    0x200
rip    0x7f4014f4ee97
rflags 0x246
cs     0x33
fs     0x0
gs     0x0

bug

All 10 comments

So far I've tracked it down to an included library, more specifically: https://github.com/OneOfOne/wjsu

Interestingly enough, the library does not import anything outside of "syscall/js" nor does it declare any constants... I'll continue to dig through.

This error is most likely caused by a global variable in one of the many packages. The "constant" it refers to is a different kind of constant as Go constants.

What I find interesting is that this build seems to be using the LLVM build with assertions enabled. It's nice to have for bugs like this, but it wasn't intended to be enabled. So I wonder how that got into a release build. @jadr2ddude any idea?

I've tracked the bug down this exact line: var Document = HTMLDocument{HTMLElement{document}} which is found in the global scope. If this line is commented out, or replaced with a getter, TinyGo builds it fine.

This code reproduces the error:

package main

import (
    "syscall/js"
)

var (
    document = js.Global().Get("document")
    Document = HTMLDocument{HTMLElement{document}}
)

type HTMLDocument struct {
    HTMLElement
}

type HTMLElement struct {
    v js.Value
}

func main() {

}

I've found that if you change document =js.Global().Get("document") to just document = js.Global() then it compiles fine.

I suspect the seed of this error is caused by the .Get() method ultimately calling js.valueGet which is not defined in Go.

I've also tried stashing the Document = HTMLDocument{HTMLElement{document}} declaration in an init() function but that results in this error:

panic: todo: store

goroutine 1 [running]:
github.com/tinygo-org/tinygo/interp.(*Eval).hasLocalSideEffects(0xc003e57b60, 0xc001a2a5b0, 0x7fd284a90fd8, 0xc003231768)
    /home/circleci/project/interp/scan.go:181 +0x1cf
github.com/tinygo-org/tinygo/interp.(*Eval).hasSideEffects(0xc003e57b60, 0x7fd28c03af18, 0x1)
    /home/circleci/project/interp/scan.go:121 +0x394
github.com/tinygo-org/tinygo/interp.(*frame).evalBasicBlock(0xc001a2b1e0, 0x7fd284a8fc00, 0x7fd284a8f7f0, 0x0, 0x0, 0x0, 0x0, 0xc0073e66d8, 0x1, 0x1, ...)
    /home/circleci/project/interp/frame.go:469 +0x581d
github.com/tinygo-org/tinygo/interp.(*Eval).function(0xc003e57b60, 0x7fd28c03ae18, 0xc001a2b328, 0x2, 0x2, 0xc0073e1b00, 0x18, 0x0, 0x0, 0x0, ...)
    /home/circleci/project/interp/interp.go:104 +0x208
github.com/tinygo-org/tinygo/interp.(*Eval).Function(...)
    /home/circleci/project/interp/interp.go:87
github.com/tinygo-org/tinygo/interp.Run(0x60119a0, 0x7ffc00000000, 0x0, 0x0)
    /home/circleci/project/interp/interp.go:74 +0x6b2
main.Compile(0x7ffcac995222, 0x10, 0x7ffcac995208, 0x19, 0xc000140000, 0xc001a2be98, 0xc001a2bc68, 0x0, 0x0)
    /home/circleci/project/main.go:152 +0xc5b
main.Build(0x7ffcac995222, 0x10, 0x7ffcac995208, 0x19, 0x7ffcac995200, 0x4, 0xc0000e1e98, 0xc0000f6250, 0x8cd78e)
    /home/circleci/project/main.go:343 +0xe2
main.main()
    /home/circleci/project/main.go:836 +0x128d

Even shorter reproducer:

package main

func foo() byte

var array = [1]byte{foo()}

func main() {
}

This bug should be fixed with #735.

@ellemlabs the related PR has been merged into the 0.10 branch, can you check whether you still encounter this bug?

This code has been released in v0.10.0 now closing.

Confirm this works now. Good work.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

andrewrynhard picture andrewrynhard  路  7Comments

cleahcim picture cleahcim  路  5Comments

Zambiorix picture Zambiorix  路  3Comments

wdevore picture wdevore  路  5Comments

johanbrandhorst picture johanbrandhorst  路  8Comments