tinygo-org / tinygo

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

interp: mis-interpretation of global map initializer #4505

Open eliasnaur opened 1 week ago

eliasnaur commented 1 week ago
$ cat precomp.go
package main

import (
    "crypto/sha256"
    "fmt"
    "os"
)

var (
    tag       = sha256.Sum256(nil)
    globalMap = map[string][32]byte{
        "": tag,
    }
)

func main() {
    localMap := map[string][32]byte{
        "": tag,
    }
    if localMap[""] != globalMap[""] {
        fmt.Printf("global %.32x\nlocal %.32x\n", globalMap, localMap)
        os.Exit(1)
    }
}
$ go run precomp.go
$ tinygo run precomp.go
global map[:0000000000000000000000000000000000000000000000000000000000000000]
local map[:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855]
failed to run compiled binary /tmp/nix-shell.HWhNg6/tinygo1488071277/main: exit status 1

This breaks anything relying on https://github.com/btcsuite/btcd/blob/67b8efd3ba53b60ff0eba5d79babe2c3d82f6c54/chaincfg/chainhash/hash.go#L50.

dgryski commented 1 week ago

Interestingly, switching the runtime hash to tsip allows this code to pass. I wonder if it's because interp decides not to run the tsip code for some reason.

~/go/src/github.com/dgryski/bug/interp $ for hash in fnv leveldb tsip; do echo $hash; tinygo run -tags=runtime_memhash_${hash} main.go; done
fnv
global map[:0000000000000000000000000000000000000000000000000000000000000000]
local map[:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855]
failed to run compiled binary /var/folders/5b/_hr1d1fd3qn4t9vtfx5p61wm0000gp/T/tinygo3541483627/main: exit status 1
leveldb
global map[:0000000000000000000000000000000000000000000000000000000000000000]
local map[:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855]
failed to run compiled binary /var/folders/5b/_hr1d1fd3qn4t9vtfx5p61wm0000gp/T/tinygo1726170860/main: exit status 1
tsip
~/go/src/github.com/dgryski/bug/interp $