Description: Fix support of 32 bits and big-endian arch
Origin: https://github.com/traefik/yaegi/commit/b7f9a39efff20637dfb01573f048012b22e90f86
Bug: https://github.com/traefik/yaegi/issues/1230
Bug-Debian: https://bugs.debian.org/992983
Forwarded: not-needed
Author: Marc Vertes <mvertes@free.fr>
Reviewed-by: Aloïs Micard <creekorful@debian.org>
Last-Update: 2021-08-28

--- a/_test/build0.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// A test program
-
-// +build darwin,linux !arm
-// +build go1.12 !go1.13
-
-package main
-
-func main() {
-	println("hello world")
-}
-
-// Output:
-// hello world
--- a/_test/const13.go
+++ b/_test/const13.go
@@ -9,7 +9,7 @@
 	const huge = 1 << 100
 	const large = huge >> 38
 
-	fmt.Println(large)
+	fmt.Println(int64(large))
 }
 
 // Output:
--- a/_test/const20.go
+++ b/_test/const20.go
@@ -2,7 +2,7 @@
 
 import "fmt"
 
-const maxLen = int64(int(^uint(0) >> 1))
+const maxLen = int64(int64(^uint64(0) >> 1))
 
 func main() {
 	fmt.Println(maxLen)
--- a/_test/unsafe3.go
+++ b/_test/unsafe3.go
@@ -1,11 +1,14 @@
 package main
 
 import (
-	"fmt"
+	"math/bits"
 	"unsafe"
 )
 
-const SSize = 16
+const (
+	SSize = 16
+	WSize = bits.UintSize / 8
+)
 
 type S struct {
 	X int
@@ -13,14 +16,19 @@
 }
 
 func main() {
+	bigEndian := (*(*[2]uint8)(unsafe.Pointer(&[]uint16{1}[0])))[0] == 0
 	var sBuf [SSize]byte
 	s := (*S)(unsafe.Pointer(&sBuf[0]))
 
 	s.X = 2
 	s.Y = 4
 
-	fmt.Println(sBuf)
+	if bigEndian {
+		println(sBuf[0+WSize-1], sBuf[WSize+WSize-1])
+	} else {
+		println(sBuf[0], sBuf[WSize])
+	}
 }
 
 // Output:
-// [2 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0]
+// 2 4
--- a/_test/unsafe4.go
+++ b/_test/unsafe4.go
@@ -2,10 +2,11 @@
 
 import (
 	"fmt"
+	"math/bits"
 	"unsafe"
 )
 
-const SSize = 24
+const WSize = bits.UintSize / 8
 
 type S struct {
 	X int
@@ -20,7 +21,8 @@
 		{X: 3},
 	}
 	addr := unsafe.Pointer(&arr[0])
-	s := *(*S)(unsafe.Pointer(uintptr(addr) + SSize*2))
+	// s := *(*S)(unsafe.Pointer(uintptr(addr) + SSize*2))
+	s := *(*S)(unsafe.Pointer(uintptr(addr) + WSize*6))
 
 	fmt.Println(s.X)
 }
--- a/_test/unsafe5.go
+++ b/_test/unsafe5.go
@@ -1,10 +1,12 @@
 package main
 
 import (
-	"fmt"
+	"math/bits"
 	"unsafe"
 )
 
+const WSize = bits.UintSize / 8
+
 type S struct {
 	X int
 	Y int
@@ -13,12 +15,12 @@
 
 func main() {
 	x := S{}
-	size := unsafe.Sizeof(x)
-	align := unsafe.Alignof(x.Y)
-	offset := unsafe.Offsetof(x.Z)
+	size := unsafe.Sizeof(x) / WSize
+	align := unsafe.Alignof(x.Y) / WSize
+	offset := unsafe.Offsetof(x.Z) / WSize
 
-	fmt.Println(size, align, offset)
+	println(size, align, offset)
 }
 
 // Output:
-// 24 8 16
+// 3 1 2
--- a/interp/interp.go
+++ b/interp/interp.go
@@ -7,11 +7,13 @@
 	"flag"
 	"fmt"
 	"go/build"
+	"go/constant"
 	"go/scanner"
 	"go/token"
 	"io"
 	"io/ioutil"
 	"log"
+	"math/bits"
 	"os"
 	"os/signal"
 	"path"
@@ -684,17 +686,17 @@
 	// Checks if input values correspond to stdlib packages by looking for one
 	// well known stdlib package path.
 	if _, ok := values["fmt/fmt"]; ok {
-		fixStdio(interp)
+		fixStdlib(interp)
 	}
 	return nil
 }
 
-// fixStdio redefines interpreter stdlib symbols to use the standard input,
+// fixStdlib redefines interpreter stdlib symbols to use the standard input,
 // output and errror assigned to the interpreter. The changes are limited to
 // the interpreter only.
 // Note that it is possible to escape the virtualized stdio by
 // read/write directly to file descriptors 0, 1, 2.
-func fixStdio(interp *Interpreter) {
+func fixStdlib(interp *Interpreter) {
 	p := interp.binPkg["fmt"]
 	if p == nil {
 		return
@@ -757,6 +759,11 @@
 			}
 		}
 	}
+
+	if p = interp.binPkg["math/bits"]; p != nil {
+		// Do not trust extracted value maybe from another arch.
+		p["UintSize"] = reflect.ValueOf(constant.MakeInt64(bits.UintSize))
+	}
 }
 
 // ignoreScannerError returns true if the error from Go scanner can be safely ignored
--- a/interp/interp_eval_test.go
+++ b/interp/interp_eval_test.go
@@ -75,7 +75,7 @@
 	i := interp.New(interp.Options{})
 	runTests(t, i, []testCase{
 		{src: "a, b, m := uint32(1), uint32(2), uint32(0); m = a + (1 << b)", res: "5"},
-		{src: "c := uint(1); d := uint(+(-(1 << c)))", res: "18446744073709551614"},
+		{src: "c := uint(1); d := uint64(+(-(1 << c)))", res: "18446744073709551614"},
 		{src: "e, f := uint32(0), uint32(0); f = 1 << -(e * 2)", res: "1"},
 		{src: "p := uint(0xdead); byte((1 << (p & 7)) - 1)", res: "31"},
 		{pre: func() { eval(t, i, "const k uint = 1 << 17") }, src: "int(k)", res: "131072"},
