Compare commits

..

2 Commits

Author SHA1 Message Date
Rob Findley
f8b1c17ace [dev.types] all: merge master into dev.types
Change-Id: Ia6964cb4e09153c15cc9c5b441373d1b3cb8f757
2020-09-11 14:23:34 -04:00
Rob Findley
e5d91ab096 [dev.types] internal/types: add an internal/types package
Add an internal/types package with placeholder AST interfaces.

Change-Id: Ib71cbce9668f02ca795b93a7526f460658708052
Reviewed-on: https://go-review.googlesource.com/c/go/+/251438
Reviewed-by: Robert Griesemer <gri@golang.org>
2020-09-08 21:28:06 +00:00
1522 changed files with 47337 additions and 75298 deletions

View File

@@ -2,56 +2,12 @@ pkg encoding/json, method (*RawMessage) MarshalJSON() ([]uint8, error)
pkg math/big, const MaxBase = 36
pkg math/big, type Word uintptr
pkg net, func ListenUnixgram(string, *UnixAddr) (*UDPConn, error)
pkg os (linux-arm), const O_SYNC = 1052672
pkg os (linux-arm), const O_SYNC = 4096
pkg os (linux-arm-cgo), const O_SYNC = 1052672
pkg os (linux-arm-cgo), const O_SYNC = 4096
pkg os, const ModeAppend FileMode
pkg os, const ModeCharDevice FileMode
pkg os, const ModeDevice FileMode
pkg os, const ModeDir FileMode
pkg os, const ModeExclusive FileMode
pkg os, const ModeIrregular FileMode
pkg os, const ModeNamedPipe FileMode
pkg os, const ModePerm FileMode
pkg os, const ModeSetgid FileMode
pkg os, const ModeSetuid FileMode
pkg os, const ModeSocket FileMode
pkg os, const ModeSticky FileMode
pkg os, const ModeSymlink FileMode
pkg os, const ModeTemporary FileMode
pkg os, const ModeType = 2399141888
pkg os, const ModeType = 2399666176
pkg os, const ModeType FileMode
pkg os, func Chmod(string, FileMode) error
pkg os, func Lstat(string) (FileInfo, error)
pkg os, func Mkdir(string, FileMode) error
pkg os, func MkdirAll(string, FileMode) error
pkg os, func OpenFile(string, int, FileMode) (*File, error)
pkg os, func SameFile(FileInfo, FileInfo) bool
pkg os, func Stat(string) (FileInfo, error)
pkg os, method (*File) Chmod(FileMode) error
pkg os, method (*File) Readdir(int) ([]FileInfo, error)
pkg os, method (*File) Stat() (FileInfo, error)
pkg os, method (*PathError) Error() string
pkg os, method (*PathError) Timeout() bool
pkg os, method (*PathError) Unwrap() error
pkg os, method (FileMode) IsDir() bool
pkg os, method (FileMode) IsRegular() bool
pkg os, method (FileMode) Perm() FileMode
pkg os, method (FileMode) String() string
pkg os, type FileInfo interface { IsDir, ModTime, Mode, Name, Size, Sys }
pkg os, type FileInfo interface, IsDir() bool
pkg os, type FileInfo interface, ModTime() time.Time
pkg os, type FileInfo interface, Mode() FileMode
pkg os, type FileInfo interface, Name() string
pkg os, type FileInfo interface, Size() int64
pkg os, type FileInfo interface, Sys() interface{}
pkg os, type FileMode uint32
pkg os, type PathError struct
pkg os, type PathError struct, Err error
pkg os, type PathError struct, Op string
pkg os, type PathError struct, Path string
pkg os (linux-arm), const O_SYNC = 4096
pkg os (linux-arm-cgo), const O_SYNC = 4096
pkg os (linux-arm), const O_SYNC = 1052672
pkg os (linux-arm-cgo), const O_SYNC = 1052672
pkg syscall (darwin-amd64), const ImplementsGetwd = false
pkg syscall (darwin-amd64), func Fchflags(string, int) error
pkg syscall (darwin-amd64-cgo), const ImplementsGetwd = false
@@ -62,72 +18,22 @@ pkg syscall (freebsd-386), const ELAST = 94
pkg syscall (freebsd-386), const ImplementsGetwd = false
pkg syscall (freebsd-386), const O_CLOEXEC = 0
pkg syscall (freebsd-386), func Fchflags(string, int) error
pkg syscall (freebsd-386), func Mknod(string, uint32, int) error
pkg syscall (freebsd-386), type Dirent struct, Fileno uint32
pkg syscall (freebsd-386), type Dirent struct, Namlen uint8
pkg syscall (freebsd-386), type Stat_t struct, Blksize uint32
pkg syscall (freebsd-386), type Stat_t struct, Dev uint32
pkg syscall (freebsd-386), type Stat_t struct, Gen uint32
pkg syscall (freebsd-386), type Stat_t struct, Ino uint32
pkg syscall (freebsd-386), type Stat_t struct, Lspare int32
pkg syscall (freebsd-386), type Stat_t struct, Nlink uint16
pkg syscall (freebsd-386), type Stat_t struct, Pad_cgo_0 [8]uint8
pkg syscall (freebsd-386), type Stat_t struct, Rdev uint32
pkg syscall (freebsd-386), type Statfs_t struct, Mntfromname [88]int8
pkg syscall (freebsd-386), type Statfs_t struct, Mntonname [88]int8
pkg syscall (freebsd-386-cgo), const AF_MAX = 38
pkg syscall (freebsd-386-cgo), const DLT_MATCHING_MAX = 242
pkg syscall (freebsd-386-cgo), const ELAST = 94
pkg syscall (freebsd-386-cgo), const ImplementsGetwd = false
pkg syscall (freebsd-386-cgo), const O_CLOEXEC = 0
pkg syscall (freebsd-386-cgo), func Mknod(string, uint32, int) error
pkg syscall (freebsd-386-cgo), type Dirent struct, Fileno uint32
pkg syscall (freebsd-386-cgo), type Dirent struct, Namlen uint8
pkg syscall (freebsd-386-cgo), type Stat_t struct, Blksize uint32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Dev uint32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Gen uint32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Ino uint32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Lspare int32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Nlink uint16
pkg syscall (freebsd-386-cgo), type Stat_t struct, Pad_cgo_0 [8]uint8
pkg syscall (freebsd-386-cgo), type Stat_t struct, Rdev uint32
pkg syscall (freebsd-386-cgo), type Statfs_t struct, Mntfromname [88]int8
pkg syscall (freebsd-386-cgo), type Statfs_t struct, Mntonname [88]int8
pkg syscall (freebsd-amd64), const AF_MAX = 38
pkg syscall (freebsd-amd64), const DLT_MATCHING_MAX = 242
pkg syscall (freebsd-amd64), const ELAST = 94
pkg syscall (freebsd-amd64), const ImplementsGetwd = false
pkg syscall (freebsd-amd64), const O_CLOEXEC = 0
pkg syscall (freebsd-amd64), func Fchflags(string, int) error
pkg syscall (freebsd-amd64), func Mknod(string, uint32, int) error
pkg syscall (freebsd-amd64), type Dirent struct, Fileno uint32
pkg syscall (freebsd-amd64), type Dirent struct, Namlen uint8
pkg syscall (freebsd-amd64), type Stat_t struct, Blksize uint32
pkg syscall (freebsd-amd64), type Stat_t struct, Dev uint32
pkg syscall (freebsd-amd64), type Stat_t struct, Gen uint32
pkg syscall (freebsd-amd64), type Stat_t struct, Ino uint32
pkg syscall (freebsd-amd64), type Stat_t struct, Lspare int32
pkg syscall (freebsd-amd64), type Stat_t struct, Nlink uint16
pkg syscall (freebsd-amd64), type Stat_t struct, Rdev uint32
pkg syscall (freebsd-amd64), type Statfs_t struct, Mntfromname [88]int8
pkg syscall (freebsd-amd64), type Statfs_t struct, Mntonname [88]int8
pkg syscall (freebsd-amd64-cgo), const AF_MAX = 38
pkg syscall (freebsd-amd64-cgo), const DLT_MATCHING_MAX = 242
pkg syscall (freebsd-amd64-cgo), const ELAST = 94
pkg syscall (freebsd-amd64-cgo), const ImplementsGetwd = false
pkg syscall (freebsd-amd64-cgo), const O_CLOEXEC = 0
pkg syscall (freebsd-amd64-cgo), func Mknod(string, uint32, int) error
pkg syscall (freebsd-amd64-cgo), type Dirent struct, Fileno uint32
pkg syscall (freebsd-amd64-cgo), type Dirent struct, Namlen uint8
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Blksize uint32
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Dev uint32
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Gen uint32
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Ino uint32
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Lspare int32
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Nlink uint16
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Rdev uint32
pkg syscall (freebsd-amd64-cgo), type Statfs_t struct, Mntfromname [88]int8
pkg syscall (freebsd-amd64-cgo), type Statfs_t struct, Mntonname [88]int8
pkg syscall (freebsd-arm), const AF_MAX = 38
pkg syscall (freebsd-arm), const BIOCGRTIMEOUT = 1074545262
pkg syscall (freebsd-arm), const BIOCSRTIMEOUT = 2148287085
@@ -156,22 +62,10 @@ pkg syscall (freebsd-arm), const SizeofSockaddrDatalink = 56
pkg syscall (freebsd-arm), const SizeofSockaddrUnix = 108
pkg syscall (freebsd-arm), const TIOCTIMESTAMP = 1074558041
pkg syscall (freebsd-arm), func Fchflags(string, int) error
pkg syscall (freebsd-arm), func Mknod(string, uint32, int) error
pkg syscall (freebsd-arm), type BpfHdr struct, Pad_cgo_0 [2]uint8
pkg syscall (freebsd-arm), type Dirent struct, Fileno uint32
pkg syscall (freebsd-arm), type Dirent struct, Namlen uint8
pkg syscall (freebsd-arm), type RawSockaddrDatalink struct, Pad_cgo_0 [2]uint8
pkg syscall (freebsd-arm), type RawSockaddrUnix struct, Pad_cgo_0 [2]uint8
pkg syscall (freebsd-arm), type Stat_t struct, Blksize uint32
pkg syscall (freebsd-arm), type Stat_t struct, Dev uint32
pkg syscall (freebsd-arm), type Stat_t struct, Gen uint32
pkg syscall (freebsd-arm), type Stat_t struct, Ino uint32
pkg syscall (freebsd-arm), type Stat_t struct, Lspare int32
pkg syscall (freebsd-arm), type Stat_t struct, Nlink uint16
pkg syscall (freebsd-arm), type Stat_t struct, Pad_cgo_0 [4]uint8
pkg syscall (freebsd-arm), type Stat_t struct, Rdev uint32
pkg syscall (freebsd-arm), type Statfs_t struct, Mntfromname [88]int8
pkg syscall (freebsd-arm), type Statfs_t struct, Mntonname [88]int8
pkg syscall (freebsd-arm-cgo), const AF_MAX = 38
pkg syscall (freebsd-arm-cgo), const BIOCGRTIMEOUT = 1074545262
pkg syscall (freebsd-arm-cgo), const BIOCSRTIMEOUT = 2148287085
@@ -200,22 +94,10 @@ pkg syscall (freebsd-arm-cgo), const SizeofSockaddrDatalink = 56
pkg syscall (freebsd-arm-cgo), const SizeofSockaddrUnix = 108
pkg syscall (freebsd-arm-cgo), const TIOCTIMESTAMP = 1074558041
pkg syscall (freebsd-arm-cgo), func Fchflags(string, int) error
pkg syscall (freebsd-arm-cgo), func Mknod(string, uint32, int) error
pkg syscall (freebsd-arm-cgo), type BpfHdr struct, Pad_cgo_0 [2]uint8
pkg syscall (freebsd-arm-cgo), type Dirent struct, Fileno uint32
pkg syscall (freebsd-arm-cgo), type Dirent struct, Namlen uint8
pkg syscall (freebsd-arm-cgo), type RawSockaddrDatalink struct, Pad_cgo_0 [2]uint8
pkg syscall (freebsd-arm-cgo), type RawSockaddrUnix struct, Pad_cgo_0 [2]uint8
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Blksize uint32
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Dev uint32
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Gen uint32
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Ino uint32
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Lspare int32
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Nlink uint16
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Pad_cgo_0 [4]uint8
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Rdev uint32
pkg syscall (freebsd-arm-cgo), type Statfs_t struct, Mntfromname [88]int8
pkg syscall (freebsd-arm-cgo), type Statfs_t struct, Mntonname [88]int8
pkg syscall (linux-386), type Cmsghdr struct, X__cmsg_data [0]uint8
pkg syscall (linux-386-cgo), type Cmsghdr struct, X__cmsg_data [0]uint8
pkg syscall (linux-amd64), type Cmsghdr struct, X__cmsg_data [0]uint8
@@ -227,10 +109,10 @@ pkg syscall (netbsd-386-cgo), const ImplementsGetwd = false
pkg syscall (netbsd-amd64), const ImplementsGetwd = false
pkg syscall (netbsd-amd64-cgo), const ImplementsGetwd = false
pkg syscall (netbsd-arm), const ImplementsGetwd = false
pkg syscall (netbsd-arm-cgo), const ImplementsGetwd = false
pkg syscall (netbsd-arm), const SizeofIfData = 132
pkg syscall (netbsd-arm), func Fchflags(string, int) error
pkg syscall (netbsd-arm), type IfMsghdr struct, Pad_cgo_1 [4]uint8
pkg syscall (netbsd-arm-cgo), const ImplementsGetwd = false
pkg syscall (netbsd-arm-cgo), const SizeofIfData = 132
pkg syscall (netbsd-arm-cgo), func Fchflags(string, int) error
pkg syscall (netbsd-arm-cgo), type IfMsghdr struct, Pad_cgo_1 [4]uint8
@@ -258,7 +140,6 @@ pkg syscall (openbsd-386), const SYS_GETITIMER = 86
pkg syscall (openbsd-386), const SYS_GETRUSAGE = 117
pkg syscall (openbsd-386), const SYS_GETTIMEOFDAY = 116
pkg syscall (openbsd-386), const SYS_KEVENT = 270
pkg syscall (openbsd-386), const SYS_KILL = 37
pkg syscall (openbsd-386), const SYS_LSTAT = 293
pkg syscall (openbsd-386), const SYS_NANOSLEEP = 240
pkg syscall (openbsd-386), const SYS_SELECT = 93
@@ -312,7 +193,6 @@ pkg syscall (openbsd-386-cgo), const SYS_GETITIMER = 86
pkg syscall (openbsd-386-cgo), const SYS_GETRUSAGE = 117
pkg syscall (openbsd-386-cgo), const SYS_GETTIMEOFDAY = 116
pkg syscall (openbsd-386-cgo), const SYS_KEVENT = 270
pkg syscall (openbsd-386-cgo), const SYS_KILL = 37
pkg syscall (openbsd-386-cgo), const SYS_LSTAT = 293
pkg syscall (openbsd-386-cgo), const SYS_NANOSLEEP = 240
pkg syscall (openbsd-386-cgo), const SYS_SELECT = 93
@@ -377,7 +257,6 @@ pkg syscall (openbsd-amd64), const SYS_GETITIMER = 86
pkg syscall (openbsd-amd64), const SYS_GETRUSAGE = 117
pkg syscall (openbsd-amd64), const SYS_GETTIMEOFDAY = 116
pkg syscall (openbsd-amd64), const SYS_KEVENT = 270
pkg syscall (openbsd-amd64), const SYS_KILL = 37
pkg syscall (openbsd-amd64), const SYS_LSTAT = 293
pkg syscall (openbsd-amd64), const SYS_NANOSLEEP = 240
pkg syscall (openbsd-amd64), const SYS_SELECT = 93
@@ -441,7 +320,6 @@ pkg syscall (openbsd-amd64-cgo), const SYS_GETITIMER = 86
pkg syscall (openbsd-amd64-cgo), const SYS_GETRUSAGE = 117
pkg syscall (openbsd-amd64-cgo), const SYS_GETTIMEOFDAY = 116
pkg syscall (openbsd-amd64-cgo), const SYS_KEVENT = 270
pkg syscall (openbsd-amd64-cgo), const SYS_KILL = 37
pkg syscall (openbsd-amd64-cgo), const SYS_LSTAT = 293
pkg syscall (openbsd-amd64-cgo), const SYS_NANOSLEEP = 240
pkg syscall (openbsd-amd64-cgo), const SYS_SELECT = 93
@@ -470,6 +348,19 @@ pkg syscall (openbsd-amd64-cgo), type Statfs_t struct, F_spare [3]uint32
pkg syscall (openbsd-amd64-cgo), type Statfs_t struct, Pad_cgo_1 [4]uint8
pkg syscall (openbsd-amd64-cgo), type Timespec struct, Pad_cgo_0 [4]uint8
pkg syscall (openbsd-amd64-cgo), type Timespec struct, Sec int32
pkg testing, func RegisterCover(Cover)
pkg testing, func MainStart(func(string, string) (bool, error), []InternalTest, []InternalBenchmark, []InternalExample) *M
pkg text/template/parse, type DotNode bool
pkg text/template/parse, type Node interface { Copy, String, Type }
pkg unicode, const Version = "6.2.0"
pkg unicode, const Version = "6.3.0"
pkg unicode, const Version = "7.0.0"
pkg unicode, const Version = "8.0.0"
pkg syscall (openbsd-386), const SYS_KILL = 37
pkg syscall (openbsd-386-cgo), const SYS_KILL = 37
pkg syscall (openbsd-amd64), const SYS_KILL = 37
pkg syscall (openbsd-amd64-cgo), const SYS_KILL = 37
pkg unicode, const Version = "9.0.0"
pkg syscall (windows-386), const TOKEN_ALL_ACCESS = 983295
pkg syscall (windows-386), type AddrinfoW struct, Addr uintptr
pkg syscall (windows-386), type CertChainPolicyPara struct, ExtraPolicyPara uintptr
@@ -488,16 +379,81 @@ pkg syscall (windows-amd64), type CertRevocationInfo struct, CrlInfo uintptr
pkg syscall (windows-amd64), type CertRevocationInfo struct, OidSpecificInfo uintptr
pkg syscall (windows-amd64), type CertSimpleChain struct, TrustListInfo uintptr
pkg syscall (windows-amd64), type RawSockaddrAny struct, Pad [96]int8
pkg testing, func MainStart(func(string, string) (bool, error), []InternalTest, []InternalBenchmark, []InternalExample) *M
pkg testing, func RegisterCover(Cover)
pkg syscall (freebsd-386), func Mknod(string, uint32, int) error
pkg syscall (freebsd-386), type Dirent struct, Fileno uint32
pkg syscall (freebsd-386), type Dirent struct, Namlen uint8
pkg syscall (freebsd-386), type Stat_t struct, Blksize uint32
pkg syscall (freebsd-386), type Stat_t struct, Dev uint32
pkg syscall (freebsd-386), type Stat_t struct, Gen uint32
pkg syscall (freebsd-386), type Stat_t struct, Ino uint32
pkg syscall (freebsd-386), type Stat_t struct, Lspare int32
pkg syscall (freebsd-386), type Stat_t struct, Nlink uint16
pkg syscall (freebsd-386), type Stat_t struct, Pad_cgo_0 [8]uint8
pkg syscall (freebsd-386), type Stat_t struct, Rdev uint32
pkg syscall (freebsd-386), type Statfs_t struct, Mntfromname [88]int8
pkg syscall (freebsd-386), type Statfs_t struct, Mntonname [88]int8
pkg syscall (freebsd-386-cgo), func Mknod(string, uint32, int) error
pkg syscall (freebsd-386-cgo), type Dirent struct, Fileno uint32
pkg syscall (freebsd-386-cgo), type Dirent struct, Namlen uint8
pkg syscall (freebsd-386-cgo), type Stat_t struct, Blksize uint32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Dev uint32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Gen uint32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Ino uint32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Lspare int32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Nlink uint16
pkg syscall (freebsd-386-cgo), type Stat_t struct, Pad_cgo_0 [8]uint8
pkg syscall (freebsd-386-cgo), type Stat_t struct, Rdev uint32
pkg syscall (freebsd-386-cgo), type Statfs_t struct, Mntfromname [88]int8
pkg syscall (freebsd-386-cgo), type Statfs_t struct, Mntonname [88]int8
pkg syscall (freebsd-amd64), func Mknod(string, uint32, int) error
pkg syscall (freebsd-amd64), type Dirent struct, Fileno uint32
pkg syscall (freebsd-amd64), type Dirent struct, Namlen uint8
pkg syscall (freebsd-amd64), type Stat_t struct, Blksize uint32
pkg syscall (freebsd-amd64), type Stat_t struct, Dev uint32
pkg syscall (freebsd-amd64), type Stat_t struct, Gen uint32
pkg syscall (freebsd-amd64), type Stat_t struct, Ino uint32
pkg syscall (freebsd-amd64), type Stat_t struct, Lspare int32
pkg syscall (freebsd-amd64), type Stat_t struct, Nlink uint16
pkg syscall (freebsd-amd64), type Stat_t struct, Rdev uint32
pkg syscall (freebsd-amd64), type Statfs_t struct, Mntfromname [88]int8
pkg syscall (freebsd-amd64), type Statfs_t struct, Mntonname [88]int8
pkg syscall (freebsd-amd64-cgo), func Mknod(string, uint32, int) error
pkg syscall (freebsd-amd64-cgo), type Dirent struct, Fileno uint32
pkg syscall (freebsd-amd64-cgo), type Dirent struct, Namlen uint8
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Blksize uint32
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Dev uint32
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Gen uint32
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Ino uint32
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Lspare int32
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Nlink uint16
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Rdev uint32
pkg syscall (freebsd-amd64-cgo), type Statfs_t struct, Mntfromname [88]int8
pkg syscall (freebsd-amd64-cgo), type Statfs_t struct, Mntonname [88]int8
pkg syscall (freebsd-arm), func Mknod(string, uint32, int) error
pkg syscall (freebsd-arm), type Dirent struct, Fileno uint32
pkg syscall (freebsd-arm), type Dirent struct, Namlen uint8
pkg syscall (freebsd-arm), type Stat_t struct, Blksize uint32
pkg syscall (freebsd-arm), type Stat_t struct, Dev uint32
pkg syscall (freebsd-arm), type Stat_t struct, Gen uint32
pkg syscall (freebsd-arm), type Stat_t struct, Ino uint32
pkg syscall (freebsd-arm), type Stat_t struct, Lspare int32
pkg syscall (freebsd-arm), type Stat_t struct, Nlink uint16
pkg syscall (freebsd-arm), type Stat_t struct, Rdev uint32
pkg syscall (freebsd-arm), type Statfs_t struct, Mntfromname [88]int8
pkg syscall (freebsd-arm), type Statfs_t struct, Mntonname [88]int8
pkg syscall (freebsd-arm-cgo), func Mknod(string, uint32, int) error
pkg syscall (freebsd-arm-cgo), type Dirent struct, Fileno uint32
pkg syscall (freebsd-arm-cgo), type Dirent struct, Namlen uint8
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Blksize uint32
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Dev uint32
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Gen uint32
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Ino uint32
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Lspare int32
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Nlink uint16
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Rdev uint32
pkg syscall (freebsd-arm-cgo), type Statfs_t struct, Mntfromname [88]int8
pkg syscall (freebsd-arm-cgo), type Statfs_t struct, Mntonname [88]int8
pkg text/scanner, const GoTokens = 1012
pkg text/template/parse, type DotNode bool
pkg text/template/parse, type Node interface { Copy, String, Type }
pkg unicode, const Version = "10.0.0"
pkg unicode, const Version = "11.0.0"
pkg unicode, const Version = "12.0.0"
pkg unicode, const Version = "6.2.0"
pkg unicode, const Version = "6.3.0"
pkg unicode, const Version = "7.0.0"
pkg unicode, const Version = "8.0.0"
pkg unicode, const Version = "9.0.0"

View File

@@ -1,321 +1,8 @@
pkg debug/elf, const DT_ADDRRNGHI = 1879047935
pkg debug/elf, const DT_ADDRRNGHI DynTag
pkg debug/elf, const DT_ADDRRNGLO = 1879047680
pkg debug/elf, const DT_ADDRRNGLO DynTag
pkg debug/elf, const DT_AUDIT = 1879047932
pkg debug/elf, const DT_AUDIT DynTag
pkg debug/elf, const DT_AUXILIARY = 2147483645
pkg debug/elf, const DT_AUXILIARY DynTag
pkg debug/elf, const DT_CHECKSUM = 1879047672
pkg debug/elf, const DT_CHECKSUM DynTag
pkg debug/elf, const DT_CONFIG = 1879047930
pkg debug/elf, const DT_CONFIG DynTag
pkg debug/elf, const DT_DEPAUDIT = 1879047931
pkg debug/elf, const DT_DEPAUDIT DynTag
pkg debug/elf, const DT_FEATURE = 1879047676
pkg debug/elf, const DT_FEATURE DynTag
pkg debug/elf, const DT_FILTER = 2147483647
pkg debug/elf, const DT_FILTER DynTag
pkg debug/elf, const DT_FLAGS_1 = 1879048187
pkg debug/elf, const DT_FLAGS_1 DynTag
pkg debug/elf, const DT_GNU_CONFLICT = 1879047928
pkg debug/elf, const DT_GNU_CONFLICT DynTag
pkg debug/elf, const DT_GNU_CONFLICTSZ = 1879047670
pkg debug/elf, const DT_GNU_CONFLICTSZ DynTag
pkg debug/elf, const DT_GNU_HASH = 1879047925
pkg debug/elf, const DT_GNU_HASH DynTag
pkg debug/elf, const DT_GNU_LIBLIST = 1879047929
pkg debug/elf, const DT_GNU_LIBLIST DynTag
pkg debug/elf, const DT_GNU_LIBLISTSZ = 1879047671
pkg debug/elf, const DT_GNU_LIBLISTSZ DynTag
pkg debug/elf, const DT_GNU_PRELINKED = 1879047669
pkg debug/elf, const DT_GNU_PRELINKED DynTag
pkg debug/elf, const DT_MIPS_AUX_DYNAMIC = 1879048241
pkg debug/elf, const DT_MIPS_AUX_DYNAMIC DynTag
pkg debug/elf, const DT_MIPS_BASE_ADDRESS = 1879048198
pkg debug/elf, const DT_MIPS_BASE_ADDRESS DynTag
pkg debug/elf, const DT_MIPS_COMPACT_SIZE = 1879048239
pkg debug/elf, const DT_MIPS_COMPACT_SIZE DynTag
pkg debug/elf, const DT_MIPS_CONFLICT = 1879048200
pkg debug/elf, const DT_MIPS_CONFLICT DynTag
pkg debug/elf, const DT_MIPS_CONFLICTNO = 1879048203
pkg debug/elf, const DT_MIPS_CONFLICTNO DynTag
pkg debug/elf, const DT_MIPS_CXX_FLAGS = 1879048226
pkg debug/elf, const DT_MIPS_CXX_FLAGS DynTag
pkg debug/elf, const DT_MIPS_DELTA_CLASS = 1879048215
pkg debug/elf, const DT_MIPS_DELTA_CLASS DynTag
pkg debug/elf, const DT_MIPS_DELTA_CLASSSYM = 1879048224
pkg debug/elf, const DT_MIPS_DELTA_CLASSSYM DynTag
pkg debug/elf, const DT_MIPS_DELTA_CLASSSYM_NO = 1879048225
pkg debug/elf, const DT_MIPS_DELTA_CLASSSYM_NO DynTag
pkg debug/elf, const DT_MIPS_DELTA_CLASS_NO = 1879048216
pkg debug/elf, const DT_MIPS_DELTA_CLASS_NO DynTag
pkg debug/elf, const DT_MIPS_DELTA_INSTANCE = 1879048217
pkg debug/elf, const DT_MIPS_DELTA_INSTANCE DynTag
pkg debug/elf, const DT_MIPS_DELTA_INSTANCE_NO = 1879048218
pkg debug/elf, const DT_MIPS_DELTA_INSTANCE_NO DynTag
pkg debug/elf, const DT_MIPS_DELTA_RELOC = 1879048219
pkg debug/elf, const DT_MIPS_DELTA_RELOC DynTag
pkg debug/elf, const DT_MIPS_DELTA_RELOC_NO = 1879048220
pkg debug/elf, const DT_MIPS_DELTA_RELOC_NO DynTag
pkg debug/elf, const DT_MIPS_DELTA_SYM = 1879048221
pkg debug/elf, const DT_MIPS_DELTA_SYM DynTag
pkg debug/elf, const DT_MIPS_DELTA_SYM_NO = 1879048222
pkg debug/elf, const DT_MIPS_DELTA_SYM_NO DynTag
pkg debug/elf, const DT_MIPS_DYNSTR_ALIGN = 1879048235
pkg debug/elf, const DT_MIPS_DYNSTR_ALIGN DynTag
pkg debug/elf, const DT_MIPS_FLAGS = 1879048197
pkg debug/elf, const DT_MIPS_FLAGS DynTag
pkg debug/elf, const DT_MIPS_GOTSYM = 1879048211
pkg debug/elf, const DT_MIPS_GOTSYM DynTag
pkg debug/elf, const DT_MIPS_GP_VALUE = 1879048240
pkg debug/elf, const DT_MIPS_GP_VALUE DynTag
pkg debug/elf, const DT_MIPS_HIDDEN_GOTIDX = 1879048231
pkg debug/elf, const DT_MIPS_HIDDEN_GOTIDX DynTag
pkg debug/elf, const DT_MIPS_HIPAGENO = 1879048212
pkg debug/elf, const DT_MIPS_HIPAGENO DynTag
pkg debug/elf, const DT_MIPS_ICHECKSUM = 1879048195
pkg debug/elf, const DT_MIPS_ICHECKSUM DynTag
pkg debug/elf, const DT_MIPS_INTERFACE = 1879048234
pkg debug/elf, const DT_MIPS_INTERFACE DynTag
pkg debug/elf, const DT_MIPS_INTERFACE_SIZE = 1879048236
pkg debug/elf, const DT_MIPS_INTERFACE_SIZE DynTag
pkg debug/elf, const DT_MIPS_IVERSION = 1879048196
pkg debug/elf, const DT_MIPS_IVERSION DynTag
pkg debug/elf, const DT_MIPS_LIBLIST = 1879048201
pkg debug/elf, const DT_MIPS_LIBLIST DynTag
pkg debug/elf, const DT_MIPS_LIBLISTNO = 1879048208
pkg debug/elf, const DT_MIPS_LIBLISTNO DynTag
pkg debug/elf, const DT_MIPS_LOCALPAGE_GOTIDX = 1879048229
pkg debug/elf, const DT_MIPS_LOCALPAGE_GOTIDX DynTag
pkg debug/elf, const DT_MIPS_LOCAL_GOTIDX = 1879048230
pkg debug/elf, const DT_MIPS_LOCAL_GOTIDX DynTag
pkg debug/elf, const DT_MIPS_LOCAL_GOTNO = 1879048202
pkg debug/elf, const DT_MIPS_LOCAL_GOTNO DynTag
pkg debug/elf, const DT_MIPS_MSYM = 1879048199
pkg debug/elf, const DT_MIPS_MSYM DynTag
pkg debug/elf, const DT_MIPS_OPTIONS = 1879048233
pkg debug/elf, const DT_MIPS_OPTIONS DynTag
pkg debug/elf, const DT_MIPS_PERF_SUFFIX = 1879048238
pkg debug/elf, const DT_MIPS_PERF_SUFFIX DynTag
pkg debug/elf, const DT_MIPS_PIXIE_INIT = 1879048227
pkg debug/elf, const DT_MIPS_PIXIE_INIT DynTag
pkg debug/elf, const DT_MIPS_PLTGOT = 1879048242
pkg debug/elf, const DT_MIPS_PLTGOT DynTag
pkg debug/elf, const DT_MIPS_PROTECTED_GOTIDX = 1879048232
pkg debug/elf, const DT_MIPS_PROTECTED_GOTIDX DynTag
pkg debug/elf, const DT_MIPS_RLD_MAP = 1879048214
pkg debug/elf, const DT_MIPS_RLD_MAP DynTag
pkg debug/elf, const DT_MIPS_RLD_MAP_REL = 1879048245
pkg debug/elf, const DT_MIPS_RLD_MAP_REL DynTag
pkg debug/elf, const DT_MIPS_RLD_TEXT_RESOLVE_ADDR = 1879048237
pkg debug/elf, const DT_MIPS_RLD_TEXT_RESOLVE_ADDR DynTag
pkg debug/elf, const DT_MIPS_RLD_VERSION = 1879048193
pkg debug/elf, const DT_MIPS_RLD_VERSION DynTag
pkg debug/elf, const DT_MIPS_RWPLT = 1879048244
pkg debug/elf, const DT_MIPS_RWPLT DynTag
pkg debug/elf, const DT_MIPS_SYMBOL_LIB = 1879048228
pkg debug/elf, const DT_MIPS_SYMBOL_LIB DynTag
pkg debug/elf, const DT_MIPS_SYMTABNO = 1879048209
pkg debug/elf, const DT_MIPS_SYMTABNO DynTag
pkg debug/elf, const DT_MIPS_TIME_STAMP = 1879048194
pkg debug/elf, const DT_MIPS_TIME_STAMP DynTag
pkg debug/elf, const DT_MIPS_UNREFEXTNO = 1879048210
pkg debug/elf, const DT_MIPS_UNREFEXTNO DynTag
pkg debug/elf, const DT_MOVEENT = 1879047674
pkg debug/elf, const DT_MOVEENT DynTag
pkg debug/elf, const DT_MOVESZ = 1879047675
pkg debug/elf, const DT_MOVESZ DynTag
pkg debug/elf, const DT_MOVETAB = 1879047934
pkg debug/elf, const DT_MOVETAB DynTag
pkg debug/elf, const DT_PLTPAD = 1879047933
pkg debug/elf, const DT_PLTPAD DynTag
pkg debug/elf, const DT_PLTPADSZ = 1879047673
pkg debug/elf, const DT_PLTPADSZ DynTag
pkg debug/elf, const DT_POSFLAG_1 = 1879047677
pkg debug/elf, const DT_POSFLAG_1 DynTag
pkg debug/elf, const DT_PPC64_GLINK = 1879048192
pkg debug/elf, const DT_PPC64_GLINK DynTag
pkg debug/elf, const DT_PPC64_OPD = 1879048193
pkg debug/elf, const DT_PPC64_OPD DynTag
pkg debug/elf, const DT_PPC64_OPDSZ = 1879048194
pkg debug/elf, const DT_PPC64_OPDSZ DynTag
pkg debug/elf, const DT_PPC64_OPT = 1879048195
pkg debug/elf, const DT_PPC64_OPT DynTag
pkg debug/elf, const DT_PPC_GOT = 1879048192
pkg debug/elf, const DT_PPC_GOT DynTag
pkg debug/elf, const DT_PPC_OPT = 1879048193
pkg debug/elf, const DT_PPC_OPT DynTag
pkg debug/elf, const DT_RELACOUNT = 1879048185
pkg debug/elf, const DT_RELACOUNT DynTag
pkg debug/elf, const DT_RELCOUNT = 1879048186
pkg debug/elf, const DT_RELCOUNT DynTag
pkg debug/elf, const DT_SPARC_REGISTER = 1879048193
pkg debug/elf, const DT_SPARC_REGISTER DynTag
pkg debug/elf, const DT_SYMINENT = 1879047679
pkg debug/elf, const DT_SYMINENT DynTag
pkg debug/elf, const DT_SYMINFO = 1879047935
pkg debug/elf, const DT_SYMINFO DynTag
pkg debug/elf, const DT_SYMINSZ = 1879047678
pkg debug/elf, const DT_SYMINSZ DynTag
pkg debug/elf, const DT_SYMTAB_SHNDX = 34
pkg debug/elf, const DT_SYMTAB_SHNDX DynTag
pkg debug/elf, const DT_TLSDESC_GOT = 1879047927
pkg debug/elf, const DT_TLSDESC_GOT DynTag
pkg debug/elf, const DT_TLSDESC_PLT = 1879047926
pkg debug/elf, const DT_TLSDESC_PLT DynTag
pkg debug/elf, const DT_USED = 2147483646
pkg debug/elf, const DT_USED DynTag
pkg debug/elf, const DT_VALRNGHI = 1879047679
pkg debug/elf, const DT_VALRNGHI DynTag
pkg debug/elf, const DT_VALRNGLO = 1879047424
pkg debug/elf, const DT_VALRNGLO DynTag
pkg debug/elf, const DT_VERDEF = 1879048188
pkg debug/elf, const DT_VERDEF DynTag
pkg debug/elf, const DT_VERDEFNUM = 1879048189
pkg debug/elf, const DT_VERDEFNUM DynTag
pkg debug/elf, const PT_AARCH64_ARCHEXT = 1879048192
pkg debug/elf, const PT_AARCH64_ARCHEXT ProgType
pkg debug/elf, const PT_AARCH64_UNWIND = 1879048193
pkg debug/elf, const PT_AARCH64_UNWIND ProgType
pkg debug/elf, const PT_ARM_ARCHEXT = 1879048192
pkg debug/elf, const PT_ARM_ARCHEXT ProgType
pkg debug/elf, const PT_ARM_EXIDX = 1879048193
pkg debug/elf, const PT_ARM_EXIDX ProgType
pkg debug/elf, const PT_GNU_EH_FRAME = 1685382480
pkg debug/elf, const PT_GNU_EH_FRAME ProgType
pkg debug/elf, const PT_GNU_MBIND_HI = 1685386580
pkg debug/elf, const PT_GNU_MBIND_HI ProgType
pkg debug/elf, const PT_GNU_MBIND_LO = 1685382485
pkg debug/elf, const PT_GNU_MBIND_LO ProgType
pkg debug/elf, const PT_GNU_PROPERTY = 1685382483
pkg debug/elf, const PT_GNU_PROPERTY ProgType
pkg debug/elf, const PT_GNU_RELRO = 1685382482
pkg debug/elf, const PT_GNU_RELRO ProgType
pkg debug/elf, const PT_GNU_STACK = 1685382481
pkg debug/elf, const PT_GNU_STACK ProgType
pkg debug/elf, const PT_MIPS_ABIFLAGS = 1879048195
pkg debug/elf, const PT_MIPS_ABIFLAGS ProgType
pkg debug/elf, const PT_MIPS_OPTIONS = 1879048194
pkg debug/elf, const PT_MIPS_OPTIONS ProgType
pkg debug/elf, const PT_MIPS_REGINFO = 1879048192
pkg debug/elf, const PT_MIPS_REGINFO ProgType
pkg debug/elf, const PT_MIPS_RTPROC = 1879048193
pkg debug/elf, const PT_MIPS_RTPROC ProgType
pkg debug/elf, const PT_OPENBSD_BOOTDATA = 1705253862
pkg debug/elf, const PT_OPENBSD_BOOTDATA ProgType
pkg debug/elf, const PT_OPENBSD_RANDOMIZE = 1705237478
pkg debug/elf, const PT_OPENBSD_RANDOMIZE ProgType
pkg debug/elf, const PT_OPENBSD_WXNEEDED = 1705237479
pkg debug/elf, const PT_OPENBSD_WXNEEDED ProgType
pkg debug/elf, const PT_PAX_FLAGS = 1694766464
pkg debug/elf, const PT_PAX_FLAGS ProgType
pkg debug/elf, const PT_S390_PGSTE = 1879048192
pkg debug/elf, const PT_S390_PGSTE ProgType
pkg debug/elf, const PT_SUNWSTACK = 1879048187
pkg debug/elf, const PT_SUNWSTACK ProgType
pkg debug/elf, const PT_SUNW_EH_FRAME = 1685382480
pkg debug/elf, const PT_SUNW_EH_FRAME ProgType
pkg flag, func Func(string, string, func(string) error)
pkg flag, method (*FlagSet) Func(string, string, func(string) error)
pkg go/build, type Package struct, IgnoredOtherFiles []string
pkg io, type ReadSeekCloser interface { Close, Read, Seek }
pkg io, type ReadSeekCloser interface, Close() error
pkg io, type ReadSeekCloser interface, Read([]uint8) (int, error)
pkg io, type ReadSeekCloser interface, Seek(int64, int) (int64, error)
pkg io/fs, const ModeAppend = 1073741824
pkg io/fs, const ModeAppend FileMode
pkg io/fs, const ModeCharDevice = 2097152
pkg io/fs, const ModeCharDevice FileMode
pkg io/fs, const ModeDevice = 67108864
pkg io/fs, const ModeDevice FileMode
pkg io/fs, const ModeDir = 2147483648
pkg io/fs, const ModeDir FileMode
pkg io/fs, const ModeExclusive = 536870912
pkg io/fs, const ModeExclusive FileMode
pkg io/fs, const ModeIrregular = 524288
pkg io/fs, const ModeIrregular FileMode
pkg io/fs, const ModeNamedPipe = 33554432
pkg io/fs, const ModeNamedPipe FileMode
pkg io/fs, const ModePerm = 511
pkg io/fs, const ModePerm FileMode
pkg io/fs, const ModeSetgid = 4194304
pkg io/fs, const ModeSetgid FileMode
pkg io/fs, const ModeSetuid = 8388608
pkg io/fs, const ModeSetuid FileMode
pkg io/fs, const ModeSocket = 16777216
pkg io/fs, const ModeSocket FileMode
pkg io/fs, const ModeSticky = 1048576
pkg io/fs, const ModeSticky FileMode
pkg io/fs, const ModeSymlink = 134217728
pkg io/fs, const ModeSymlink FileMode
pkg io/fs, const ModeTemporary = 268435456
pkg io/fs, const ModeTemporary FileMode
pkg io/fs, const ModeType = 2401763328
pkg io/fs, const ModeType FileMode
pkg io/fs, method (*PathError) Error() string
pkg io/fs, method (*PathError) Timeout() bool
pkg io/fs, method (*PathError) Unwrap() error
pkg io/fs, method (FileMode) IsDir() bool
pkg io/fs, method (FileMode) IsRegular() bool
pkg io/fs, method (FileMode) Perm() FileMode
pkg io/fs, method (FileMode) String() string
pkg io/fs, method (FileMode) Type() FileMode
pkg io/fs, type FileInfo interface { IsDir, ModTime, Mode, Name, Size, Sys }
pkg io/fs, type FileInfo interface, IsDir() bool
pkg io/fs, type FileInfo interface, ModTime() time.Time
pkg io/fs, type FileInfo interface, Mode() FileMode
pkg io/fs, type FileInfo interface, Name() string
pkg io/fs, type FileInfo interface, Size() int64
pkg io/fs, type FileInfo interface, Sys() interface{}
pkg io/fs, type FileMode uint32
pkg io/fs, type PathError struct
pkg io/fs, type PathError struct, Err error
pkg io/fs, type PathError struct, Op string
pkg io/fs, type PathError struct, Path string
pkg io/fs, var ErrClosed error
pkg io/fs, var ErrExist error
pkg io/fs, var ErrInvalid error
pkg io/fs, var ErrNotExist error
pkg io/fs, var ErrPermission error
pkg net, var ErrClosed error
pkg net/http, type Transport struct, GetProxyConnectHeader func(context.Context, *url.URL, string) (Header, error)
pkg os, const ModeAppend fs.FileMode
pkg os, const ModeCharDevice fs.FileMode
pkg os, const ModeDevice fs.FileMode
pkg os, const ModeDir fs.FileMode
pkg os, const ModeExclusive fs.FileMode
pkg os, const ModeIrregular fs.FileMode
pkg os, const ModeNamedPipe fs.FileMode
pkg os, const ModePerm fs.FileMode
pkg os, const ModeSetgid fs.FileMode
pkg os, const ModeSetuid fs.FileMode
pkg os, const ModeSocket fs.FileMode
pkg os, const ModeSticky fs.FileMode
pkg os, const ModeSymlink fs.FileMode
pkg os, const ModeTemporary fs.FileMode
pkg os, const ModeType fs.FileMode
pkg os, func Chmod(string, fs.FileMode) error
pkg os, func Lstat(string) (fs.FileInfo, error)
pkg os, func Mkdir(string, fs.FileMode) error
pkg os, func MkdirAll(string, fs.FileMode) error
pkg os, func OpenFile(string, int, fs.FileMode) (*File, error)
pkg os, func SameFile(fs.FileInfo, fs.FileInfo) bool
pkg os, func Stat(string) (fs.FileInfo, error)
pkg os, method (*File) Chmod(fs.FileMode) error
pkg os, method (*File) ReadDir(int) ([]DirEntry, error)
pkg os, method (*File) Readdir(int) ([]fs.FileInfo, error)
pkg os, method (*File) Stat() (fs.FileInfo, error)
pkg os, type DirEntry interface { Info, IsDir, Name, Type }
pkg os, type DirEntry interface, Info() (fs.FileInfo, error)
pkg os, type DirEntry interface, IsDir() bool
pkg os, type DirEntry interface, Name() string
pkg os, type DirEntry interface, Type() fs.FileMode
pkg os, type FileInfo = fs.FileInfo
pkg os, type FileMode = fs.FileMode
pkg os, type PathError = fs.PathError
pkg os/signal, func NotifyContext(context.Context, ...os.Signal) (context.Context, context.CancelFunc)
pkg testing/iotest, func ErrReader(error) io.Reader
pkg unicode, const Version = "13.0.0"
pkg unicode, var Chorasmian *RangeTable
pkg unicode, var Dives_Akuru *RangeTable
pkg unicode, var Khitan_Small_Script *RangeTable
pkg unicode, var Yezidi *RangeTable
pkg text/template/parse, const NodeComment = 20
pkg text/template/parse, const NodeComment NodeType
pkg text/template/parse, const ParseComments = 1
@@ -330,8 +17,3 @@ pkg text/template/parse, type CommentNode struct, embedded NodeType
pkg text/template/parse, type CommentNode struct, embedded Pos
pkg text/template/parse, type Mode uint
pkg text/template/parse, type Tree struct, Mode Mode
pkg unicode, const Version = "13.0.0"
pkg unicode, var Chorasmian *RangeTable
pkg unicode, var Dives_Akuru *RangeTable
pkg unicode, var Khitan_Small_Script *RangeTable
pkg unicode, var Yezidi *RangeTable

View File

@@ -45,8 +45,8 @@ CLA (Contributor License Agreement).
</li>
<li>
<b>Step 2</b>: Configure authentication credentials for the Go Git repository.
Visit <a href="https://go.googlesource.com">go.googlesource.com</a>, click
"Generate Password" in the page's top right menu bar, and follow the
Visit <a href="https://go.googlesource.com/">go.googlesource.com</a>, click
on the gear icon (top right), then on "Obtain password", and follow the
instructions.
</li>
<li>
@@ -806,9 +806,10 @@ tracker will automatically mark the issue as fixed.
<p>
If the change is a partial step towards the resolution of the issue,
write "Updates #12345" instead.
This will leave a comment in the issue linking back to the change in
Gerrit, but it will not close the issue when the change is applied.
uses the notation "Updates #12345".
This will leave a comment in the issue
linking back to the change in Gerrit, but it will not close the issue
when the change is applied.
</p>
<p>

View File

@@ -454,8 +454,6 @@ environmental variable is set accordingly.</p>
<li>GODEBUG=gctrace=1 prints garbage collector events at
each collection, summarizing the amount of memory collected
and the length of the pause.</li>
<li>GODEBUG=inittrace=1 prints a summary of execution time and memory allocation
information for completed package initilization work.</li>
<li>GODEBUG=schedtrace=X prints scheduling events every X milliseconds.</li>
</ul>

View File

@@ -31,22 +31,8 @@ Do not send CLs removing the interior tags from such phrases.
<h2 id="ports">Ports</h2>
<h3 id="netbsd">NetBSD</h3>
<p><!-- golang.org/issue/30824 -->
Go now supports the 64-bit ARM architecture on NetBSD (the
<code>netbsd/arm64</code> port).
</p>
<h3 id="386">386</h3>
<p><!-- golang.org/issue/40255, golang.org/issue/41848, CL 258957, and CL 260017 -->
As <a href="go1.15#386">announced</a> in the Go 1.15 release notes,
Go 1.16 drops support for x87 mode compilation (<code>GO386=387</code>).
Support for non-SSE2 processors is now available using soft float
mode (<code>GO386=softfloat</code>).
Users running on non-SSE2 processors should replace <code>GO386=387</code>
with <code>GO386=softfloat</code>.
<p>
TODO
</p>
<h2 id="tools">Tools</h2>
@@ -57,20 +43,6 @@ Do not send CLs removing the interior tags from such phrases.
<h3 id="go-command">Go command</h3>
<h4 id="modules">Modules</h4>
<p><!-- golang.org/issue/40276 -->
<code>go</code> <code>install</code> now accepts arguments with
version suffixes (for example, <code>go</code> <code>install</code>
<code>example.com/cmd@v1.0.0</code>). This causes <code>go</code>
<code>install</code> to build and install packages in module-aware mode,
ignoring the <code>go.mod</code> file in the current directory or any parent
directory, if there is one. This is useful for installing executables without
affecting the dependencies of the main module.<br>
TODO: write and link to section in golang.org/ref/mod<br>
TODO: write and link to blog post
</p>
<p><!-- golang.org/issue/24031 -->
<code>retract</code> directives may now be used in a <code>go.mod</code> file
to indicate that certain published versions of the module should not be used
@@ -80,36 +52,16 @@ Do not send CLs removing the interior tags from such phrases.
TODO: write and link to tutorial or blog post
</p>
<p><!-- golang.org/issue/26603 -->
The <code>go</code> <code>mod</code> <code>vendor</code>
and <code>go</code> <code>mod</code> <code>tidy</code> subcommands now accept
the <code>-e</code> flag, which instructs them to proceed despite errors in
resolving missing packages.
</p>
<h4 id="go-test"><code>go</code> <code>test</code></h4>
<p><!-- golang.org/issue/29062 -->
When using <code>go</code> <code>test</code>, a test that
When using <code>go test</code>, a test that
calls <code>os.Exit(0)</code> during execution of a test function
will now be considered to fail.
This will help catch cases in which a test calls code that calls
<code>os.Exit(0)</code> and thereby stops running all future tests.
os.Exit(0) and thereby stops running all future tests.
If a <code>TestMain</code> function calls <code>os.Exit(0)</code>
that is still considered to be a passing test.
</p>
<p><!-- golang.org/issue/37519 -->
The <code>go</code> <code>get</code> <code>-insecure</code> flag is
deprecated and will be removed in a future version. This flag permits
fetching from repositories and resolving custom domains using insecure
schemes such as HTTP, and also bypassess module sum validation using the
checksum database. To permit the use of insecure schemes, use the
<code>GOINSECURE</code> environment variable instead. To bypass module
sum validation, use <code>GOPRIVATE</code> or <code>GONOSUMDB</code>.
See <code>go</code> <code>help</code> <code>environment</code> for details.
</p>
<h4 id="all-pattern">The <code>all</code> pattern</h4>
<p><!-- golang.org/cl/240623 -->
@@ -122,35 +74,6 @@ Do not send CLs removing the interior tags from such phrases.
by <code>go</code> <code>mod</code> <code>vendor</code> since Go 1.11.
</p>
<h4 id="toolexec">The <code>-toolexec</code> build flag</h4>
<p><!-- golang.org/cl/263357 -->
When the <code>-toolexec</code> build flag is specified to use a program when
invoking toolchain programs like compile or asm, the environment variable
<code>TOOLEXEC_IMPORTPATH</code> is now set to the import path of the package
being built.
</p>
<h4 id="list-buildid">The <code>list</code> command</h4>
<p><!-- golang.org/cl/263542 -->
When the <code>-export</code> flag is specified, the <code>BuildID</code>
field is now set to the build ID of the compiled package. This is equivalent
to running <code>go</code> <code>tool</code> <code>buildid</code> on
<code>go</code> <code>list</code> <code>-exported</code> <code>-f</code> <code>{{.Export}</code>,
but without the extra step.
</p>
<h3 id="cgo">Cgo</h3>
<p> <!-- CL 252378 -->
The <a href="/cmd/cgo">cgo</a> tool will no longer try to translate
C struct bitfields into Go struct fields, even if their size can be
represented in Go. The order in which C bitfields appear in memory
is implementation dependent, so in some cases the cgo tool produced
results that were silently incorrect.
</p>
<p>
TODO
</p>
@@ -192,60 +115,12 @@ Do not send CLs removing the interior tags from such phrases.
TODO: update with final numbers later in the release.
</p>
<p> <!-- CL 255259 -->
On Windows, <code>go build -buildmode=c-shared</code> now generates Windows
ASLR DLLs by default. ASLR can be disabled with <code>--ldflags=-aslr=false</code>.
</p>
<h2 id="library">Core library</h2>
<p>
TODO
</p>
<h3 id="crypto/hmac"><a href="/pkg/crypto/hmac">crypto/hmac</a></h3>
<p><!-- CL 261960 -->
<a href="/pkg/crypto/hmac/#New">New</a> will now panic if separate calls to
the hash generation function fail to return new values. Previously, the
behavior was undefined and invalid outputs were sometimes generated.
</p>
<h3 id="crypto/tls"><a href="/pkg/crypto/tls">crypto/tls</a></h3>
<p><!-- CL 256897 -->
I/O operations on closing or closed TLS connections can now be detected using
the new <a href="/pkg/net/#ErrClosed">ErrClosed</a> error. A typical use
would be <code>errors.Is(err, net.ErrClosed)</code>. In earlier releases
the only way to reliably detect this case was to match the string returned
by the <code>Error</code> method with <code>"tls: use of closed connection"</code>.
</p>
<h3 id="crypto/x509"><a href="/pkg/crypto/x509">crypto/x509</a></h3>
<p><!-- CL 235078 -->
<a href="/pkg/crypto/x509/#ParseCertificate">ParseCertificate</a> and
<a href="/pkg/crypto/x509/#CreateCertificate">CreateCertificate</a> both
now enforce string encoding restrictions for the fields <code>DNSNames</code>,
<code>EmailAddresses</code>, and <code>URIs</code>. These fields can only
contain strings with characters within the ASCII range.
</p>
<p><!-- CL 259697 -->
<a href="/pkg/crypto/x509/#CreateCertificate">CreateCertificate</a> now
verifies the generated certificate's signature using the signer's
public key. If the signature is invalid, an error is returned, instead
of a malformed certificate.
</p>
<h3 id="encoding/json"><a href="/pkg/encoding/json">encoding/json</a></h3>
<p><!-- CL 263619 -->
The error message for
<a href="/pkg/encoding/json/#SyntaxError">SyntaxError</a>
now begins with "json: ", matching the other errors in the package.
</p>
<h3 id="net"><a href="/pkg/net/">net</a></h3>
<p><!-- CL 250357 -->
@@ -258,20 +133,6 @@ Do not send CLs removing the interior tags from such phrases.
with <code>"use of closed network connection"</code>.
</p>
<p><!-- CL 255898 -->
In previous Go releases the default TCP listener backlog size on Linux systems,
set by <code>/proc/sys/net/core/somaxconn</code>, was limited to a maximum of <code>65535</code>.
On Linux kernel version 4.1 and above, the maximum is now <code>4294967295</code>.
</p>
<h3 id="reflect"><a href="/pkg/reflect/">reflect</a></h3>
<p><!-- CL 259237, golang.org/issue/22075 -->
For interface types and values, <a href="/pkg/reflect/#Value.Method">Method</a>,
<a href="/pkg/reflect/#Value.MethodByName">MethodByName</a>, and
<a href="/pkg/reflect/#Value.NumMethod">NumMethod</a> now
operate on the interface's exported method set, rather than its full method set.
</p>
<h3 id="text/template/parse"><a href="/pkg/text/template/parse/">text/template/parse</a></h3>
@@ -305,39 +166,6 @@ Do not send CLs removing the interior tags from such phrases.
TODO
</p>
<dl id="crypto/dsa"><dt><a href="/pkg/crypto/dsa/">crypto/dsa</a></dt>
<dd>
<p><!-- CL 257939 -->
The <a href="/pkg/crypto/dsa/"><code>crypto/dsa</code></a> package is now deprecated.
See <a href="https://golang.org/issue/40337">issue #40337</a>.
</p>
</dd>
</dl><!-- crypto/dsa -->
<dl id="crypto/x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt>
<dd>
<p><!-- CL 257939 -->
DSA signature verification is no longer supported. Note that DSA signature
generation was never supported.
See <a href="https://golang.org/issue/40337">issue #40337</a>.
</p>
</dd>
</dl><!-- crypto/x509 -->
<dl id="encoding/xml"><dt><a href="/pkg/encoding/xml/">encoding/xml</a></dt>
<dd>
<p><!-- CL 264024 -->
The encoder has always taken care to avoid using namespace prefixes
beginning with <code>xml</code>, which are reserved by the XML
specification.
Now, following the specification more closely, that check is
case-insensitive, so that prefixes beginning
with <code>XML</code>, <code>XmL</code>, and so on are also
avoided.
</p>
</dd>
</dl><!-- encoding/xml -->
<dl id="net/http"><dt><a href="/pkg/net/http/">net/http</a></dt>
<dd>
<p><!-- CL 233637 -->
@@ -359,31 +187,5 @@ Do not send CLs removing the interior tags from such phrases.
of the form <code>"Range": "bytes=--N"</code> where <code>"-N"</code> is a negative suffix length, for
example <code>"Range": "bytes=--2"</code>. It now replies with a <code>416 "Range Not Satisfiable"</code> response.
</p>
<p><!-- CL 256498, golang.org/issue/36990 -->
Cookies set with <code>SameSiteDefaultMode</code> now behave according to the current
spec (no attribute is set) instead of generating a SameSite key without a value.
</p>
</dd>
</dl><!-- net/http -->
<dl id="runtime/debug"><dt><a href="/pkg/runtime/debug/">runtime/debug</a></dt>
<dd>
<p><!-- CL 249677 -->
TODO: <a href="https://golang.org/cl/249677">https://golang.org/cl/249677</a>: provide Addr method for errors from SetPanicOnFault
</p>
</dd>
</dl><!-- runtime/debug -->
<dl id="strconv"><dt><a href="/pkg/strconv/">strconv</a></dt>
<dd>
<p><!-- CL 260858 -->
<a href="/pkg/strconv/#ParseFloat"><code>ParseFloat</code></a> now uses
the <a
href="https://nigeltao.github.io/blog/2020/eisel-lemire.html">Eisel-Lemire
algorithm</a>, improving performance by up to a factor of 2. This can
also speed up decoding textual formats like <a
href="/pkg/encoding/json/"><code>encoding/json</code></a>.
</p>
</dd>
</dl><!-- strconv -->

View File

@@ -1,6 +1,6 @@
<!--{
"Title": "The Go Programming Language Specification",
"Subtitle": "Version of Sep 24, 2020",
"Subtitle": "Version of Jan 14, 2020",
"Path": "/ref/spec"
}-->
@@ -3646,7 +3646,7 @@ For instance, <code>x / y * z</code> is the same as <code>(x / y) * z</code>.
x &lt;= f()
^a &gt;&gt; b
f() || g()
x == y+1 &amp;&amp; &lt;-chanInt &gt; 0
x == y+1 &amp;&amp; &lt;-chanPtr &gt; 0
</pre>

View File

@@ -507,8 +507,8 @@ These default to the values of <code>$GOHOSTOS</code> and
<p>
Choices for <code>$GOOS</code> are
<code>android</code>, <code>darwin</code>, <code>dragonfly</code>,
<code>freebsd</code>, <code>illumos</code>, <code>ios</code>, <code>js</code>,
<code>android</code>, <code>darwin</code> (macOS/iOS),
<code>dragonfly</code>, <code>freebsd</code>, <code>illumos</code>, <code>js</code>,
<code>linux</code>, <code>netbsd</code>, <code>openbsd</code>,
<code>plan9</code>, <code>solaris</code> and <code>windows</code>.
</p>
@@ -567,9 +567,6 @@ The valid combinations of <code>$GOOS</code> and <code>$GOARCH</code> are:
<td></td><td><code>illumos</code></td> <td><code>amd64</code></td>
</tr>
<tr>
<td></td><td><code>ios</code></td> <td><code>arm64</code></td>
</tr>
<tr>
<td></td><td><code>js</code></td> <td><code>wasm</code></td>
</tr>
<tr>
@@ -666,13 +663,16 @@ For example, you should not set <code>$GOHOSTARCH</code> to
<code>arm</code> on an x86 system.
</p>
<li><code>$GO386</code> (for <code>386</code> only, defaults to <code>sse2</code>)
<li><code>$GO386</code> (for <code>386</code> only, default is auto-detected
if built on either <code>386</code> or <code>amd64</code>, <code>387</code> otherwise)
<p>
This variable controls how gc implements floating point computations.
This controls the code generated by gc to use either the 387 floating-point unit
(set to <code>387</code>) or SSE2 instructions (set to <code>sse2</code>) for
floating point computations.
</p>
<ul>
<li><code>GO386=softfloat</code>: use software floating point operations; should support all x86 chips (Pentium MMX or later).</li>
<li><code>GO386=sse2</code>: use SSE2 for floating point operations; has better performance but only available on Pentium 4/Opteron/Athlon 64 or later.</li>
<li><code>GO386=387</code>: use x87 for floating point operations; should support all x86 chips (Pentium MMX or later).</li>
<li><code>GO386=sse2</code>: use SSE2 for floating point operations; has better performance than 387, but only available on Pentium 4/Opteron/Athlon 64 or later.</li>
</ul>
</li>

View File

@@ -8,8 +8,8 @@
# Consult https://www.iana.org/time-zones for the latest versions.
# Versions to use.
CODE=2020d
DATA=2020d
CODE=2020a
DATA=2020a
set -e
rm -rf work

Binary file not shown.

View File

@@ -181,7 +181,7 @@ func testCallbackCallers(t *testing.T) {
name := []string{
"runtime.cgocallbackg1",
"runtime.cgocallbackg",
"runtime.cgocallback",
"runtime.cgocallback_gofunc",
"runtime.asmcgocall",
"runtime.cgocall",
"test._Cfunc_callback",

View File

@@ -15,6 +15,5 @@ func TestSetgid(t *testing.T) {
}
testSetgid(t)
}
func Test1435(t *testing.T) { test1435(t) }
func Test6997(t *testing.T) { test6997(t) }
func TestBuildID(t *testing.T) { testBuildID(t) }

View File

@@ -76,8 +76,6 @@ func TestCheckConst(t *testing.T) { testCheckConst(t) }
func TestConst(t *testing.T) { testConst(t) }
func TestCthread(t *testing.T) { testCthread(t) }
func TestEnum(t *testing.T) { testEnum(t) }
func TestNamedEnum(t *testing.T) { testNamedEnum(t) }
func TestCastToEnum(t *testing.T) { testCastToEnum(t) }
func TestErrno(t *testing.T) { testErrno(t) }
func TestFpVar(t *testing.T) { testFpVar(t) }
func TestHelpers(t *testing.T) { testHelpers(t) }

View File

@@ -1,152 +0,0 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux,cgo
package cgotest
import (
"fmt"
"io/ioutil"
"strings"
"syscall"
"testing"
)
// #include <stdio.h>
// #include <stdlib.h>
// #include <pthread.h>
// #include <unistd.h>
// #include <sys/types.h>
//
// pthread_t *t = NULL;
// pthread_mutex_t mu;
// int nts = 0;
// int all_done = 0;
//
// static void *aFn(void *vargp) {
// int done = 0;
// while (!done) {
// usleep(100);
// pthread_mutex_lock(&mu);
// done = all_done;
// pthread_mutex_unlock(&mu);
// }
// return NULL;
// }
//
// void trial(int argc) {
// int i;
// nts = argc;
// t = calloc(nts, sizeof(pthread_t));
// pthread_mutex_init(&mu, NULL);
// for (i = 0; i < nts; i++) {
// pthread_create(&t[i], NULL, aFn, NULL);
// }
// }
//
// void cleanup(void) {
// int i;
// pthread_mutex_lock(&mu);
// all_done = 1;
// pthread_mutex_unlock(&mu);
// for (i = 0; i < nts; i++) {
// pthread_join(t[i], NULL);
// }
// pthread_mutex_destroy(&mu);
// free(t);
// }
import "C"
// compareStatus is used to confirm the contents of the thread
// specific status files match expectations.
func compareStatus(filter, expect string) error {
expected := filter + "\t" + expect
pid := syscall.Getpid()
fs, err := ioutil.ReadDir(fmt.Sprintf("/proc/%d/task", pid))
if err != nil {
return fmt.Errorf("unable to find %d tasks: %v", pid, err)
}
for _, f := range fs {
tf := fmt.Sprintf("/proc/%s/status", f.Name())
d, err := ioutil.ReadFile(tf)
if err != nil {
return fmt.Errorf("unable to read %q: %v", tf, err)
}
lines := strings.Split(string(d), "\n")
for _, line := range lines {
if strings.HasPrefix(line, filter) {
if line != expected {
return fmt.Errorf("%s %s (bad)\n", tf, line)
}
break
}
}
}
return nil
}
// test1435 test 9 glibc implemented setuid/gid syscall functions are
// mapped. This test is a slightly more expansive test than that of
// src/syscall/syscall_linux_test.go:TestSetuidEtc() insofar as it
// launches concurrent threads from C code via CGo and validates that
// they are subject to the system calls being tested. For the actual
// Go functionality being tested here, the syscall_linux_test version
// is considered authoritative, but non-trivial improvements to that
// should be mirrored here.
func test1435(t *testing.T) {
if syscall.Getuid() != 0 {
t.Skip("skipping root only test")
}
// Launch some threads in C.
const cts = 5
C.trial(cts)
defer C.cleanup()
vs := []struct {
call string
fn func() error
filter, expect string
}{
{call: "Setegid(1)", fn: func() error { return syscall.Setegid(1) }, filter: "Gid:", expect: "0\t1\t0\t1"},
{call: "Setegid(0)", fn: func() error { return syscall.Setegid(0) }, filter: "Gid:", expect: "0\t0\t0\t0"},
{call: "Seteuid(1)", fn: func() error { return syscall.Seteuid(1) }, filter: "Uid:", expect: "0\t1\t0\t1"},
{call: "Setuid(0)", fn: func() error { return syscall.Setuid(0) }, filter: "Uid:", expect: "0\t0\t0\t0"},
{call: "Setgid(1)", fn: func() error { return syscall.Setgid(1) }, filter: "Gid:", expect: "1\t1\t1\t1"},
{call: "Setgid(0)", fn: func() error { return syscall.Setgid(0) }, filter: "Gid:", expect: "0\t0\t0\t0"},
{call: "Setgroups([]int{0,1,2,3})", fn: func() error { return syscall.Setgroups([]int{0, 1, 2, 3}) }, filter: "Groups:", expect: "0 1 2 3 "},
{call: "Setgroups(nil)", fn: func() error { return syscall.Setgroups(nil) }, filter: "Groups:", expect: " "},
{call: "Setgroups([]int{0})", fn: func() error { return syscall.Setgroups([]int{0}) }, filter: "Groups:", expect: "0 "},
{call: "Setregid(101,0)", fn: func() error { return syscall.Setregid(101, 0) }, filter: "Gid:", expect: "101\t0\t0\t0"},
{call: "Setregid(0,102)", fn: func() error { return syscall.Setregid(0, 102) }, filter: "Gid:", expect: "0\t102\t102\t102"},
{call: "Setregid(0,0)", fn: func() error { return syscall.Setregid(0, 0) }, filter: "Gid:", expect: "0\t0\t0\t0"},
{call: "Setreuid(1,0)", fn: func() error { return syscall.Setreuid(1, 0) }, filter: "Uid:", expect: "1\t0\t0\t0"},
{call: "Setreuid(0,2)", fn: func() error { return syscall.Setreuid(0, 2) }, filter: "Uid:", expect: "0\t2\t2\t2"},
{call: "Setreuid(0,0)", fn: func() error { return syscall.Setreuid(0, 0) }, filter: "Uid:", expect: "0\t0\t0\t0"},
{call: "Setresgid(101,0,102)", fn: func() error { return syscall.Setresgid(101, 0, 102) }, filter: "Gid:", expect: "101\t0\t102\t0"},
{call: "Setresgid(0,102,101)", fn: func() error { return syscall.Setresgid(0, 102, 101) }, filter: "Gid:", expect: "0\t102\t101\t102"},
{call: "Setresgid(0,0,0)", fn: func() error { return syscall.Setresgid(0, 0, 0) }, filter: "Gid:", expect: "0\t0\t0\t0"},
{call: "Setresuid(1,0,2)", fn: func() error { return syscall.Setresuid(1, 0, 2) }, filter: "Uid:", expect: "1\t0\t2\t0"},
{call: "Setresuid(0,2,1)", fn: func() error { return syscall.Setresuid(0, 2, 1) }, filter: "Uid:", expect: "0\t2\t1\t2"},
{call: "Setresuid(0,0,0)", fn: func() error { return syscall.Setresuid(0, 0, 0) }, filter: "Uid:", expect: "0\t0\t0\t0"},
}
for i, v := range vs {
if err := v.fn(); err != nil {
t.Errorf("[%d] %q failed: %v", i, v.call, err)
continue
}
if err := compareStatus(v.filter, v.expect); err != nil {
t.Errorf("[%d] %q comparison: %v", i, v.call, err)
}
}
}

View File

@@ -24,7 +24,7 @@ func test18146(t *testing.T) {
t.Skip("skipping in short mode")
}
if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
if runtime.GOOS == "darwin" {
t.Skipf("skipping flaky test on %s; see golang.org/issue/18202", runtime.GOOS)
}

View File

@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
// +build !windows,!static
// +build !darwin !internal_pie,!arm64
#include <stdint.h>
#include <dlfcn.h>

View File

@@ -3,11 +3,6 @@
// license that can be found in the LICENSE file.
// +build !windows,!static
// +build !darwin !internal_pie,!arm64
// Excluded in darwin internal linking PIE mode, as dynamic export is not
// supported.
// Excluded in internal linking mode on darwin/arm64, as it is always PIE.
package cgotest

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows static darwin,internal_pie darwin,arm64
// +build windows static
package cgotest

View File

@@ -30,7 +30,7 @@ func TestCrossPackageTests(t *testing.T) {
switch runtime.GOOS {
case "android":
t.Skip("Can't exec cmd/go subprocess on Android.")
case "darwin", "ios":
case "darwin":
switch runtime.GOARCH {
case "arm64":
t.Skip("Can't exec cmd/go subprocess on iOS.")

View File

@@ -62,7 +62,7 @@ import (
func testSigaltstack(t *testing.T) {
switch {
case runtime.GOOS == "solaris", runtime.GOOS == "illumos", runtime.GOOS == "ios" && runtime.GOARCH == "arm64":
case runtime.GOOS == "solaris", runtime.GOOS == "illumos", runtime.GOOS == "darwin" && runtime.GOARCH == "arm64":
t.Skipf("switching signal stack not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
}

View File

@@ -1000,32 +1000,6 @@ func testEnum(t *testing.T) {
}
}
func testNamedEnum(t *testing.T) {
e := new(C.enum_E)
*e = C.Enum1
if *e != 1 {
t.Error("bad enum", C.Enum1)
}
*e = C.Enum2
if *e != 2 {
t.Error("bad enum", C.Enum2)
}
}
func testCastToEnum(t *testing.T) {
e := C.enum_E(C.Enum1)
if e != 1 {
t.Error("bad enum", C.Enum1)
}
e = C.enum_E(C.Enum2)
if e != 2 {
t.Error("bad enum", C.Enum2)
}
}
func testAtol(t *testing.T) {
l := Atol("123")
if l != 123 {
@@ -1802,7 +1776,7 @@ func test14838(t *testing.T) {
var sink C.int
func test17065(t *testing.T) {
if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
if runtime.GOOS == "darwin" {
t.Skip("broken on darwin; issue 17065")
}
for i := range C.ii {

View File

@@ -1,20 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cgotest
/*
typedef struct S S;
*/
import "C"
import (
"cgotest/issue41761a"
"testing"
)
func test41761(t *testing.T) {
var x issue41761a.T
_ = (*C.struct_S)(x.X)
}

View File

@@ -1,14 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package issue41761a
/*
typedef struct S S;
*/
import "C"
type T struct {
X *C.S
}

View File

@@ -164,7 +164,7 @@ func Add(x int) {
}
func testCthread(t *testing.T) {
if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && runtime.GOARCH == "arm64" {
if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
t.Skip("the iOS exec wrapper is unable to properly handle the panic from Add")
}
sum.i = 0

View File

@@ -118,9 +118,9 @@ func testMain(m *testing.M) int {
cc = append(cc, s[start:])
}
if GOOS == "darwin" || GOOS == "ios" {
if GOOS == "darwin" {
// For Darwin/ARM.
// TODO: do we still need this?
// TODO(crawshaw): can we do better?
cc = append(cc, []string{"-framework", "CoreFoundation", "-framework", "Foundation"}...)
}
if GOOS == "aix" {
@@ -133,7 +133,7 @@ func testMain(m *testing.M) int {
libbase = "gccgo_" + libgodir + "_fPIC"
} else {
switch GOOS {
case "darwin", "ios":
case "darwin":
if GOARCH == "arm64" {
libbase += "_shared"
}
@@ -303,7 +303,7 @@ func TestInstall(t *testing.T) {
func TestEarlySignalHandler(t *testing.T) {
switch GOOS {
case "darwin", "ios":
case "darwin":
switch GOARCH {
case "arm64":
t.Skipf("skipping on %s/%s; see https://golang.org/issue/13701", GOOS, GOARCH)
@@ -384,7 +384,7 @@ func TestSignalForwarding(t *testing.T) {
expectSignal(t, err, syscall.SIGSEGV)
// SIGPIPE is never forwarded on darwin. See golang.org/issue/33384.
if runtime.GOOS != "darwin" && runtime.GOOS != "ios" {
if runtime.GOOS != "darwin" {
// Test SIGPIPE forwarding
cmd = exec.Command(bin[0], append(bin[1:], "3")...)
@@ -485,7 +485,7 @@ func TestSignalForwardingExternal(t *testing.T) {
// doesn't work on this platform.
func checkSignalForwardingTest(t *testing.T) {
switch GOOS {
case "darwin", "ios":
case "darwin":
switch GOARCH {
case "arm64":
t.Skipf("skipping on %s/%s; see https://golang.org/issue/13701", GOOS, GOARCH)
@@ -603,7 +603,7 @@ func TestExtar(t *testing.T) {
if runtime.Compiler == "gccgo" {
t.Skip("skipping -extar test when using gccgo")
}
if runtime.GOOS == "ios" {
if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
t.Skip("shell scripts are not executable on iOS hosts")
}
@@ -645,7 +645,7 @@ func TestExtar(t *testing.T) {
func TestPIE(t *testing.T) {
switch GOOS {
case "windows", "darwin", "ios", "plan9":
case "windows", "darwin", "plan9":
t.Skipf("skipping PIE test on %s", GOOS)
}
@@ -738,7 +738,7 @@ func TestSIGPROF(t *testing.T) {
switch GOOS {
case "windows", "plan9":
t.Skipf("skipping SIGPROF test on %s", GOOS)
case "darwin", "ios":
case "darwin":
t.Skipf("skipping SIGPROF test on %s; see https://golang.org/issue/19320", GOOS)
}
@@ -841,7 +841,7 @@ func TestCompileWithoutShared(t *testing.T) {
expectSignal(t, err, syscall.SIGSEGV)
// SIGPIPE is never forwarded on darwin. See golang.org/issue/33384.
if runtime.GOOS != "darwin" && runtime.GOOS != "ios" {
if runtime.GOOS != "darwin" {
binArgs := append(cmdToRun(exe), "3")
t.Log(binArgs)
out, err = exec.Command(binArgs[0], binArgs[1:]...).CombinedOutput()

View File

@@ -7,8 +7,6 @@ package cshared_test
import (
"bytes"
"debug/elf"
"debug/pe"
"encoding/binary"
"flag"
"fmt"
"io/ioutil"
@@ -100,7 +98,7 @@ func testMain(m *testing.M) int {
}
switch GOOS {
case "darwin", "ios":
case "darwin":
// For Darwin/ARM.
// TODO(crawshaw): can we do better?
cc = append(cc, []string{"-framework", "CoreFoundation", "-framework", "Foundation"}...)
@@ -109,7 +107,7 @@ func testMain(m *testing.M) int {
}
libgodir := GOOS + "_" + GOARCH
switch GOOS {
case "darwin", "ios":
case "darwin":
if GOARCH == "arm64" {
libgodir += "_shared"
}
@@ -357,100 +355,6 @@ func TestExportedSymbols(t *testing.T) {
}
}
func checkNumberOfExportedFunctionsWindows(t *testing.T, exportAllSymbols bool) {
const prog = `
package main
import "C"
//export GoFunc
func GoFunc() {
println(42)
}
//export GoFunc2
func GoFunc2() {
println(24)
}
func main() {
}
`
tmpdir := t.TempDir()
srcfile := filepath.Join(tmpdir, "test.go")
objfile := filepath.Join(tmpdir, "test.dll")
if err := ioutil.WriteFile(srcfile, []byte(prog), 0666); err != nil {
t.Fatal(err)
}
argv := []string{"build", "-buildmode=c-shared"}
if exportAllSymbols {
argv = append(argv, "-ldflags", "-extldflags=-Wl,--export-all-symbols")
}
argv = append(argv, "-o", objfile, srcfile)
out, err := exec.Command("go", argv...).CombinedOutput()
if err != nil {
t.Fatalf("build failure: %s\n%s\n", err, string(out))
}
f, err := pe.Open(objfile)
if err != nil {
t.Fatalf("pe.Open failed: %v", err)
}
defer f.Close()
section := f.Section(".edata")
if section == nil {
t.Error(".edata section is not present")
}
// TODO: deduplicate this struct from cmd/link/internal/ld/pe.go
type IMAGE_EXPORT_DIRECTORY struct {
_ [2]uint32
_ [2]uint16
_ [2]uint32
NumberOfFunctions uint32
NumberOfNames uint32
_ [3]uint32
}
var e IMAGE_EXPORT_DIRECTORY
if err := binary.Read(section.Open(), binary.LittleEndian, &e); err != nil {
t.Fatalf("binary.Read failed: %v", err)
}
expectedNumber := uint32(2)
if exportAllSymbols {
if e.NumberOfFunctions <= expectedNumber {
t.Fatalf("missing exported functions: %v", e.NumberOfFunctions)
}
if e.NumberOfNames <= expectedNumber {
t.Fatalf("missing exported names: %v", e.NumberOfNames)
}
} else {
if e.NumberOfFunctions != expectedNumber {
t.Fatalf("too many exported functions: %v", e.NumberOfFunctions)
}
if e.NumberOfNames != expectedNumber {
t.Fatalf("too many exported names: %v", e.NumberOfNames)
}
}
}
func TestNumberOfExportedFunctions(t *testing.T) {
if GOOS != "windows" {
t.Skip("skipping windows only test")
}
t.Parallel()
t.Run("OnlyExported", func(t *testing.T) {
checkNumberOfExportedFunctionsWindows(t, false)
})
t.Run("All", func(t *testing.T) {
checkNumberOfExportedFunctionsWindows(t, true)
})
}
// test1: shared library can be dynamically loaded and exported symbols are accessible.
func TestExportedSymbolsWithDynamicLoad(t *testing.T) {
t.Parallel()
@@ -503,7 +407,7 @@ func TestUnexportedSymbols(t *testing.T) {
adbPush(t, libname)
linkFlags := "-Wl,--no-as-needed"
if GOOS == "darwin" || GOOS == "ios" {
if GOOS == "darwin" {
linkFlags = ""
}
@@ -732,7 +636,7 @@ func copyFile(t *testing.T, dst, src string) {
func TestGo2C2Go(t *testing.T) {
switch GOOS {
case "darwin", "ios":
case "darwin":
// Darwin shared libraries don't support the multiple
// copies of the runtime package implied by this test.
t.Skip("linking c-shared into Go programs not supported on Darwin; issue 29061")

View File

@@ -1,31 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// +build ignore
package main
// This file tests that we don't generate an incorrect field location
// for a bitfield that appears aligned.
/*
struct bitfields {
unsigned int B1 : 5;
unsigned int B2 : 1;
unsigned int B3 : 1;
unsigned int B4 : 1;
unsigned int Short1 : 16; // misaligned on 8 bit boundary
unsigned int B5 : 1;
unsigned int B6 : 1;
unsigned int B7 : 1;
unsigned int B8 : 1;
unsigned int B9 : 1;
unsigned int B10 : 3;
unsigned int Short2 : 16; // alignment is OK
unsigned int Short3 : 16; // alignment is OK
};
*/
import "C"
type bitfields C.struct_bitfields

View File

@@ -4,12 +4,6 @@
package main
import (
"fmt"
"os"
"reflect"
)
// Test that the struct field in anonunion.go was promoted.
var v1 T
var v2 = v1.L
@@ -29,26 +23,4 @@ var v7 = S{}
var _ = issue38649{X: 0}
func main() {
pass := true
// The Go translation of bitfields should not have any of the
// bitfield types. The order in which bitfields are laid out
// in memory is implementation defined, so we can't easily
// know how a bitfield should correspond to a Go type, even if
// it appears to be aligned correctly.
bitfieldType := reflect.TypeOf(bitfields{})
check := func(name string) {
_, ok := bitfieldType.FieldByName(name)
if ok {
fmt.Fprintf(os.Stderr, "found unexpected bitfields field %s\n", name)
pass = false
}
}
check("Short1")
check("Short2")
check("Short3")
if !pass {
os.Exit(1)
}
}

View File

@@ -19,7 +19,6 @@ import (
// import "C" block. Add more tests here.
var filePrefixes = []string{
"anonunion",
"bitfields",
"issue8478",
"fieldtypedef",
"issue37479",

View File

@@ -21,7 +21,7 @@ func requireTestSOSupported(t *testing.T) {
t.Helper()
switch runtime.GOARCH {
case "arm64":
if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
if runtime.GOOS == "darwin" {
t.Skip("No exec facility on iOS.")
}
case "ppc64":
@@ -74,7 +74,7 @@ func TestSO(t *testing.T) {
ext := "so"
args := append(gogccflags, "-shared")
switch runtime.GOOS {
case "darwin", "ios":
case "darwin":
ext = "dylib"
args = append(args, "-undefined", "suppress", "-flat_namespace")
case "windows":
@@ -119,7 +119,7 @@ func TestSO(t *testing.T) {
cmd.Env = append(os.Environ(), "GOPATH="+GOPATH)
if runtime.GOOS != "windows" {
s := "LD_LIBRARY_PATH"
if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
if runtime.GOOS == "darwin" {
s = "DYLD_LIBRARY_PATH"
}
cmd.Env = append(os.Environ(), s+"=.")

View File

@@ -21,7 +21,7 @@ func requireTestSOSupported(t *testing.T) {
t.Helper()
switch runtime.GOARCH {
case "arm64":
if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
if runtime.GOOS == "darwin" {
t.Skip("No exec facility on iOS.")
}
case "ppc64":
@@ -74,7 +74,7 @@ func TestSO(t *testing.T) {
ext := "so"
args := append(gogccflags, "-shared")
switch runtime.GOOS {
case "darwin", "ios":
case "darwin":
ext = "dylib"
args = append(args, "-undefined", "suppress", "-flat_namespace")
case "windows":
@@ -119,7 +119,7 @@ func TestSO(t *testing.T) {
cmd.Env = append(os.Environ(), "GOPATH="+GOPATH)
if runtime.GOOS != "windows" {
s := "LD_LIBRARY_PATH"
if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
if runtime.GOOS == "darwin" {
s = "DYLD_LIBRARY_PATH"
}
cmd.Env = append(os.Environ(), s+"=.")

View File

@@ -1,20 +1,13 @@
Go on iOS
=========
To run the standard library tests, run all.bash as usual, but with the compiler
set to the clang wrapper that invokes clang for iOS. For example, this command runs
all.bash on the iOS emulator:
For details on developing Go for iOS on macOS, see the documentation in the mobile
subrepository:
GOOS=ios GOARCH=amd64 CGO_ENABLED=1 CC_FOR_TARGET=$(pwd)/../misc/ios/clangwrap.sh ./all.bash
https://github.com/golang/mobile
To use the go tool to run individual programs and tests, put $GOROOT/bin into PATH to ensure
the go_ios_$GOARCH_exec wrapper is found. For example, to run the archive/tar tests:
export PATH=$GOROOT/bin:$PATH
GOOS=ios GOARCH=amd64 CGO_ENABLED=1 go test archive/tar
The go_ios_exec wrapper uses GOARCH to select the emulator (amd64) or the device (arm64).
However, further setup is required to run tests or programs directly on a device.
It is necessary to set up the environment before running tests or programs directly on a
device.
First make sure you have a valid developer certificate and have setup your device properly
to run apps signed by your developer certificate. Then install the libimobiledevice and
@@ -36,10 +29,18 @@ which will output something similar to
export GOIOS_TEAM_ID=ZZZZZZZZ
If you have multiple devices connected, specify the device UDID with the GOIOS_DEVICE_ID
variable. Use `idevice_id -l` to list all available UDIDs. Then, setting GOARCH to arm64
will select the device:
variable. Use `idevice_id -l` to list all available UDIDs.
GOOS=ios GOARCH=arm64 CGO_ENABLED=1 CC_FOR_TARGET=$(pwd)/../misc/ios/clangwrap.sh ./all.bash
Finally, to run the standard library tests, run all.bash as usual, but with the compiler
set to the clang wrapper that invokes clang for iOS. For example,
GOARCH=arm64 CGO_ENABLED=1 CC_FOR_TARGET=$(pwd)/../misc/ios/clangwrap.sh ./all.bash
To use the go tool directly to run programs and tests, put $GOROOT/bin into PATH to ensure
the go_darwin_$GOARCH_exec wrapper is found. For example, to run the archive/tar tests
export PATH=$GOROOT/bin:$PATH
GOARCH=arm64 CGO_ENABLED=1 go test archive/tar
Note that the go_darwin_$GOARCH_exec wrapper uninstalls any existing app identified by
the bundle id before installing a new app. If the uninstalled app is the last app by

View File

@@ -2,19 +2,17 @@
# This uses the latest available iOS SDK, which is recommended.
# To select a specific SDK, run 'xcodebuild -showsdks'
# to see the available SDKs and replace iphoneos with one of them.
if [ "$GOARCH" == "arm64" ]; then
SDK=iphoneos
PLATFORM=ios
CLANGARCH="arm64"
else
SDK=iphonesimulator
PLATFORM=ios-simulator
CLANGARCH="x86_64"
fi
SDK=iphoneos
SDK_PATH=`xcrun --sdk $SDK --show-sdk-path`
export IPHONEOS_DEPLOYMENT_TARGET=5.1
# cmd/cgo doesn't support llvm-gcc-4.2, so we have to use clang.
CLANG=`xcrun --sdk $SDK --find clang`
exec "$CLANG" -arch $CLANGARCH -isysroot "$SDK_PATH" -m${PLATFORM}-version-min=10.0 "$@"
if [ "$GOARCH" == "arm64" ]; then
CLANGARCH="arm64"
else
echo "unknown GOARCH=$GOARCH" >&2
exit 1
fi
exec $CLANG -arch $CLANGARCH -isysroot $SDK_PATH -mios-version-min=10.0 "$@"

View File

@@ -6,7 +6,7 @@
// detect attempts to autodetect the correct
// values of the environment variables
// used by go_ios_exec.
// used by go_darwin_arm_exec.
// detect shells out to ideviceinfo, a third party program that can
// be obtained by following the instructions at
// https://github.com/libimobiledevice/libimobiledevice.

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This program can be used as go_ios_$GOARCH_exec by the Go tool.
// This program can be used as go_darwin_arm_exec by the Go tool.
// It executes binaries on an iOS device using the XCode toolchain
// and the ios-deploy program: https://github.com/phonegap/ios-deploy
//
@@ -34,7 +34,6 @@ import (
"os/signal"
"path/filepath"
"runtime"
"strconv"
"strings"
"syscall"
"time"
@@ -59,16 +58,34 @@ var lock *os.File
func main() {
log.SetFlags(0)
log.SetPrefix("go_ios_exec: ")
log.SetPrefix("go_darwin_arm_exec: ")
if debug {
log.Println(strings.Join(os.Args, " "))
}
if len(os.Args) < 2 {
log.Fatal("usage: go_ios_exec a.out")
log.Fatal("usage: go_darwin_arm_exec a.out")
}
// e.g. B393DDEB490947F5A463FD074299B6C0AXXXXXXX
devID = getenv("GOIOS_DEV_ID")
// e.g. Z8B3JBXXXX.org.golang.sample, Z8B3JBXXXX prefix is available at
// https://developer.apple.com/membercenter/index.action#accountSummary as Team ID.
appID = getenv("GOIOS_APP_ID")
// e.g. Z8B3JBXXXX, available at
// https://developer.apple.com/membercenter/index.action#accountSummary as Team ID.
teamID = getenv("GOIOS_TEAM_ID")
// Device IDs as listed with ios-deploy -c.
deviceID = os.Getenv("GOIOS_DEVICE_ID")
parts := strings.SplitN(appID, ".", 2)
// For compatibility with the old builders, use a fallback bundle ID
bundleID = "golang.gotest"
if len(parts) == 2 {
bundleID = parts[1]
}
exitCode, err := runMain()
if err != nil {
@@ -79,7 +96,7 @@ func main() {
func runMain() (int, error) {
var err error
tmpdir, err = ioutil.TempDir("", "go_ios_exec_")
tmpdir, err = ioutil.TempDir("", "go_darwin_arm_exec_")
if err != nil {
return 1, err
}
@@ -100,7 +117,7 @@ func runMain() (int, error) {
//
// The lock file is never deleted, to avoid concurrent locks on distinct
// files with the same path.
lockName := filepath.Join(os.TempDir(), "go_ios_exec-"+deviceID+".lock")
lockName := filepath.Join(os.TempDir(), "go_darwin_arm_exec-"+deviceID+".lock")
lock, err = os.OpenFile(lockName, os.O_CREATE|os.O_RDONLY, 0666)
if err != nil {
return 1, err
@@ -109,12 +126,28 @@ func runMain() (int, error) {
return 1, err
}
if goarch := os.Getenv("GOARCH"); goarch == "arm64" {
err = runOnDevice(appdir)
} else {
err = runOnSimulator(appdir)
if err := uninstall(bundleID); err != nil {
return 1, err
}
if err := install(appdir); err != nil {
return 1, err
}
if err := mountDevImage(); err != nil {
return 1, err
}
// Kill any hanging debug bridges that might take up port 3222.
exec.Command("killall", "idevicedebugserverproxy").Run()
closer, err := startDebugBridge()
if err != nil {
return 1, err
}
defer closer()
if err := run(appdir, bundleID, os.Args[2:]); err != nil {
// If the lldb driver completed with an exit code, use that.
if err, ok := err.(*exec.ExitError); ok {
if ws, ok := err.Sys().(interface{ ExitStatus() int }); ok {
@@ -126,62 +159,6 @@ func runMain() (int, error) {
return 0, nil
}
func runOnSimulator(appdir string) error {
if err := installSimulator(appdir); err != nil {
return err
}
return runSimulator(appdir, bundleID, os.Args[2:])
}
func runOnDevice(appdir string) error {
// e.g. B393DDEB490947F5A463FD074299B6C0AXXXXXXX
devID = getenv("GOIOS_DEV_ID")
// e.g. Z8B3JBXXXX.org.golang.sample, Z8B3JBXXXX prefix is available at
// https://developer.apple.com/membercenter/index.action#accountSummary as Team ID.
appID = getenv("GOIOS_APP_ID")
// e.g. Z8B3JBXXXX, available at
// https://developer.apple.com/membercenter/index.action#accountSummary as Team ID.
teamID = getenv("GOIOS_TEAM_ID")
// Device IDs as listed with ios-deploy -c.
deviceID = os.Getenv("GOIOS_DEVICE_ID")
parts := strings.SplitN(appID, ".", 2)
if len(parts) == 2 {
bundleID = parts[1]
}
if err := signApp(appdir); err != nil {
return err
}
if err := uninstallDevice(bundleID); err != nil {
return err
}
if err := installDevice(appdir); err != nil {
return err
}
if err := mountDevImage(); err != nil {
return err
}
// Kill any hanging debug bridges that might take up port 3222.
exec.Command("killall", "idevicedebugserverproxy").Run()
closer, err := startDebugBridge()
if err != nil {
return err
}
defer closer()
return runDevice(appdir, bundleID, os.Args[2:])
}
func getenv(envvar string) string {
s := os.Getenv(envvar)
if s == "" {
@@ -214,11 +191,7 @@ func assembleApp(appdir, bin string) error {
if err := ioutil.WriteFile(filepath.Join(appdir, "ResourceRules.plist"), []byte(resourceRules), 0744); err != nil {
return err
}
return nil
}
func signApp(appdir string) error {
entitlementsPath := filepath.Join(tmpdir, "Entitlements.plist")
cmd := exec.Command(
"codesign",
"-f",
@@ -448,20 +421,7 @@ func parsePlistDict(dict []byte) (map[string]string, error) {
return values, nil
}
func installSimulator(appdir string) error {
cmd := exec.Command(
"xcrun", "simctl", "install",
"booted", // Install to the booted simulator.
appdir,
)
if out, err := cmd.CombinedOutput(); err != nil {
os.Stderr.Write(out)
return fmt.Errorf("xcrun simctl install booted %q: %v", appdir, err)
}
return nil
}
func uninstallDevice(bundleID string) error {
func uninstall(bundleID string) error {
cmd := idevCmd(exec.Command(
"ideviceinstaller",
"-U", bundleID,
@@ -473,7 +433,7 @@ func uninstallDevice(bundleID string) error {
return nil
}
func installDevice(appdir string) error {
func install(appdir string) error {
attempt := 0
for {
cmd := idevCmd(exec.Command(
@@ -504,28 +464,15 @@ func idevCmd(cmd *exec.Cmd) *exec.Cmd {
return cmd
}
func runSimulator(appdir, bundleID string, args []string) error {
cmd := exec.Command(
"xcrun", "simctl", "launch",
"--wait-for-debugger",
"booted",
bundleID,
)
out, err := cmd.CombinedOutput()
if err != nil {
os.Stderr.Write(out)
return fmt.Errorf("xcrun simctl launch booted %q: %v", bundleID, err)
func run(appdir, bundleID string, args []string) error {
var env []string
for _, e := range os.Environ() {
// Don't override TMPDIR, HOME, GOCACHE on the device.
if strings.HasPrefix(e, "TMPDIR=") || strings.HasPrefix(e, "HOME=") || strings.HasPrefix(e, "GOCACHE=") {
continue
}
env = append(env, e)
}
var processID int
var ignore string
if _, err := fmt.Sscanf(string(out), "%s %d", &ignore, &processID); err != nil {
return fmt.Errorf("runSimulator: couldn't find processID from `simctl launch`: %v (%q)", err, out)
}
_, err = runLLDB("ios-simulator", appdir, strconv.Itoa(processID), args)
return err
}
func runDevice(appdir, bundleID string, args []string) error {
attempt := 0
for {
// The device app path reported by the device might be stale, so retry
@@ -540,10 +487,37 @@ func runDevice(appdir, bundleID string, args []string) error {
time.Sleep(5 * time.Second)
continue
}
out, err := runLLDB("remote-ios", appdir, deviceapp, args)
lldb := exec.Command(
"python",
"-", // Read script from stdin.
appdir,
deviceapp,
)
lldb.Args = append(lldb.Args, args...)
lldb.Env = env
lldb.Stdin = strings.NewReader(lldbDriver)
lldb.Stdout = os.Stdout
var out bytes.Buffer
lldb.Stderr = io.MultiWriter(&out, os.Stderr)
err = lldb.Start()
if err == nil {
// Forward SIGQUIT to the lldb driver which in turn will forward
// to the running program.
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGQUIT)
proc := lldb.Process
go func() {
for sig := range sigs {
proc.Signal(sig)
}
}()
err = lldb.Wait()
signal.Stop(sigs)
close(sigs)
}
// If the program was not started it can be retried without papering over
// real test failures.
started := bytes.HasPrefix(out, []byte("lldb: running program"))
started := bytes.HasPrefix(out.Bytes(), []byte("lldb: running program"))
if started || err == nil || attempt == 5 {
return err
}
@@ -554,47 +528,6 @@ func runDevice(appdir, bundleID string, args []string) error {
}
}
func runLLDB(target, appdir, deviceapp string, args []string) ([]byte, error) {
var env []string
for _, e := range os.Environ() {
// Don't override TMPDIR, HOME, GOCACHE on the device.
if strings.HasPrefix(e, "TMPDIR=") || strings.HasPrefix(e, "HOME=") || strings.HasPrefix(e, "GOCACHE=") {
continue
}
env = append(env, e)
}
lldb := exec.Command(
"python",
"-", // Read script from stdin.
target,
appdir,
deviceapp,
)
lldb.Args = append(lldb.Args, args...)
lldb.Env = env
lldb.Stdin = strings.NewReader(lldbDriver)
lldb.Stdout = os.Stdout
var out bytes.Buffer
lldb.Stderr = io.MultiWriter(&out, os.Stderr)
err := lldb.Start()
if err == nil {
// Forward SIGQUIT to the lldb driver which in turn will forward
// to the running program.
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGQUIT)
proc := lldb.Process
go func() {
for sig := range sigs {
proc.Signal(sig)
}
}()
err = lldb.Wait()
signal.Stop(sigs)
close(sigs)
}
return out.Bytes(), err
}
func copyLocalDir(dst, src string) error {
if err := os.Mkdir(dst, 0755); err != nil {
return err
@@ -746,7 +679,6 @@ func infoPlist(pkgpath string) string {
<key>CFBundleSupportedPlatforms</key><array><string>iPhoneOS</string></array>
<key>CFBundleExecutable</key><string>gotest</string>
<key>CFBundleVersion</key><string>1.0</string>
<key>CFBundleShortVersionString</key><string>1.0</string>
<key>CFBundleIdentifier</key><string>` + bundleID + `</string>
<key>CFBundleResourceSpecification</key><string>ResourceRules.plist</string>
<key>LSRequiresIPhoneOS</key><true/>
@@ -807,7 +739,7 @@ import sys
import os
import signal
platform, exe, device_exe_or_pid, args = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4:]
exe, device_exe, args = sys.argv[1], sys.argv[2], sys.argv[3:]
env = []
for k, v in os.environ.items():
@@ -822,21 +754,17 @@ debugger.SetAsync(True)
debugger.SkipLLDBInitFiles(True)
err = lldb.SBError()
target = debugger.CreateTarget(exe, None, platform, True, err)
target = debugger.CreateTarget(exe, None, 'remote-ios', True, err)
if not target.IsValid() or not err.Success():
sys.stderr.write("lldb: failed to setup up target: %s\n" % (err))
sys.exit(1)
target.modules[0].SetPlatformFileSpec(lldb.SBFileSpec(device_exe))
listener = debugger.GetListener()
if platform == 'remote-ios':
target.modules[0].SetPlatformFileSpec(lldb.SBFileSpec(device_exe_or_pid))
process = target.ConnectRemote(listener, 'connect://localhost:3222', None, err)
else:
process = target.AttachToProcessWithID(listener, int(device_exe_or_pid), err)
process = target.ConnectRemote(listener, 'connect://localhost:3222', None, err)
if not err.Success():
sys.stderr.write("lldb: failed to connect to remote target %s: %s\n" % (device_exe_or_pid, err))
sys.stderr.write("lldb: failed to connect to remote target: %s\n" % (err))
sys.exit(1)
# Don't stop on signals.
@@ -849,25 +777,6 @@ for i in range(0, sigs.GetNumSignals()):
event = lldb.SBEvent()
running = False
prev_handler = None
def signal_handler(signal, frame):
process.Signal(signal)
def run_program():
# Forward SIGQUIT to the program.
prev_handler = signal.signal(signal.SIGQUIT, signal_handler)
# Tell the Go driver that the program is running and should not be retried.
sys.stderr.write("lldb: running program\n")
running = True
# Process is stopped at attach/launch. Let it run.
process.Continue()
if platform != 'remote-ios':
# For the local emulator the program is ready to run.
# For remote device runs, we need to wait for eStateConnected,
# below.
run_program()
while True:
if not listener.WaitForEvent(1, event):
continue
@@ -891,22 +800,24 @@ while True:
signal.signal(signal.SIGQUIT, prev_handler)
break
elif state == lldb.eStateConnected:
if platform == 'remote-ios':
process.RemoteLaunch(args, env, None, None, None, None, 0, False, err)
if not err.Success():
sys.stderr.write("lldb: failed to launch remote process: %s\n" % (err))
process.Kill()
debugger.Terminate()
sys.exit(1)
run_program()
process.RemoteLaunch(args, env, None, None, None, None, 0, False, err)
if not err.Success():
sys.stderr.write("lldb: failed to launch remote process: %s\n" % (err))
process.Kill()
debugger.Terminate()
sys.exit(1)
# Forward SIGQUIT to the program.
def signal_handler(signal, frame):
process.Signal(signal)
prev_handler = signal.signal(signal.SIGQUIT, signal_handler)
# Tell the Go driver that the program is running and should not be retried.
sys.stderr.write("lldb: running program\n")
running = True
# Process stops once at the beginning. Continue.
process.Continue()
exitStatus = process.GetExitStatus()
exitDesc = process.GetExitDescription()
process.Kill()
debugger.Terminate()
if exitStatus == 0 and exitDesc is not None:
# Ensure tests fail when killed by a signal.
exitStatus = 123
sys.exit(exitStatus)
`

View File

@@ -102,7 +102,7 @@
}
}
if (!global.crypto && global.require) {
if (!global.crypto) {
const nodeCrypto = require("crypto");
global.crypto = {
getRandomValues(b) {
@@ -110,9 +110,6 @@
},
};
}
if (!global.crypto) {
throw new Error("global.crypto is not available, polyfill required (getRandomValues only)");
}
if (!global.performance) {
global.performance = {
@@ -123,18 +120,12 @@
};
}
if (!global.TextEncoder && global.require) {
if (!global.TextEncoder) {
global.TextEncoder = require("util").TextEncoder;
}
if (!global.TextEncoder) {
throw new Error("global.TextEncoder is not available, polyfill required");
}
if (!global.TextDecoder && global.require) {
global.TextDecoder = require("util").TextDecoder;
}
if (!global.TextDecoder) {
throw new Error("global.TextDecoder is not available, polyfill required");
global.TextDecoder = require("util").TextDecoder;
}
// End of polyfills for common API.
@@ -264,7 +255,6 @@
// func wasmExit(code int32)
"runtime.wasmExit": (sp) => {
sp >>>= 0;
const code = this.mem.getInt32(sp + 8, true);
this.exited = true;
delete this._inst;
@@ -277,7 +267,6 @@
// func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)
"runtime.wasmWrite": (sp) => {
sp >>>= 0;
const fd = getInt64(sp + 8);
const p = getInt64(sp + 16);
const n = this.mem.getInt32(sp + 24, true);
@@ -286,19 +275,16 @@
// func resetMemoryDataView()
"runtime.resetMemoryDataView": (sp) => {
sp >>>= 0;
this.mem = new DataView(this._inst.exports.mem.buffer);
},
// func nanotime1() int64
"runtime.nanotime1": (sp) => {
sp >>>= 0;
setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000);
},
// func walltime1() (sec int64, nsec int32)
"runtime.walltime1": (sp) => {
sp >>>= 0;
const msec = (new Date).getTime();
setInt64(sp + 8, msec / 1000);
this.mem.setInt32(sp + 16, (msec % 1000) * 1000000, true);
@@ -306,7 +292,6 @@
// func scheduleTimeoutEvent(delay int64) int32
"runtime.scheduleTimeoutEvent": (sp) => {
sp >>>= 0;
const id = this._nextCallbackTimeoutID;
this._nextCallbackTimeoutID++;
this._scheduledTimeouts.set(id, setTimeout(
@@ -326,7 +311,6 @@
// func clearTimeoutEvent(id int32)
"runtime.clearTimeoutEvent": (sp) => {
sp >>>= 0;
const id = this.mem.getInt32(sp + 8, true);
clearTimeout(this._scheduledTimeouts.get(id));
this._scheduledTimeouts.delete(id);
@@ -334,13 +318,11 @@
// func getRandomData(r []byte)
"runtime.getRandomData": (sp) => {
sp >>>= 0;
crypto.getRandomValues(loadSlice(sp + 8));
},
// func finalizeRef(v ref)
"syscall/js.finalizeRef": (sp) => {
sp >>>= 0;
const id = this.mem.getUint32(sp + 8, true);
this._goRefCounts[id]--;
if (this._goRefCounts[id] === 0) {
@@ -353,51 +335,44 @@
// func stringVal(value string) ref
"syscall/js.stringVal": (sp) => {
sp >>>= 0;
storeValue(sp + 24, loadString(sp + 8));
},
// func valueGet(v ref, p string) ref
"syscall/js.valueGet": (sp) => {
sp >>>= 0;
const result = Reflect.get(loadValue(sp + 8), loadString(sp + 16));
sp = this._inst.exports.getsp() >>> 0; // see comment above
sp = this._inst.exports.getsp(); // see comment above
storeValue(sp + 32, result);
},
// func valueSet(v ref, p string, x ref)
"syscall/js.valueSet": (sp) => {
sp >>>= 0;
Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32));
},
// func valueDelete(v ref, p string)
"syscall/js.valueDelete": (sp) => {
sp >>>= 0;
Reflect.deleteProperty(loadValue(sp + 8), loadString(sp + 16));
},
// func valueIndex(v ref, i int) ref
"syscall/js.valueIndex": (sp) => {
sp >>>= 0;
storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16)));
},
// valueSetIndex(v ref, i int, x ref)
"syscall/js.valueSetIndex": (sp) => {
sp >>>= 0;
Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24));
},
// func valueCall(v ref, m string, args []ref) (ref, bool)
"syscall/js.valueCall": (sp) => {
sp >>>= 0;
try {
const v = loadValue(sp + 8);
const m = Reflect.get(v, loadString(sp + 16));
const args = loadSliceOfValues(sp + 32);
const result = Reflect.apply(m, v, args);
sp = this._inst.exports.getsp() >>> 0; // see comment above
sp = this._inst.exports.getsp(); // see comment above
storeValue(sp + 56, result);
this.mem.setUint8(sp + 64, 1);
} catch (err) {
@@ -408,12 +383,11 @@
// func valueInvoke(v ref, args []ref) (ref, bool)
"syscall/js.valueInvoke": (sp) => {
sp >>>= 0;
try {
const v = loadValue(sp + 8);
const args = loadSliceOfValues(sp + 16);
const result = Reflect.apply(v, undefined, args);
sp = this._inst.exports.getsp() >>> 0; // see comment above
sp = this._inst.exports.getsp(); // see comment above
storeValue(sp + 40, result);
this.mem.setUint8(sp + 48, 1);
} catch (err) {
@@ -424,12 +398,11 @@
// func valueNew(v ref, args []ref) (ref, bool)
"syscall/js.valueNew": (sp) => {
sp >>>= 0;
try {
const v = loadValue(sp + 8);
const args = loadSliceOfValues(sp + 16);
const result = Reflect.construct(v, args);
sp = this._inst.exports.getsp() >>> 0; // see comment above
sp = this._inst.exports.getsp(); // see comment above
storeValue(sp + 40, result);
this.mem.setUint8(sp + 48, 1);
} catch (err) {
@@ -440,13 +413,11 @@
// func valueLength(v ref) int
"syscall/js.valueLength": (sp) => {
sp >>>= 0;
setInt64(sp + 16, parseInt(loadValue(sp + 8).length));
},
// valuePrepareString(v ref) (ref, int)
"syscall/js.valuePrepareString": (sp) => {
sp >>>= 0;
const str = encoder.encode(String(loadValue(sp + 8)));
storeValue(sp + 16, str);
setInt64(sp + 24, str.length);
@@ -454,20 +425,17 @@
// valueLoadString(v ref, b []byte)
"syscall/js.valueLoadString": (sp) => {
sp >>>= 0;
const str = loadValue(sp + 8);
loadSlice(sp + 16).set(str);
},
// func valueInstanceOf(v ref, t ref) bool
"syscall/js.valueInstanceOf": (sp) => {
sp >>>= 0;
this.mem.setUint8(sp + 24, (loadValue(sp + 8) instanceof loadValue(sp + 16)) ? 1 : 0);
},
// func copyBytesToGo(dst []byte, src ref) (int, bool)
"syscall/js.copyBytesToGo": (sp) => {
sp >>>= 0;
const dst = loadSlice(sp + 8);
const src = loadValue(sp + 32);
if (!(src instanceof Uint8Array || src instanceof Uint8ClampedArray)) {
@@ -482,7 +450,6 @@
// func copyBytesToJS(dst ref, src []byte) (int, bool)
"syscall/js.copyBytesToJS": (sp) => {
sp >>>= 0;
const dst = loadValue(sp + 8);
const src = loadSlice(sp + 16);
if (!(dst instanceof Uint8Array || dst instanceof Uint8ClampedArray)) {

View File

@@ -13,8 +13,8 @@ package tar
import (
"errors"
"fmt"
"io/fs"
"math"
"os"
"path"
"reflect"
"strconv"
@@ -525,12 +525,12 @@ func (h Header) allowedFormats() (format Format, paxHdrs map[string]string, err
return format, paxHdrs, err
}
// FileInfo returns an fs.FileInfo for the Header.
func (h *Header) FileInfo() fs.FileInfo {
// FileInfo returns an os.FileInfo for the Header.
func (h *Header) FileInfo() os.FileInfo {
return headerFileInfo{h}
}
// headerFileInfo implements fs.FileInfo.
// headerFileInfo implements os.FileInfo.
type headerFileInfo struct {
h *Header
}
@@ -549,57 +549,57 @@ func (fi headerFileInfo) Name() string {
}
// Mode returns the permission and mode bits for the headerFileInfo.
func (fi headerFileInfo) Mode() (mode fs.FileMode) {
func (fi headerFileInfo) Mode() (mode os.FileMode) {
// Set file permission bits.
mode = fs.FileMode(fi.h.Mode).Perm()
mode = os.FileMode(fi.h.Mode).Perm()
// Set setuid, setgid and sticky bits.
if fi.h.Mode&c_ISUID != 0 {
mode |= fs.ModeSetuid
mode |= os.ModeSetuid
}
if fi.h.Mode&c_ISGID != 0 {
mode |= fs.ModeSetgid
mode |= os.ModeSetgid
}
if fi.h.Mode&c_ISVTX != 0 {
mode |= fs.ModeSticky
mode |= os.ModeSticky
}
// Set file mode bits; clear perm, setuid, setgid, and sticky bits.
switch m := fs.FileMode(fi.h.Mode) &^ 07777; m {
switch m := os.FileMode(fi.h.Mode) &^ 07777; m {
case c_ISDIR:
mode |= fs.ModeDir
mode |= os.ModeDir
case c_ISFIFO:
mode |= fs.ModeNamedPipe
mode |= os.ModeNamedPipe
case c_ISLNK:
mode |= fs.ModeSymlink
mode |= os.ModeSymlink
case c_ISBLK:
mode |= fs.ModeDevice
mode |= os.ModeDevice
case c_ISCHR:
mode |= fs.ModeDevice
mode |= fs.ModeCharDevice
mode |= os.ModeDevice
mode |= os.ModeCharDevice
case c_ISSOCK:
mode |= fs.ModeSocket
mode |= os.ModeSocket
}
switch fi.h.Typeflag {
case TypeSymlink:
mode |= fs.ModeSymlink
mode |= os.ModeSymlink
case TypeChar:
mode |= fs.ModeDevice
mode |= fs.ModeCharDevice
mode |= os.ModeDevice
mode |= os.ModeCharDevice
case TypeBlock:
mode |= fs.ModeDevice
mode |= os.ModeDevice
case TypeDir:
mode |= fs.ModeDir
mode |= os.ModeDir
case TypeFifo:
mode |= fs.ModeNamedPipe
mode |= os.ModeNamedPipe
}
return mode
}
// sysStat, if non-nil, populates h from system-dependent fields of fi.
var sysStat func(fi fs.FileInfo, h *Header) error
var sysStat func(fi os.FileInfo, h *Header) error
const (
// Mode constants from the USTAR spec:
@@ -623,10 +623,10 @@ const (
// If fi describes a symlink, FileInfoHeader records link as the link target.
// If fi describes a directory, a slash is appended to the name.
//
// Since fs.FileInfo's Name method only returns the base name of
// Since os.FileInfo's Name method only returns the base name of
// the file it describes, it may be necessary to modify Header.Name
// to provide the full path name of the file.
func FileInfoHeader(fi fs.FileInfo, link string) (*Header, error) {
func FileInfoHeader(fi os.FileInfo, link string) (*Header, error) {
if fi == nil {
return nil, errors.New("archive/tar: FileInfo is nil")
}
@@ -643,29 +643,29 @@ func FileInfoHeader(fi fs.FileInfo, link string) (*Header, error) {
case fi.IsDir():
h.Typeflag = TypeDir
h.Name += "/"
case fm&fs.ModeSymlink != 0:
case fm&os.ModeSymlink != 0:
h.Typeflag = TypeSymlink
h.Linkname = link
case fm&fs.ModeDevice != 0:
if fm&fs.ModeCharDevice != 0 {
case fm&os.ModeDevice != 0:
if fm&os.ModeCharDevice != 0 {
h.Typeflag = TypeChar
} else {
h.Typeflag = TypeBlock
}
case fm&fs.ModeNamedPipe != 0:
case fm&os.ModeNamedPipe != 0:
h.Typeflag = TypeFifo
case fm&fs.ModeSocket != 0:
case fm&os.ModeSocket != 0:
return nil, fmt.Errorf("archive/tar: sockets not supported")
default:
return nil, fmt.Errorf("archive/tar: unknown file mode %v", fm)
}
if fm&fs.ModeSetuid != 0 {
if fm&os.ModeSetuid != 0 {
h.Mode |= c_ISUID
}
if fm&fs.ModeSetgid != 0 {
if fm&os.ModeSetgid != 0 {
h.Mode |= c_ISGID
}
if fm&fs.ModeSticky != 0 {
if fm&os.ModeSticky != 0 {
h.Mode |= c_ISVTX
}
// If possible, populate additional fields from OS-specific

View File

@@ -7,6 +7,7 @@ package tar
import (
"bytes"
"io"
"io/ioutil"
"strconv"
"strings"
"time"
@@ -103,7 +104,7 @@ func (tr *Reader) next() (*Header, error) {
continue // This is a meta header affecting the next header
case TypeGNULongName, TypeGNULongLink:
format.mayOnlyBe(FormatGNU)
realname, err := io.ReadAll(tr)
realname, err := ioutil.ReadAll(tr)
if err != nil {
return nil, err
}
@@ -293,7 +294,7 @@ func mergePAX(hdr *Header, paxHdrs map[string]string) (err error) {
// parsePAX parses PAX headers.
// If an extended header (type 'x') is invalid, ErrHeader is returned
func parsePAX(r io.Reader) (map[string]string, error) {
buf, err := io.ReadAll(r)
buf, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
@@ -849,7 +850,7 @@ func discard(r io.Reader, n int64) error {
}
}
copySkipped, err := io.CopyN(io.Discard, r, n-seekSkipped)
copySkipped, err := io.CopyN(ioutil.Discard, r, n-seekSkipped)
if err == io.EOF && seekSkipped+copySkipped < n {
err = io.ErrUnexpectedEOF
}

View File

@@ -865,7 +865,7 @@ func TestReadTruncation(t *testing.T) {
}
cnt++
if s2 == "manual" {
if _, err = tr.writeTo(io.Discard); err != nil {
if _, err = tr.writeTo(ioutil.Discard); err != nil {
break
}
}

View File

@@ -7,7 +7,7 @@
package tar
import (
"io/fs"
"os"
"os/user"
"runtime"
"strconv"
@@ -23,7 +23,7 @@ func init() {
// The downside is that renaming uname or gname by the OS never takes effect.
var userMap, groupMap sync.Map // map[int]string
func statUnix(fi fs.FileInfo, h *Header) error {
func statUnix(fi os.FileInfo, h *Header) error {
sys, ok := fi.Sys().(*syscall.Stat_t)
if !ok {
return nil
@@ -66,7 +66,7 @@ func statUnix(fi fs.FileInfo, h *Header) error {
minor := uint32((dev & 0x00000000000000ff) >> 0)
minor |= uint32((dev & 0x00000ffffff00000) >> 12)
h.Devmajor, h.Devminor = int64(major), int64(minor)
case "darwin", "ios":
case "darwin":
// Copied from golang.org/x/sys/unix/dev_darwin.go.
major := uint32((dev >> 24) & 0xff)
minor := uint32(dev & 0xffffff)

View File

@@ -10,7 +10,6 @@ import (
"fmt"
"internal/testenv"
"io"
"io/fs"
"io/ioutil"
"math"
"os"
@@ -328,7 +327,7 @@ func TestRoundTrip(t *testing.T) {
if !reflect.DeepEqual(rHdr, hdr) {
t.Errorf("Header mismatch.\n got %+v\nwant %+v", rHdr, hdr)
}
rData, err := io.ReadAll(tr)
rData, err := ioutil.ReadAll(tr)
if err != nil {
t.Fatalf("Read: %v", err)
}
@@ -339,7 +338,7 @@ func TestRoundTrip(t *testing.T) {
type headerRoundTripTest struct {
h *Header
fm fs.FileMode
fm os.FileMode
}
func TestHeaderRoundTrip(t *testing.T) {
@@ -362,7 +361,7 @@ func TestHeaderRoundTrip(t *testing.T) {
ModTime: time.Unix(1360600852, 0),
Typeflag: TypeSymlink,
},
fm: 0777 | fs.ModeSymlink,
fm: 0777 | os.ModeSymlink,
}, {
// character device node.
h: &Header{
@@ -372,7 +371,7 @@ func TestHeaderRoundTrip(t *testing.T) {
ModTime: time.Unix(1360578951, 0),
Typeflag: TypeChar,
},
fm: 0666 | fs.ModeDevice | fs.ModeCharDevice,
fm: 0666 | os.ModeDevice | os.ModeCharDevice,
}, {
// block device node.
h: &Header{
@@ -382,7 +381,7 @@ func TestHeaderRoundTrip(t *testing.T) {
ModTime: time.Unix(1360578954, 0),
Typeflag: TypeBlock,
},
fm: 0660 | fs.ModeDevice,
fm: 0660 | os.ModeDevice,
}, {
// directory.
h: &Header{
@@ -392,7 +391,7 @@ func TestHeaderRoundTrip(t *testing.T) {
ModTime: time.Unix(1360601116, 0),
Typeflag: TypeDir,
},
fm: 0755 | fs.ModeDir,
fm: 0755 | os.ModeDir,
}, {
// fifo node.
h: &Header{
@@ -402,7 +401,7 @@ func TestHeaderRoundTrip(t *testing.T) {
ModTime: time.Unix(1360578949, 0),
Typeflag: TypeFifo,
},
fm: 0600 | fs.ModeNamedPipe,
fm: 0600 | os.ModeNamedPipe,
}, {
// setuid.
h: &Header{
@@ -412,7 +411,7 @@ func TestHeaderRoundTrip(t *testing.T) {
ModTime: time.Unix(1355405093, 0),
Typeflag: TypeReg,
},
fm: 0755 | fs.ModeSetuid,
fm: 0755 | os.ModeSetuid,
}, {
// setguid.
h: &Header{
@@ -422,7 +421,7 @@ func TestHeaderRoundTrip(t *testing.T) {
ModTime: time.Unix(1360602346, 0),
Typeflag: TypeReg,
},
fm: 0750 | fs.ModeSetgid,
fm: 0750 | os.ModeSetgid,
}, {
// sticky.
h: &Header{
@@ -432,7 +431,7 @@ func TestHeaderRoundTrip(t *testing.T) {
ModTime: time.Unix(1360602540, 0),
Typeflag: TypeReg,
},
fm: 0600 | fs.ModeSticky,
fm: 0600 | os.ModeSticky,
}, {
// hard link.
h: &Header{
@@ -805,9 +804,9 @@ func Benchmark(b *testing.B) {
b.Run(v.label, func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
// Writing to io.Discard because we want to
// Writing to ioutil.Discard because we want to
// test purely the writer code and not bring in disk performance into this.
tw := NewWriter(io.Discard)
tw := NewWriter(ioutil.Discard)
for _, file := range v.files {
if err := tw.WriteHeader(file.hdr); err != nil {
b.Errorf("unexpected WriteHeader error: %v", err)
@@ -845,7 +844,7 @@ func Benchmark(b *testing.B) {
if _, err := tr.Next(); err != nil {
b.Errorf("unexpected Next error: %v", err)
}
if _, err := io.Copy(io.Discard, tr); err != nil {
if _, err := io.Copy(ioutil.Discard, tr); err != nil {
b.Errorf("unexpected Copy error : %v", err)
}
}

View File

@@ -11,12 +11,7 @@ import (
"hash"
"hash/crc32"
"io"
"io/fs"
"os"
"path"
"sort"
"strings"
"sync"
"time"
)
@@ -26,28 +21,18 @@ var (
ErrChecksum = errors.New("zip: checksum error")
)
// A Reader serves content from a ZIP archive.
type Reader struct {
r io.ReaderAt
File []*File
Comment string
decompressors map[uint16]Decompressor
// fileList is a list of files sorted by ename,
// for use by the Open method.
fileListOnce sync.Once
fileList []fileListEntry
}
// A ReadCloser is a Reader that must be closed when no longer needed.
type ReadCloser struct {
f *os.File
Reader
}
// A File is a single file in a ZIP archive.
// The file information is in the embedded FileHeader.
// The file content can be accessed by calling Open.
type File struct {
FileHeader
zip *Reader
@@ -202,10 +187,6 @@ type checksumReader struct {
err error // sticky error
}
func (r *checksumReader) Stat() (fs.FileInfo, error) {
return headerFileInfo{&r.f.FileHeader}, nil
}
func (r *checksumReader) Read(b []byte) (n int, err error) {
if r.err != nil {
return 0, r.err
@@ -626,173 +607,3 @@ func (b *readBuf) sub(n int) readBuf {
*b = (*b)[n:]
return b2
}
// A fileListEntry is a File and its ename.
// If file == nil, the fileListEntry describes a directory, without metadata.
type fileListEntry struct {
name string
file *File // nil for directories
}
type fileInfoDirEntry interface {
fs.FileInfo
fs.DirEntry
}
func (e *fileListEntry) stat() fileInfoDirEntry {
if e.file != nil {
return headerFileInfo{&e.file.FileHeader}
}
return e
}
// Only used for directories.
func (f *fileListEntry) Name() string { _, elem, _ := split(f.name); return elem }
func (f *fileListEntry) Size() int64 { return 0 }
func (f *fileListEntry) ModTime() time.Time { return time.Time{} }
func (f *fileListEntry) Mode() fs.FileMode { return fs.ModeDir | 0555 }
func (f *fileListEntry) Type() fs.FileMode { return fs.ModeDir }
func (f *fileListEntry) IsDir() bool { return true }
func (f *fileListEntry) Sys() interface{} { return nil }
func (f *fileListEntry) Info() (fs.FileInfo, error) { return f, nil }
// toValidName coerces name to be a valid name for fs.FS.Open.
func toValidName(name string) string {
name = strings.ReplaceAll(name, `\`, `/`)
p := path.Clean(name)
if strings.HasPrefix(p, "/") {
p = p[len("/"):]
}
for strings.HasPrefix(name, "../") {
p = p[len("../"):]
}
return p
}
func (r *Reader) initFileList() {
r.fileListOnce.Do(func() {
dirs := make(map[string]bool)
for _, file := range r.File {
name := toValidName(file.Name)
for dir := path.Dir(name); dir != "."; dir = path.Dir(dir) {
dirs[dir] = true
}
r.fileList = append(r.fileList, fileListEntry{name, file})
}
for dir := range dirs {
r.fileList = append(r.fileList, fileListEntry{dir + "/", nil})
}
sort.Slice(r.fileList, func(i, j int) bool { return fileEntryLess(r.fileList[i].name, r.fileList[j].name) })
})
}
func fileEntryLess(x, y string) bool {
xdir, xelem, _ := split(x)
ydir, yelem, _ := split(y)
return xdir < ydir || xdir == ydir && xelem < yelem
}
// Open opens the named file in the ZIP archive,
// using the semantics of io.FS.Open:
// paths are always slash separated, with no
// leading / or ../ elements.
func (r *Reader) Open(name string) (fs.File, error) {
r.initFileList()
e := r.openLookup(name)
if e == nil || !fs.ValidPath(name) {
return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist}
}
if e.file == nil || strings.HasSuffix(e.file.Name, "/") {
return &openDir{e, r.openReadDir(name), 0}, nil
}
rc, err := e.file.Open()
if err != nil {
return nil, err
}
return rc.(fs.File), nil
}
func split(name string) (dir, elem string, isDir bool) {
if name[len(name)-1] == '/' {
isDir = true
name = name[:len(name)-1]
}
i := len(name) - 1
for i >= 0 && name[i] != '/' {
i--
}
if i < 0 {
return ".", name, isDir
}
return name[:i], name[i+1:], isDir
}
var dotFile = &fileListEntry{name: "./"}
func (r *Reader) openLookup(name string) *fileListEntry {
if name == "." {
return dotFile
}
dir, elem, _ := split(name)
files := r.fileList
i := sort.Search(len(files), func(i int) bool {
idir, ielem, _ := split(files[i].name)
return idir > dir || idir == dir && ielem >= elem
})
if i < len(files) {
fname := files[i].name
if fname == name || len(fname) == len(name)+1 && fname[len(name)] == '/' && fname[:len(name)] == name {
return &files[i]
}
}
return nil
}
func (r *Reader) openReadDir(dir string) []fileListEntry {
files := r.fileList
i := sort.Search(len(files), func(i int) bool {
idir, _, _ := split(files[i].name)
return idir >= dir
})
j := sort.Search(len(files), func(j int) bool {
jdir, _, _ := split(files[j].name)
return jdir > dir
})
return files[i:j]
}
type openDir struct {
e *fileListEntry
files []fileListEntry
offset int
}
func (d *openDir) Close() error { return nil }
func (d *openDir) Stat() (fs.FileInfo, error) { return d.e.stat(), nil }
func (d *openDir) Read([]byte) (int, error) {
return 0, &fs.PathError{Op: "read", Path: d.e.name, Err: errors.New("is a directory")}
}
func (d *openDir) ReadDir(count int) ([]fs.DirEntry, error) {
n := len(d.files) - d.offset
if count > 0 && n > count {
n = count
}
if n == 0 {
if count <= 0 {
return nil, nil
}
return nil, io.EOF
}
list := make([]fs.DirEntry, n)
for i := range list {
list[i] = d.files[d.offset+i].stat()
}
d.offset += n
return list, nil
}

View File

@@ -10,14 +10,12 @@ import (
"encoding/hex"
"internal/obscuretestdata"
"io"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"strings"
"testing"
"testing/fstest"
"time"
)
@@ -32,7 +30,7 @@ type ZipTest struct {
type ZipTestFile struct {
Name string
Mode fs.FileMode
Mode os.FileMode
NonUTF8 bool
ModTime time.Time
Modified time.Time
@@ -109,7 +107,7 @@ var tests = []ZipTest{
Name: "symlink",
Content: []byte("../target"),
Modified: time.Date(2012, 2, 3, 19, 56, 48, 0, timeZone(-2*time.Hour)),
Mode: 0777 | fs.ModeSymlink,
Mode: 0777 | os.ModeSymlink,
},
},
},
@@ -151,7 +149,7 @@ var tests = []ZipTest{
Name: "dir/empty/",
Content: []byte{},
Modified: time.Date(2011, 12, 8, 10, 8, 6, 0, time.UTC),
Mode: fs.ModeDir | 0777,
Mode: os.ModeDir | 0777,
},
{
Name: "readonly",
@@ -181,7 +179,7 @@ var tests = []ZipTest{
Name: "dir/empty/",
Content: []byte{},
Modified: time.Date(2011, 12, 8, 10, 8, 6, 0, timeZone(0)),
Mode: fs.ModeDir | 0777,
Mode: os.ModeDir | 0777,
},
{
Name: "readonly",
@@ -647,7 +645,7 @@ func readTestFile(t *testing.T, zt ZipTest, ft ZipTestFile, f *File) {
}
}
func testFileMode(t *testing.T, f *File, want fs.FileMode) {
func testFileMode(t *testing.T, f *File, want os.FileMode) {
mode := f.Mode()
if want == 0 {
t.Errorf("%s mode: got %v, want none", f.Name, mode)
@@ -930,7 +928,7 @@ func returnBigZipBytes() (r io.ReaderAt, size int64) {
if err != nil {
panic(err)
}
b, err = io.ReadAll(f)
b, err = ioutil.ReadAll(f)
if err != nil {
panic(err)
}
@@ -987,7 +985,7 @@ func TestIssue10957(t *testing.T) {
continue
}
if f.UncompressedSize64 < 1e6 {
n, err := io.Copy(io.Discard, r)
n, err := io.Copy(ioutil.Discard, r)
if i == 3 && err != io.ErrUnexpectedEOF {
t.Errorf("File[3] error = %v; want io.ErrUnexpectedEOF", err)
}
@@ -1029,7 +1027,7 @@ func TestIssue11146(t *testing.T) {
if err != nil {
t.Fatal(err)
}
_, err = io.ReadAll(r)
_, err = ioutil.ReadAll(r)
if err != io.ErrUnexpectedEOF {
t.Errorf("File[0] error = %v; want io.ErrUnexpectedEOF", err)
}
@@ -1072,13 +1070,3 @@ func TestIssue12449(t *testing.T) {
t.Errorf("Error reading the archive: %v", err)
}
}
func TestFS(t *testing.T) {
z, err := OpenReader("testdata/unix.zip")
if err != nil {
t.Fatal(err)
}
if err := fstest.TestFS(z, "hello", "dir/bar", "dir/empty", "readonly"); err != nil {
t.Fatal(err)
}
}

View File

@@ -8,6 +8,7 @@ import (
"compress/flate"
"errors"
"io"
"io/ioutil"
"sync"
)
@@ -110,7 +111,7 @@ func init() {
compressors.Store(Store, Compressor(func(w io.Writer) (io.WriteCloser, error) { return &nopCloser{w}, nil }))
compressors.Store(Deflate, Compressor(func(w io.Writer) (io.WriteCloser, error) { return newFlateWriter(w), nil }))
decompressors.Store(Store, Decompressor(io.NopCloser))
decompressors.Store(Store, Decompressor(ioutil.NopCloser))
decompressors.Store(Deflate, Decompressor(newFlateReader))
}

View File

@@ -20,7 +20,7 @@ fields must be used instead.
package zip
import (
"io/fs"
"os"
"path"
"time"
)
@@ -137,12 +137,12 @@ type FileHeader struct {
ExternalAttrs uint32 // Meaning depends on CreatorVersion
}
// FileInfo returns an fs.FileInfo for the FileHeader.
func (h *FileHeader) FileInfo() fs.FileInfo {
// FileInfo returns an os.FileInfo for the FileHeader.
func (h *FileHeader) FileInfo() os.FileInfo {
return headerFileInfo{h}
}
// headerFileInfo implements fs.FileInfo.
// headerFileInfo implements os.FileInfo.
type headerFileInfo struct {
fh *FileHeader
}
@@ -161,20 +161,17 @@ func (fi headerFileInfo) ModTime() time.Time {
}
return fi.fh.Modified.UTC()
}
func (fi headerFileInfo) Mode() fs.FileMode { return fi.fh.Mode() }
func (fi headerFileInfo) Type() fs.FileMode { return fi.fh.Mode().Type() }
func (fi headerFileInfo) Mode() os.FileMode { return fi.fh.Mode() }
func (fi headerFileInfo) Sys() interface{} { return fi.fh }
func (fi headerFileInfo) Info() (fs.FileInfo, error) { return fi, nil }
// FileInfoHeader creates a partially-populated FileHeader from an
// fs.FileInfo.
// Because fs.FileInfo's Name method returns only the base name of
// os.FileInfo.
// Because os.FileInfo's Name method returns only the base name of
// the file it describes, it may be necessary to modify the Name field
// of the returned header to provide the full path name of the file.
// If compression is desired, callers should set the FileHeader.Method
// field; it is unset by default.
func FileInfoHeader(fi fs.FileInfo) (*FileHeader, error) {
func FileInfoHeader(fi os.FileInfo) (*FileHeader, error) {
size := fi.Size()
fh := &FileHeader{
Name: fi.Name(),
@@ -283,7 +280,7 @@ const (
)
// Mode returns the permission and mode bits for the FileHeader.
func (h *FileHeader) Mode() (mode fs.FileMode) {
func (h *FileHeader) Mode() (mode os.FileMode) {
switch h.CreatorVersion >> 8 {
case creatorUnix, creatorMacOSX:
mode = unixModeToFileMode(h.ExternalAttrs >> 16)
@@ -291,18 +288,18 @@ func (h *FileHeader) Mode() (mode fs.FileMode) {
mode = msdosModeToFileMode(h.ExternalAttrs)
}
if len(h.Name) > 0 && h.Name[len(h.Name)-1] == '/' {
mode |= fs.ModeDir
mode |= os.ModeDir
}
return mode
}
// SetMode changes the permission and mode bits for the FileHeader.
func (h *FileHeader) SetMode(mode fs.FileMode) {
func (h *FileHeader) SetMode(mode os.FileMode) {
h.CreatorVersion = h.CreatorVersion&0xff | creatorUnix<<8
h.ExternalAttrs = fileModeToUnixMode(mode) << 16
// set MSDOS attributes too, as the original zip does.
if mode&fs.ModeDir != 0 {
if mode&os.ModeDir != 0 {
h.ExternalAttrs |= msdosDir
}
if mode&0200 == 0 {
@@ -315,9 +312,9 @@ func (h *FileHeader) isZip64() bool {
return h.CompressedSize64 >= uint32max || h.UncompressedSize64 >= uint32max
}
func msdosModeToFileMode(m uint32) (mode fs.FileMode) {
func msdosModeToFileMode(m uint32) (mode os.FileMode) {
if m&msdosDir != 0 {
mode = fs.ModeDir | 0777
mode = os.ModeDir | 0777
} else {
mode = 0666
}
@@ -327,64 +324,64 @@ func msdosModeToFileMode(m uint32) (mode fs.FileMode) {
return mode
}
func fileModeToUnixMode(mode fs.FileMode) uint32 {
func fileModeToUnixMode(mode os.FileMode) uint32 {
var m uint32
switch mode & fs.ModeType {
switch mode & os.ModeType {
default:
m = s_IFREG
case fs.ModeDir:
case os.ModeDir:
m = s_IFDIR
case fs.ModeSymlink:
case os.ModeSymlink:
m = s_IFLNK
case fs.ModeNamedPipe:
case os.ModeNamedPipe:
m = s_IFIFO
case fs.ModeSocket:
case os.ModeSocket:
m = s_IFSOCK
case fs.ModeDevice:
if mode&fs.ModeCharDevice != 0 {
case os.ModeDevice:
if mode&os.ModeCharDevice != 0 {
m = s_IFCHR
} else {
m = s_IFBLK
}
}
if mode&fs.ModeSetuid != 0 {
if mode&os.ModeSetuid != 0 {
m |= s_ISUID
}
if mode&fs.ModeSetgid != 0 {
if mode&os.ModeSetgid != 0 {
m |= s_ISGID
}
if mode&fs.ModeSticky != 0 {
if mode&os.ModeSticky != 0 {
m |= s_ISVTX
}
return m | uint32(mode&0777)
}
func unixModeToFileMode(m uint32) fs.FileMode {
mode := fs.FileMode(m & 0777)
func unixModeToFileMode(m uint32) os.FileMode {
mode := os.FileMode(m & 0777)
switch m & s_IFMT {
case s_IFBLK:
mode |= fs.ModeDevice
mode |= os.ModeDevice
case s_IFCHR:
mode |= fs.ModeDevice | fs.ModeCharDevice
mode |= os.ModeDevice | os.ModeCharDevice
case s_IFDIR:
mode |= fs.ModeDir
mode |= os.ModeDir
case s_IFIFO:
mode |= fs.ModeNamedPipe
mode |= os.ModeNamedPipe
case s_IFLNK:
mode |= fs.ModeSymlink
mode |= os.ModeSymlink
case s_IFREG:
// nothing to do
case s_IFSOCK:
mode |= fs.ModeSocket
mode |= os.ModeSocket
}
if m&s_ISGID != 0 {
mode |= fs.ModeSetgid
mode |= os.ModeSetgid
}
if m&s_ISUID != 0 {
mode |= fs.ModeSetuid
mode |= os.ModeSetuid
}
if m&s_ISVTX != 0 {
mode |= fs.ModeSticky
mode |= os.ModeSticky
}
return mode
}

View File

@@ -9,9 +9,9 @@ import (
"encoding/binary"
"fmt"
"io"
"io/fs"
"io/ioutil"
"math/rand"
"os"
"strings"
"testing"
"time"
@@ -23,7 +23,7 @@ type WriteTest struct {
Name string
Data []byte
Method uint16
Mode fs.FileMode
Mode os.FileMode
}
var writeTests = []WriteTest{
@@ -43,19 +43,19 @@ var writeTests = []WriteTest{
Name: "setuid",
Data: []byte("setuid file"),
Method: Deflate,
Mode: 0755 | fs.ModeSetuid,
Mode: 0755 | os.ModeSetuid,
},
{
Name: "setgid",
Data: []byte("setgid file"),
Method: Deflate,
Mode: 0755 | fs.ModeSetgid,
Mode: 0755 | os.ModeSetgid,
},
{
Name: "symlink",
Data: []byte("../link/target"),
Method: Deflate,
Mode: 0755 | fs.ModeSymlink,
Mode: 0755 | os.ModeSymlink,
},
}
@@ -301,7 +301,7 @@ func TestWriterFlush(t *testing.T) {
}
func TestWriterDir(t *testing.T) {
w := NewWriter(io.Discard)
w := NewWriter(ioutil.Discard)
dw, err := w.Create("dir/")
if err != nil {
t.Fatal(err)
@@ -380,7 +380,7 @@ func testReadFile(t *testing.T, f *File, wt *WriteTest) {
if err != nil {
t.Fatal("opening:", err)
}
b, err := io.ReadAll(rc)
b, err := ioutil.ReadAll(rc)
if err != nil {
t.Fatal("reading:", err)
}

View File

@@ -13,6 +13,7 @@ import (
"hash"
"internal/testenv"
"io"
"io/ioutil"
"runtime"
"sort"
"strings"
@@ -619,7 +620,7 @@ func testZip64(t testing.TB, size int64) *rleBuffer {
t.Fatal("read:", err)
}
}
gotEnd, err := io.ReadAll(rc)
gotEnd, err := ioutil.ReadAll(rc)
if err != nil {
t.Fatal("read end:", err)
}

View File

@@ -10,6 +10,7 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"strings"
"testing"
"testing/iotest"
@@ -885,7 +886,7 @@ func TestReadEmptyBuffer(t *testing.T) {
func TestLinesAfterRead(t *testing.T) {
l := NewReaderSize(bytes.NewReader([]byte("foo")), minReadBufferSize)
_, err := io.ReadAll(l)
_, err := ioutil.ReadAll(l)
if err != nil {
t.Error(err)
return
@@ -1129,7 +1130,7 @@ func TestWriterReadFromCounts(t *testing.T) {
}
}
// A writeCountingDiscard is like io.Discard and counts the number of times
// A writeCountingDiscard is like ioutil.Discard and counts the number of times
// Write is called on it.
type writeCountingDiscard int
@@ -1299,7 +1300,7 @@ func TestReaderReset(t *testing.T) {
t.Errorf("buf = %q; want foo", buf)
}
r.Reset(strings.NewReader("bar bar"))
all, err := io.ReadAll(r)
all, err := ioutil.ReadAll(r)
if err != nil {
t.Fatal(err)
}
@@ -1644,13 +1645,13 @@ func BenchmarkReaderWriteToOptimal(b *testing.B) {
buf := make([]byte, bufSize)
r := bytes.NewReader(buf)
srcReader := NewReaderSize(onlyReader{r}, 1<<10)
if _, ok := io.Discard.(io.ReaderFrom); !ok {
b.Fatal("io.Discard doesn't support ReaderFrom")
if _, ok := ioutil.Discard.(io.ReaderFrom); !ok {
b.Fatal("ioutil.Discard doesn't support ReaderFrom")
}
for i := 0; i < b.N; i++ {
r.Seek(0, io.SeekStart)
srcReader.Reset(onlyReader{r})
n, err := srcReader.WriteTo(io.Discard)
n, err := srcReader.WriteTo(ioutil.Discard)
if err != nil {
b.Fatal(err)
}
@@ -1721,7 +1722,7 @@ func BenchmarkReaderEmpty(b *testing.B) {
str := strings.Repeat("x", 16<<10)
for i := 0; i < b.N; i++ {
br := NewReader(strings.NewReader(str))
n, err := io.Copy(io.Discard, br)
n, err := io.Copy(ioutil.Discard, br)
if err != nil {
b.Fatal(err)
}
@@ -1736,7 +1737,7 @@ func BenchmarkWriterEmpty(b *testing.B) {
str := strings.Repeat("x", 1<<10)
bs := []byte(str)
for i := 0; i < b.N; i++ {
bw := NewWriter(io.Discard)
bw := NewWriter(ioutil.Discard)
bw.Flush()
bw.WriteByte('a')
bw.Flush()
@@ -1751,7 +1752,7 @@ func BenchmarkWriterEmpty(b *testing.B) {
func BenchmarkWriterFlush(b *testing.B) {
b.ReportAllocs()
bw := NewWriter(io.Discard)
bw := NewWriter(ioutil.Discard)
str := strings.Repeat("x", 50)
for i := 0; i < b.N; i++ {
bw.WriteString(str)

View File

@@ -3,10 +3,10 @@
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
# Usage: buildall.bash [-e] [pattern]
# Usage: buildall.sh [-e] [pattern]
#
# buildall.bash builds the standard library for all Go-supported
# architectures. It is used by the "misc-compile" trybot builders,
# architectures. It is used by the "all-compile" trybot builder,
# as a smoke test to quickly flag portability issues.
#
# Options:
@@ -37,11 +37,12 @@ GOROOT="$(cd .. && pwd)"
gettargets() {
../bin/go tool dist list | sed -e 's|/|-|'
echo linux-386-387
echo linux-arm-arm5
}
selectedtargets() {
gettargets | egrep "$pattern"
gettargets | egrep -v 'android-arm|darwin-arm64' | egrep "$pattern"
}
# put linux first in the target list to get all the architectures up front.
@@ -63,11 +64,15 @@ do
echo "### Building $target"
export GOOS=$(echo $target | sed 's/-.*//')
export GOARCH=$(echo $target | sed 's/.*-//')
unset GOARM
unset GO386 GOARM
if [ "$GOARCH" = "arm5" ]; then
export GOARCH=arm
export GOARM=5
fi
if [ "$GOARCH" = "387" ]; then
export GOARCH=386
export GO386=387
fi
# Build and vet everything.
# cmd/go/internal/work/exec.go enables the same vet flags during go test of std cmd

View File

@@ -227,26 +227,19 @@ func IndexAny(s []byte, chars string) int {
continue
}
r, width = utf8.DecodeRune(s[i:])
if r != utf8.RuneError {
// r is 2 to 4 bytes
if len(chars) == width {
if chars == string(r) {
if r == utf8.RuneError {
for _, r = range chars {
if r == utf8.RuneError {
return i
}
continue
}
// Use bytealg.IndexString for performance if available.
if bytealg.MaxLen >= width {
if bytealg.IndexString(chars, string(r)) >= 0 {
return i
}
continue
}
continue
}
for _, ch := range chars {
if r == ch {
return i
}
// r is 2 to 4 bytes. Using strings.Index is more reasonable, but as the bytes
// package should not import the strings package, use bytealg.IndexString
// instead. And this does not seem to lose much performance.
if chars == string(r) || bytealg.IndexString(chars, string(r)) >= 0 {
return i
}
}
return -1
@@ -311,26 +304,19 @@ func LastIndexAny(s []byte, chars string) int {
}
r, size := utf8.DecodeLastRune(s[:i])
i -= size
if r != utf8.RuneError {
// r is 2 to 4 bytes
if len(chars) == size {
if chars == string(r) {
if r == utf8.RuneError {
for _, r = range chars {
if r == utf8.RuneError {
return i
}
continue
}
// Use bytealg.IndexString for performance if available.
if bytealg.MaxLen >= size {
if bytealg.IndexString(chars, string(r)) >= 0 {
return i
}
continue
}
continue
}
for _, ch := range chars {
if r == ch {
return i
}
// r is 2 to 4 bytes. Using strings.Index is more reasonable, but as the bytes
// package should not import the strings package, use bytealg.IndexString
// instead. And this does not seem to lose much performance.
if chars == string(r) || bytealg.IndexString(chars, string(r)) >= 0 {
return i
}
}
return -1

View File

@@ -8,6 +8,7 @@ import (
. "bytes"
"fmt"
"io"
"io/ioutil"
"sync"
"testing"
)
@@ -234,7 +235,7 @@ func TestReaderCopyNothing(t *testing.T) {
type justWriter struct {
io.Writer
}
discard := justWriter{io.Discard} // hide ReadFrom
discard := justWriter{ioutil.Discard} // hide ReadFrom
var with, withOut nErr
with.n, with.err = io.Copy(discard, NewReader(nil))
@@ -247,7 +248,7 @@ func TestReaderCopyNothing(t *testing.T) {
// tests that Len is affected by reads, but Size is not.
func TestReaderLenSize(t *testing.T) {
r := NewReader([]byte("abc"))
io.CopyN(io.Discard, r, 1)
io.CopyN(ioutil.Discard, r, 1)
if r.Len() != 2 {
t.Errorf("Len = %d; want 2", r.Len())
}
@@ -267,7 +268,7 @@ func TestReaderReset(t *testing.T) {
if err := r.UnreadRune(); err == nil {
t.Errorf("UnreadRune: expected error, got nil")
}
buf, err := io.ReadAll(r)
buf, err := ioutil.ReadAll(r)
if err != nil {
t.Errorf("ReadAll: unexpected error: %v", err)
}
@@ -313,7 +314,7 @@ func TestReaderZero(t *testing.T) {
t.Errorf("UnreadRune: got nil, want error")
}
if n, err := (&Reader{}).WriteTo(io.Discard); n != 0 || err != nil {
if n, err := (&Reader{}).WriteTo(ioutil.Discard); n != 0 || err != nil {
t.Errorf("WriteTo: got %d, %v; want 0, nil", n, err)
}
}

View File

@@ -73,37 +73,29 @@ func testAddr2Line(t *testing.T, exepath, addr string) {
if err != nil {
t.Fatalf("Stat failed: %v", err)
}
// Debug paths are stored slash-separated, so convert to system-native.
srcPath = filepath.FromSlash(srcPath)
fi2, err := os.Stat(srcPath)
// If GOROOT_FINAL is set and srcPath is not the file we expect, perhaps
// srcPath has had GOROOT_FINAL substituted for GOROOT and GOROOT hasn't been
// moved to its final location yet. If so, try the original location instead.
if gorootFinal := os.Getenv("GOROOT_FINAL"); gorootFinal != "" &&
(os.IsNotExist(err) || (err == nil && !os.SameFile(fi1, fi2))) {
// srcPath is clean, but GOROOT_FINAL itself might not be.
// (See https://golang.org/issue/41447.)
gorootFinal = filepath.Clean(gorootFinal)
if strings.HasPrefix(srcPath, gorootFinal) {
if gorootFinal := os.Getenv("GOROOT_FINAL"); gorootFinal != "" && strings.HasPrefix(srcPath, gorootFinal) {
if os.IsNotExist(err) || (err == nil && !os.SameFile(fi1, fi2)) {
// srcPath has had GOROOT_FINAL substituted for GOROOT, and it doesn't
// match the actual file. GOROOT probably hasn't been moved to its final
// location yet, so try the original location instead.
fi2, err = os.Stat(runtime.GOROOT() + strings.TrimPrefix(srcPath, gorootFinal))
}
}
if err != nil {
t.Fatalf("Stat failed: %v", err)
}
if !os.SameFile(fi1, fi2) {
t.Fatalf("addr2line_test.go and %s are not same file", srcPath)
}
if srcLineNo != "107" {
t.Fatalf("line number = %v; want 107", srcLineNo)
if srcLineNo != "99" {
t.Fatalf("line number = %v; want 99", srcLineNo)
}
}
// This is line 106. The test depends on that.
// This is line 98. The test depends on that.
func TestAddr2Line(t *testing.T) {
testenv.MustHaveGoBuild(t)

View File

@@ -87,10 +87,7 @@ var contexts = []*build.Context{
func contextName(c *build.Context) string {
s := c.GOOS + "-" + c.GOARCH
if c.CgoEnabled {
s += "-cgo"
}
if c.Dir != "" {
s += fmt.Sprintf(" [%s]", c.Dir)
return s + "-cgo"
}
return s
}
@@ -326,18 +323,6 @@ func compareAPI(w io.Writer, features, required, optional, exception []string, a
return
}
// aliasReplacer applies type aliases to earlier API files,
// to avoid misleading negative results.
// This makes all the references to os.FileInfo in go1.txt
// be read as if they said fs.FileInfo, since os.FileInfo is now an alias.
// If there are many of these, we could do a more general solution,
// but for now the replacer is fine.
var aliasReplacer = strings.NewReplacer(
"os.FileInfo", "fs.FileInfo",
"os.FileMode", "fs.FileMode",
"os.PathError", "fs.PathError",
)
func fileFeatures(filename string) []string {
if filename == "" {
return nil
@@ -346,9 +331,7 @@ func fileFeatures(filename string) []string {
if err != nil {
log.Fatalf("Error reading file %s: %v", filename, err)
}
s := string(bs)
s = aliasReplacer.Replace(s)
lines := strings.Split(s, "\n")
lines := strings.Split(string(bs), "\n")
var nonblank []string
for _, line := range lines {
line = strings.TrimSpace(line)
@@ -495,9 +478,6 @@ func (w *Walker) loadImports() {
cmd := exec.Command(goCmd(), "list", "-e", "-deps", "-json", "std")
cmd.Env = listEnv(w.context)
if w.context.Dir != "" {
cmd.Dir = w.context.Dir
}
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatalf("loading imports: %v\n%s", err, out)
@@ -511,7 +491,6 @@ func (w *Walker) loadImports() {
var pkg struct {
ImportPath, Dir string
ImportMap map[string]string
Standard bool
}
err := dec.Decode(&pkg)
if err == io.EOF {
@@ -524,13 +503,11 @@ func (w *Walker) loadImports() {
// - Package "unsafe" contains special signatures requiring
// extra care when printing them - ignore since it is not
// going to change w/o a language change.
// - Internal and vendored packages do not contribute to our
// API surface. (If we are running within the "std" module,
// vendored dependencies appear as themselves instead of
// their "vendor/" standard-library copies.)
// - internal and vendored packages do not contribute to our
// API surface.
// - 'go list std' does not include commands, which cannot be
// imported anyway.
if ip := pkg.ImportPath; pkg.Standard && ip != "unsafe" && !strings.HasPrefix(ip, "vendor/") && !internalPkg.MatchString(ip) {
if ip := pkg.ImportPath; ip != "unsafe" && !strings.HasPrefix(ip, "vendor/") && !internalPkg.MatchString(ip) {
stdPackages = append(stdPackages, ip)
}
importDir[pkg.ImportPath] = pkg.Dir
@@ -870,10 +847,6 @@ func (w *Walker) emitObj(obj types.Object) {
func (w *Walker) emitType(obj *types.TypeName) {
name := obj.Name()
typ := obj.Type()
if obj.IsAlias() {
w.emitf("type %s = %s", name, w.typeString(typ))
return
}
switch typ := typ.Underlying().(type) {
case *types.Struct:
w.emitStructType(name, typ)

View File

@@ -216,16 +216,3 @@ func TestIssue29837(t *testing.T) {
}
}
}
func TestIssue41358(t *testing.T) {
context := new(build.Context)
*context = build.Default
context.Dir = filepath.Join(context.GOROOT, "src")
w := NewWalker(context, context.Dir)
for _, pkg := range w.stdPackages {
if strings.HasPrefix(pkg, "vendor/") || strings.HasPrefix(pkg, "golang.org/x/") {
t.Fatalf("stdPackages contains unexpected package %s", pkg)
}
}
}

View File

@@ -82,17 +82,6 @@ func IsARM64STLXR(op obj.As) bool {
return false
}
// IsARM64TBL reports whether the op (as defined by an arm64.A*
// constant) is one of the TBL-like instructions and one of its
// inputs does not fit into prog.Reg, so require special handling.
func IsARM64TBL(op obj.As) bool {
switch op {
case arm64.AVTBL, arm64.AVMOVQ:
return true
}
return false
}
// ARM64Suffix handles the special suffix for the ARM64.
// It returns a boolean to indicate success; failure means
// cond was unrecognized.
@@ -136,6 +125,13 @@ func arm64RegisterNumber(name string, n int16) (int16, bool) {
return 0, false
}
// IsARM64TBL reports whether the op (as defined by an arm64.A*
// constant) is one of the table lookup instructions that require special
// handling.
func IsARM64TBL(op obj.As) bool {
return op == arm64.AVTBL
}
// ARM64RegisterExtension parses an ARM64 register with extension or arrangement.
func ARM64RegisterExtension(a *obj.Addr, ext string, reg, num int16, isAmount, isIndex bool) error {
Rnum := (reg & 31) + int16(num<<5)

View File

@@ -181,7 +181,7 @@ func (p *Parser) asmText(operands [][]lex.Token) {
// Argsize set below.
},
}
nameAddr.Sym.Func().Text = prog
nameAddr.Sym.Func.Text = prog
prog.To.Val = int32(argSize)
p.append(prog, "", true)
}
@@ -622,9 +622,8 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
prog.SetFrom3(a[1])
prog.To = a[2]
case sys.ARM64:
switch {
case arch.IsARM64STLXR(op):
// ARM64 instructions with one input and two outputs.
// ARM64 instructions with one input and two outputs.
if arch.IsARM64STLXR(op) {
prog.From = a[0]
prog.To = a[1]
if a[2].Type != obj.TYPE_REG {
@@ -632,16 +631,20 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
return
}
prog.RegTo2 = a[2].Reg
case arch.IsARM64TBL(op):
// one of its inputs does not fit into prog.Reg.
break
}
if arch.IsARM64TBL(op) {
prog.From = a[0]
if a[1].Type != obj.TYPE_REGLIST {
p.errorf("%s: expected list; found %s", op, obj.Dconv(prog, &a[1]))
}
prog.SetFrom3(a[1])
prog.To = a[2]
default:
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
prog.To = a[2]
break
}
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
prog.To = a[2]
case sys.I386:
prog.From = a[0]
prog.SetFrom3(a[1])

View File

@@ -31,7 +31,7 @@ func testEndToEnd(t *testing.T, goarch, file string) {
architecture, ctxt := setArch(goarch)
architecture.Init(ctxt)
lexer := lex.NewLexer(input)
parser := NewParser(ctxt, architecture, lexer, false)
parser := NewParser(ctxt, architecture, lexer)
pList := new(obj.Plist)
var ok bool
testOut = new(bytes.Buffer) // The assembler writes test output to this buffer.
@@ -257,11 +257,11 @@ func isHexes(s string) bool {
return true
}
// It would be nice if the error messages always began with
// It would be nice if the error messages began with
// the standard file:line: prefix,
// but that's not where we are today.
// It might be at the beginning but it might be in the middle of the printed instruction.
var fileLineRE = regexp.MustCompile(`(?:^|\()(testdata[/\\][0-9a-z]+\.s:[0-9]+)(?:$|\)|:)`)
var fileLineRE = regexp.MustCompile(`(?:^|\()(testdata[/\\][0-9a-z]+\.s:[0-9]+)(?:$|\))`)
// Same as in test/run.go
var (
@@ -273,7 +273,7 @@ func testErrors(t *testing.T, goarch, file string) {
input := filepath.Join("testdata", file+".s")
architecture, ctxt := setArch(goarch)
lexer := lex.NewLexer(input)
parser := NewParser(ctxt, architecture, lexer, false)
parser := NewParser(ctxt, architecture, lexer)
pList := new(obj.Plist)
var ok bool
testOut = new(bytes.Buffer) // The assembler writes test output to this buffer.
@@ -281,7 +281,6 @@ func testErrors(t *testing.T, goarch, file string) {
defer ctxt.Bso.Flush()
failed := false
var errBuf bytes.Buffer
parser.errorWriter = &errBuf
ctxt.DiagFunc = func(format string, args ...interface{}) {
failed = true
s := fmt.Sprintf(format, args...)
@@ -293,7 +292,7 @@ func testErrors(t *testing.T, goarch, file string) {
pList.Firstpc, ok = parser.Parse()
obj.Flushplist(ctxt, pList, nil, "")
if ok && !failed {
t.Errorf("asm: %s had no errors", file)
t.Errorf("asm: %s had no errors", goarch)
}
errors := map[string]string{}
@@ -354,7 +353,12 @@ func testErrors(t *testing.T, goarch, file string) {
}
func Test386EndToEnd(t *testing.T) {
testEndToEnd(t, "386", "386")
defer func(old string) { objabi.GO386 = old }(objabi.GO386)
for _, go386 := range []string{"387", "sse2"} {
t.Logf("GO386=%v", go386)
objabi.GO386 = go386
testEndToEnd(t, "386", "386")
}
}
func TestARMEndToEnd(t *testing.T) {
@@ -369,10 +373,6 @@ func TestARMEndToEnd(t *testing.T) {
}
}
func TestGoBuildErrors(t *testing.T) {
testErrors(t, "amd64", "buildtagerror")
}
func TestARMErrors(t *testing.T) {
testErrors(t, "arm", "armerror")
}
@@ -442,6 +442,10 @@ func TestPPC64EndToEnd(t *testing.T) {
testEndToEnd(t, "ppc64", "ppc64")
}
func TestPPC64Encoder(t *testing.T) {
testEndToEnd(t, "ppc64", "ppc64enc")
}
func TestRISCVEncoder(t *testing.T) {
testEndToEnd(t, "riscv64", "riscvenc")
}

View File

@@ -57,7 +57,7 @@ var exprTests = []exprTest{
}
func TestExpr(t *testing.T) {
p := NewParser(nil, nil, nil, false) // Expression evaluation uses none of these fields of the parser.
p := NewParser(nil, nil, nil) // Expression evaluation uses none of these fields of the parser.
for i, test := range exprTests {
p.start(lex.Tokenize(test.input))
result := int64(p.expr())
@@ -113,7 +113,7 @@ func TestBadExpr(t *testing.T) {
}
func runBadTest(i int, test badExprTest, t *testing.T) (err error) {
p := NewParser(nil, nil, nil, false) // Expression evaluation uses none of these fields of the parser.
p := NewParser(nil, nil, nil) // Expression evaluation uses none of these fields of the parser.
p.start(lex.Tokenize(test.input))
return tryParse(t, func() {
p.expr()

View File

@@ -39,7 +39,7 @@ func testBadInstParser(t *testing.T, goarch string, tests []badInstTest) {
for i, test := range tests {
arch, ctxt := setArch(goarch)
tokenizer := lex.NewTokenizer("", strings.NewReader(test.input+"\n"), nil)
parser := NewParser(ctxt, arch, tokenizer, false)
parser := NewParser(ctxt, arch, tokenizer)
err := tryParse(t, func() {
parser.Parse()

View File

@@ -28,7 +28,7 @@ func setArch(goarch string) (*arch.Arch, *obj.Link) {
func newParser(goarch string) *Parser {
architecture, ctxt := setArch(goarch)
return NewParser(ctxt, architecture, nil, false)
return NewParser(ctxt, architecture, nil)
}
// tryParse executes parse func in panicOnError=true context.
@@ -75,12 +75,7 @@ func testOperandParser(t *testing.T, parser *Parser, tests []operandTest) {
parser.start(lex.Tokenize(test.input))
addr := obj.Addr{}
parser.operand(&addr)
var result string
if parser.compilingRuntime {
result = obj.DconvWithABIDetail(&emptyProg, &addr)
} else {
result = obj.Dconv(&emptyProg, &addr)
}
result := obj.Dconv(&emptyProg, &addr)
if result != test.output {
t.Errorf("fail at %s: got %s; expected %s\n", test.input, result, test.output)
}
@@ -91,9 +86,6 @@ func TestAMD64OperandParser(t *testing.T) {
parser := newParser("amd64")
testOperandParser(t, parser, amd64OperandTests)
testBadOperandParser(t, parser, amd64BadOperandTests)
parser.compilingRuntime = true
testOperandParser(t, parser, amd64RuntimeOperandTests)
testBadOperandParser(t, parser, amd64BadOperandRuntimeTests)
}
func Test386OperandParser(t *testing.T) {
@@ -149,7 +141,7 @@ func TestFuncAddress(t *testing.T) {
parser := newParser(sub.arch)
for _, test := range sub.tests {
parser.start(lex.Tokenize(test.input))
name, _, ok := parser.funcAddress()
name, ok := parser.funcAddress()
isFuncSym := strings.HasSuffix(test.input, "(SB)") &&
// Ignore static symbols.
@@ -306,11 +298,6 @@ var amd64OperandTests = []operandTest{
{"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.
}
var amd64RuntimeOperandTests = []operandTest{
{"$bar<ABI0>(SB)", "$bar<ABI0>(SB)"},
{"$foo<ABIInternal>(SB)", "$foo<ABIInternal>(SB)"},
}
var amd64BadOperandTests = []badOperandTest{
{"[", "register list: expected ']', found EOF"},
{"[4", "register list: bad low register in `[4`"},
@@ -324,11 +311,6 @@ var amd64BadOperandTests = []badOperandTest{
{"[X0-X1-X2]", "register list: expected ']' after `[X0-X1`, found '-'"},
{"[X0,X3]", "register list: expected '-' after `[X0`, found ','"},
{"[X0,X1,X2,X3]", "register list: expected '-' after `[X0`, found ','"},
{"$foo<ABI0>", "ABI selector only permitted when compiling runtime, reference was to \"foo\""},
}
var amd64BadOperandRuntimeTests = []badOperandTest{
{"$foo<bletch>", "malformed ABI selector \"bletch\" in reference to \"foo\""},
}
var x86OperandTests = []operandTest{

View File

@@ -25,26 +25,24 @@ import (
)
type Parser struct {
lex lex.TokenReader
lineNum int // Line number in source file.
errorLine int // Line number of last error.
errorCount int // Number of errors.
sawCode bool // saw code in this file (as opposed to comments and blank lines)
pc int64 // virtual PC; count of Progs; doesn't advance for GLOBL or DATA.
input []lex.Token
inputPos int
pendingLabels []string // Labels to attach to next instruction.
labels map[string]*obj.Prog
toPatch []Patch
addr []obj.Addr
arch *arch.Arch
ctxt *obj.Link
firstProg *obj.Prog
lastProg *obj.Prog
dataAddr map[string]int64 // Most recent address for DATA for this symbol.
isJump bool // Instruction being assembled is a jump.
compilingRuntime bool
errorWriter io.Writer
lex lex.TokenReader
lineNum int // Line number in source file.
errorLine int // Line number of last error.
errorCount int // Number of errors.
pc int64 // virtual PC; count of Progs; doesn't advance for GLOBL or DATA.
input []lex.Token
inputPos int
pendingLabels []string // Labels to attach to next instruction.
labels map[string]*obj.Prog
toPatch []Patch
addr []obj.Addr
arch *arch.Arch
ctxt *obj.Link
firstProg *obj.Prog
lastProg *obj.Prog
dataAddr map[string]int64 // Most recent address for DATA for this symbol.
isJump bool // Instruction being assembled is a jump.
errorWriter io.Writer
}
type Patch struct {
@@ -52,15 +50,14 @@ type Patch struct {
label string
}
func NewParser(ctxt *obj.Link, ar *arch.Arch, lexer lex.TokenReader, compilingRuntime bool) *Parser {
func NewParser(ctxt *obj.Link, ar *arch.Arch, lexer lex.TokenReader) *Parser {
return &Parser{
ctxt: ctxt,
arch: ar,
lex: lexer,
labels: make(map[string]*obj.Prog),
dataAddr: make(map[string]int64),
errorWriter: os.Stderr,
compilingRuntime: compilingRuntime,
ctxt: ctxt,
arch: ar,
lex: lexer,
labels: make(map[string]*obj.Prog),
dataAddr: make(map[string]int64),
errorWriter: os.Stderr,
}
}
@@ -135,30 +132,6 @@ func (p *Parser) ParseSymABIs(w io.Writer) bool {
return p.errorCount == 0
}
// nextToken returns the next non-build-comment token from the lexer.
// It reports misplaced //go:build comments but otherwise discards them.
func (p *Parser) nextToken() lex.ScanToken {
for {
tok := p.lex.Next()
if tok == lex.BuildComment {
if p.sawCode {
p.errorf("misplaced //go:build comment")
}
continue
}
if tok != '\n' {
p.sawCode = true
}
if tok == '#' {
// A leftover wisp of a #include/#define/etc,
// to let us know that p.sawCode should be true now.
// Otherwise ignored.
continue
}
return tok
}
}
// line consumes a single assembly line from p.lex of the form
//
// {label:} WORD[.cond] [ arg {, arg} ] (';' | '\n')
@@ -173,7 +146,7 @@ next:
// Skip newlines.
var tok lex.ScanToken
for {
tok = p.nextToken()
tok = p.lex.Next()
// We save the line number here so error messages from this instruction
// are labeled with this line. Otherwise we complain after we've absorbed
// the terminating newline and the line numbers are off by one in errors.
@@ -206,11 +179,11 @@ next:
items = make([]lex.Token, 0, 3)
}
for {
tok = p.nextToken()
tok = p.lex.Next()
if len(operands) == 0 && len(items) == 0 {
if p.arch.InFamily(sys.ARM, sys.ARM64, sys.AMD64, sys.I386) && tok == '.' {
// Suffixes: ARM conditionals or x86 modifiers.
tok = p.nextToken()
tok = p.lex.Next()
str := p.lex.Text()
if tok != scanner.Ident {
p.errorf("instruction suffix expected identifier, found %s", str)
@@ -312,8 +285,8 @@ func (p *Parser) symDefRef(w io.Writer, word string, operands [][]lex.Token) {
// Defines text symbol in operands[0].
if len(operands) > 0 {
p.start(operands[0])
if name, abi, ok := p.funcAddress(); ok {
fmt.Fprintf(w, "def %s %s\n", name, abi)
if name, ok := p.funcAddress(); ok {
fmt.Fprintf(w, "def %s ABI0\n", name)
}
}
return
@@ -331,8 +304,8 @@ func (p *Parser) symDefRef(w io.Writer, word string, operands [][]lex.Token) {
// Search for symbol references.
for _, op := range operands {
p.start(op)
if name, abi, ok := p.funcAddress(); ok {
fmt.Fprintf(w, "ref %s %s\n", name, abi)
if name, ok := p.funcAddress(); ok {
fmt.Fprintf(w, "ref %s ABI0\n", name)
}
}
}
@@ -767,19 +740,20 @@ func (p *Parser) symbolReference(a *obj.Addr, name string, prefix rune) {
case '*':
a.Type = obj.TYPE_INDIR
}
// Parse optional <> (indicates a static symbol) or
// <ABIxxx> (selecting text symbol with specific ABI).
doIssueError := true
isStatic, abi := p.symRefAttrs(name, doIssueError)
// Weirdness with statics: Might now have "<>".
isStatic := false
if p.peek() == '<' {
isStatic = true
p.next()
p.get('>')
}
if p.peek() == '+' || p.peek() == '-' {
a.Offset = int64(p.expr())
}
if isStatic {
a.Sym = p.ctxt.LookupStatic(name)
} else {
a.Sym = p.ctxt.LookupABI(name, abi)
a.Sym = p.ctxt.Lookup(name)
}
if p.peek() == scanner.EOF {
if prefix == 0 && p.isJump {
@@ -824,60 +798,12 @@ func (p *Parser) setPseudoRegister(addr *obj.Addr, reg string, isStatic bool, pr
}
}
// symRefAttrs parses an optional function symbol attribute clause for
// the function symbol 'name', logging an error for a malformed
// attribute clause if 'issueError' is true. The return value is a
// (boolean, ABI) pair indicating that the named symbol is either
// static or a particular ABI specification.
//
// The expected form of the attribute clause is:
//
// empty, yielding (false, obj.ABI0)
// "<>", yielding (true, obj.ABI0)
// "<ABI0>" yielding (false, obj.ABI0)
// "<ABIInternal>" yielding (false, obj.ABIInternal)
//
// Anything else beginning with "<" logs an error if issueError is
// true, otherwise returns (false, obj.ABI0).
//
func (p *Parser) symRefAttrs(name string, issueError bool) (bool, obj.ABI) {
abi := obj.ABI0
isStatic := false
if p.peek() != '<' {
return isStatic, abi
}
p.next()
tok := p.peek()
if tok == '>' {
isStatic = true
} else if tok == scanner.Ident {
abistr := p.get(scanner.Ident).String()
if !p.compilingRuntime {
if issueError {
p.errorf("ABI selector only permitted when compiling runtime, reference was to %q", name)
}
} else {
theabi, valid := obj.ParseABI(abistr)
if !valid {
if issueError {
p.errorf("malformed ABI selector %q in reference to %q",
abistr, name)
}
} else {
abi = theabi
}
}
}
p.get('>')
return isStatic, abi
}
// funcAddress parses an external function address. This is a
// constrained form of the operand syntax that's always SB-based,
// non-static, and has at most a simple integer offset:
//
// [$|*]sym[<abi>][+Int](SB)
func (p *Parser) funcAddress() (string, obj.ABI, bool) {
// [$|*]sym[+Int](SB)
func (p *Parser) funcAddress() (string, bool) {
switch p.peek() {
case '$', '*':
// Skip prefix.
@@ -887,32 +813,25 @@ func (p *Parser) funcAddress() (string, obj.ABI, bool) {
tok := p.next()
name := tok.String()
if tok.ScanToken != scanner.Ident || p.atStartOfRegister(name) {
return "", obj.ABI0, false
}
// Parse optional <> (indicates a static symbol) or
// <ABIxxx> (selecting text symbol with specific ABI).
noErrMsg := false
isStatic, abi := p.symRefAttrs(name, noErrMsg)
if isStatic {
return "", obj.ABI0, false // This function rejects static symbols.
return "", false
}
tok = p.next()
if tok.ScanToken == '+' {
if p.next().ScanToken != scanner.Int {
return "", obj.ABI0, false
return "", false
}
tok = p.next()
}
if tok.ScanToken != '(' {
return "", obj.ABI0, false
return "", false
}
if reg := p.next(); reg.ScanToken != scanner.Ident || reg.String() != "SB" {
return "", obj.ABI0, false
return "", false
}
if p.next().ScanToken != ')' || p.peek() != scanner.EOF {
return "", obj.ABI0, false
return "", false
}
return name, abi, true
return name, true
}
// registerIndirect parses the general form of a register indirection.

View File

@@ -37,7 +37,6 @@ func TestErroneous(t *testing.T) {
{"TEXT", "$0É:0, 0, $1", "expected end of operand, found É"}, // Issue #12467.
{"TEXT", "$:0:(SB, 0, $1", "expected '(', found 0"}, // Issue 12468.
{"TEXT", "@B(SB),0,$0", "expected '(', found B"}, // Issue 23580.
{"TEXT", "foo<ABIInternal>(SB),0", "ABI selector only permitted when compiling runtime, reference was to \"foo\""},
{"FUNCDATA", "", "expect two operands for FUNCDATA"},
{"FUNCDATA", "(SB ", "expect two operands for FUNCDATA"},
{"DATA", "", "expect two operands for DATA"},

View File

@@ -81,8 +81,6 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
SHA512H2 V4.D2, V3, V2 // 628464ce
SHA512SU0 V9.D2, V8.D2 // 2881c0ce
SHA512SU1 V7.D2, V6.D2, V5.D2 // c58867ce
VRAX1 V26.D2, V29.D2, V30.D2 // be8f7ace
VXAR $63, V27.D2, V21.D2, V26.D2 // bafe9bce
VADDV V0.S4, V0 // 00b8b14e
VMOVI $82, V0.B16 // 40e6024f
VUADDLV V6.B16, V6 // c638306e
@@ -141,8 +139,6 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
VTBL V14.B16, [V3.B16, V4.B16, V5.B16], V17.B16 // 71400e4e
VTBL V13.B16, [V29.B16, V30.B16, V31.B16, V0.B16], V28.B16 // bc630d4e
VTBL V3.B8, [V27.B16], V8.B8 // 6803030e
VEOR3 V2.B16, V7.B16, V12.B16, V25.B16 // 990907ce
VBCAX V1.B16, V2.B16, V26.B16, V31.B16 // 5f0722ce
VZIP1 V16.H8, V3.H8, V19.H8 // 7338504e
VZIP2 V22.D2, V25.D2, V21.D2 // 357bd64e
VZIP1 V6.D2, V9.D2, V11.D2 // 2b39c64e
@@ -222,10 +218,8 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
FMOVD $(28.0), F4 // 0490671e
// move a large constant to a Vd.
VMOVS $0x80402010, V11 // VMOVS $2151686160, V11
VMOVD $0x8040201008040201, V20 // VMOVD $-9205322385119247871, V20
VMOVQ $0x7040201008040201, $0x8040201008040201, V10 // VMOVQ $8088500183983456769, $-9205322385119247871, V10
VMOVQ $0x8040201008040202, $0x7040201008040201, V20 // VMOVQ $-9205322385119247870, $8088500183983456769, V20
FMOVD $0x8040201008040201, V20 // FMOVD $-9205322385119247871, V20
FMOVQ $0x8040201008040202, V29 // FMOVQ $-9205322385119247870, V29
FMOVS (R2)(R6), F4 // FMOVS (R2)(R6*1), F4 // 446866bc
FMOVS (R2)(R6<<2), F4 // 447866bc
@@ -346,19 +340,8 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
MOVD $0x1111ffff1111aaaa, R1 // MOVD $1230045644216969898, R1 // a1aa8a922122a2f22122e2f2
MOVD $0, R1 // 010080d2
MOVD $-1, R1 // 01008092
MOVD $0x210000, R0 // MOVD $2162688, R0 // 2004a0d2
MOVD $0xffffffffffffaaaa, R1 // MOVD $-21846, R1 // a1aa8a92
MOVD $0x1002(RSP), R1 // MOVD $4098(RSP), R1 // fb074091610b0091
MOVD $0x1708(RSP), RSP // MOVD $5896(RSP), RSP // fb0740917f231c91
MOVD $0x2001(R7), R1 // MOVD $8193(R7), R1 // fb08409161070091
MOVD $0xffffff(R7), R1 // MOVD $16777215(R7), R1 // fbfc7f9161ff3f91
MOVD $-0x1(R7), R1 // MOVD $-1(R7), R1 // e10400d1
MOVD $-0x30(R7), R1 // MOVD $-48(R7), R1 // e1c000d1
MOVD $-0x708(R7), R1 // MOVD $-1800(R7), R1 // e1201cd1
MOVD $-0x2000(RSP), R1 // MOVD $-8192(RSP), R1 // e10b40d1
MOVD $-0x10000(RSP), RSP // MOVD $-65536(RSP), RSP // ff4340d1
MOVD $0x210000, R0 // MOVD $2162688, R0 // 2004a0d2
MOVD $0xffffffffffffaaaa, R1 // MOVD $-21846, R1 // a1aa8a92
//
// CLS

View File

@@ -1,8 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#define X 1
//go:build x // ERROR "misplaced //go:build comment"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,633 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Initial set of opcode combinations based on
// improvements to processing of constant
// operands.
// Full set will be added at a later date.
#include "../../../../../runtime/textflag.h"
TEXT asmtest(SB),DUPOK|NOSPLIT,$0
// move constants
MOVD $1, R3 // 38600001
MOVD $-1, R4 // 3880ffff
MOVD $65535, R5 // 6005ffff
MOVD $65536, R6 // 64060001
MOVD $-32767, R5 // 38a08001
MOVD $-32768, R6 // 38c08000
MOVD $1234567, R5 // 6405001260a5d687
MOVW $1, R3 // 38600001
MOVW $-1, R4 // 3880ffff
MOVW $65535, R5 // 6005ffff
MOVW $65536, R6 // 64060001
MOVW $-32767, R5 // 38a08001
MOVW $-32768, R6 // 38c08000
MOVW $1234567, R5 // 6405001260a5d687
MOVD 8(R3), R4 // e8830008
MOVD (R3)(R4), R5 // 7ca4182a
MOVW 4(R3), R4 // e8830006
MOVW (R3)(R4), R5 // 7ca41aaa
MOVWZ 4(R3), R4 // 80830004
MOVWZ (R3)(R4), R5 // 7ca4182e
MOVH 4(R3), R4 // a8830004
MOVH (R3)(R4), R5 // 7ca41aae
MOVHZ 2(R3), R4 // a0830002
MOVHZ (R3)(R4), R5 // 7ca41a2e
MOVB 1(R3), R4 // 888300017c840774
MOVB (R3)(R4), R5 // 7ca418ae7ca50774
MOVBZ 1(R3), R4 // 88830001
MOVBZ (R3)(R4), R5 // 7ca418ae
MOVDBR (R3)(R4), R5 // 7ca41c28
MOVWBR (R3)(R4), R5 // 7ca41c2c
MOVHBR (R3)(R4), R5 // 7ca41e2c
MOVDU 8(R3), R4 // e8830009
MOVDU (R3)(R4), R5 // 7ca4186a
MOVWU (R3)(R4), R5 // 7ca41aea
MOVWZU 4(R3), R4 // 84830004
MOVWZU (R3)(R4), R5 // 7ca4186e
MOVHU 2(R3), R4 // ac830002
MOVHU (R3)(R4), R5 // 7ca41aee
MOVHZU 2(R3), R4 // a4830002
MOVHZU (R3)(R4), R5 // 7ca41a6e
MOVBU 1(R3), R4 // 8c8300017c840774
MOVBU (R3)(R4), R5 // 7ca418ee7ca50774
MOVBZU 1(R3), R4 // 8c830001
MOVBZU (R3)(R4), R5 // 7ca418ee
MOVD R4, 8(R3) // f8830008
MOVD R5, (R3)(R4) // 7ca4192a
MOVW R4, 4(R3) // 90830004
MOVW R5, (R3)(R4) // 7ca4192e
MOVH R4, 2(R3) // b0830002
MOVH R5, (R3)(R4) // 7ca41b2e
MOVB R4, 1(R3) // 98830001
MOVB R5, (R3)(R4) // 7ca419ae
MOVDBR R5, (R3)(R4) // 7ca41d28
MOVWBR R5, (R3)(R4) // 7ca41d2c
MOVHBR R5, (R3)(R4) // 7ca41f2c
MOVDU R4, 8(R3) // f8830009
MOVDU R5, (R3)(R4) // 7ca4196a
MOVWU R4, 4(R3) // 94830004
MOVWU R5, (R3)(R4) // 7ca4196e
MOVHU R4, 2(R3) // b4830002
MOVHU R5, (R3)(R4) // 7ca41b6e
MOVBU R4, 1(R3) // 9c830001
MOVBU R5, (R3)(R4) // 7ca419ee
ADD $1, R3 // 38630001
ADD $1, R3, R4 // 38830001
ADD $-1, R4 // 3884ffff
ADD $-1, R4, R5 // 38a4ffff
ADD $65535, R5 // 601fffff7cbf2a14
ADD $65535, R5, R6 // 601fffff7cdf2a14
ADD $65536, R6 // 3cc60001
ADD $65536, R6, R7 // 3ce60001
ADD $-32767, R5 // 38a58001
ADD $-32767, R5, R4 // 38858001
ADD $-32768, R6 // 38c68000
ADD $-32768, R6, R5 // 38a68000
ADD $1234567, R5 // 641f001263ffd6877cbf2a14
ADD $1234567, R5, R6 // 641f001263ffd6877cdf2a14
ADDIS $8, R3 // 3c630008
ADDIS $1000, R3, R4 // 3c8303e8
ANDCC $1, R3 // 70630001
ANDCC $1, R3, R4 // 70640001
ANDCC $-1, R4 // 3be0ffff7fe42039
ANDCC $-1, R4, R5 // 3be0ffff7fe52039
ANDCC $65535, R5 // 70a5ffff
ANDCC $65535, R5, R6 // 70a6ffff
ANDCC $65536, R6 // 74c60001
ANDCC $65536, R6, R7 // 74c70001
ANDCC $-32767, R5 // 3be080017fe52839
ANDCC $-32767, R5, R4 // 3be080017fe42839
ANDCC $-32768, R6 // 3be080007fe63039
ANDCC $-32768, R5, R6 // 3be080007fe62839
ANDCC $1234567, R5 // 641f001263ffd6877fe52839
ANDCC $1234567, R5, R6 // 641f001263ffd6877fe62839
ANDISCC $1, R3 // 74630001
ANDISCC $1000, R3, R4 // 746403e8
OR $1, R3 // 60630001
OR $1, R3, R4 // 60640001
OR $-1, R4 // 3be0ffff7fe42378
OR $-1, R4, R5 // 3be0ffff7fe52378
OR $65535, R5 // 60a5ffff
OR $65535, R5, R6 // 60a6ffff
OR $65536, R6 // 64c60001
OR $65536, R6, R7 // 64c70001
OR $-32767, R5 // 3be080017fe52b78
OR $-32767, R5, R6 // 3be080017fe62b78
OR $-32768, R6 // 3be080007fe63378
OR $-32768, R6, R7 // 3be080007fe73378
OR $1234567, R5 // 641f001263ffd6877fe52b78
OR $1234567, R5, R3 // 641f001263ffd6877fe32b78
XOR $1, R3 // 68630001
XOR $1, R3, R4 // 68640001
XOR $-1, R4 // 3be0ffff7fe42278
XOR $-1, R4, R5 // 3be0ffff7fe52278
XOR $65535, R5 // 68a5ffff
XOR $65535, R5, R6 // 68a6ffff
XOR $65536, R6 // 6cc60001
XOR $65536, R6, R7 // 6cc70001
XOR $-32767, R5 // 3be080017fe52a78
XOR $-32767, R5, R6 // 3be080017fe62a78
XOR $-32768, R6 // 3be080007fe63278
XOR $-32768, R6, R7 // 3be080007fe73278
XOR $1234567, R5 // 641f001263ffd6877fe52a78
XOR $1234567, R5, R3 // 641f001263ffd6877fe32a78
// TODO: the order of CR operands don't match
CMP R3, R4 // 7c232000
CMPU R3, R4 // 7c232040
CMPW R3, R4 // 7c032000
CMPWU R3, R4 // 7c032040
// TODO: constants for ADDC?
ADD R3, R4 // 7c841a14
ADD R3, R4, R5 // 7ca41a14
ADDC R3, R4 // 7c841814
ADDC R3, R4, R5 // 7ca41814
ADDE R3, R4 // 7c841914
ADDECC R3, R4 // 7c841915
ADDEV R3, R4 // 7c841d14
ADDEVCC R3, R4 // 7c841d15
ADDV R3, R4 // 7c841e14
ADDVCC R3, R4 // 7c841e15
ADDCCC R3, R4, R5 // 7ca41815
ADDME R3, R4 // 7c8301d4
ADDMECC R3, R4 // 7c8301d5
ADDMEV R3, R4 // 7c8305d4
ADDMEVCC R3, R4 // 7c8305d5
ADDCV R3, R4 // 7c841c14
ADDCVCC R3, R4 // 7c841c15
ADDZE R3, R4 // 7c830194
ADDZECC R3, R4 // 7c830195
ADDZEV R3, R4 // 7c830594
ADDZEVCC R3, R4 // 7c830595
SUBME R3, R4 // 7c8301d0
SUBMECC R3, R4 // 7c8301d1
SUBMEV R3, R4 // 7c8305d0
SUBZE R3, R4 // 7c830190
SUBZECC R3, R4 // 7c830191
SUBZEV R3, R4 // 7c830590
SUBZEVCC R3, R4 // 7c830591
AND R3, R4 // 7c841838
AND R3, R4, R5 // 7c851838
ANDN R3, R4, R5 // 7c851878
ANDCC R3, R4, R5 // 7c851839
OR R3, R4 // 7c841b78
OR R3, R4, R5 // 7c851b78
ORN R3, R4, R5 // 7c851b38
ORCC R3, R4, R5 // 7c851b79
XOR R3, R4 // 7c841a78
XOR R3, R4, R5 // 7c851a78
XORCC R3, R4, R5 // 7c851a79
NAND R3, R4, R5 // 7c851bb8
NANDCC R3, R4, R5 // 7c851bb9
EQV R3, R4, R5 // 7c851a38
EQVCC R3, R4, R5 // 7c851a39
NOR R3, R4, R5 // 7c8518f8
NORCC R3, R4, R5 // 7c8518f9
SUB R3, R4 // 7c832050
SUB R3, R4, R5 // 7ca32050
SUBC R3, R4 // 7c832010
SUBC R3, R4, R5 // 7ca32010
MULLW R3, R4 // 7c8419d6
MULLW R3, R4, R5 // 7ca419d6
MULLWCC R3, R4, R5 // 7ca419d7
MULHW R3, R4, R5 // 7ca41896
MULHWU R3, R4, R5 // 7ca41816
MULLD R3, R4 // 7c8419d2
MULLD R4, R4, R5 // 7ca421d2
MULLDCC R3, R4, R5 // 7ca419d3
MULHD R3, R4, R5 // 7ca41892
MULHDCC R3, R4, R5 // 7ca41893
MULLWV R3, R4 // 7c841dd6
MULLWV R3, R4, R5 // 7ca41dd6
MULLWVCC R3, R4, R5 // 7ca41dd7
MULHWUCC R3, R4, R5 // 7ca41817
MULLDV R3, R4, R5 // 7ca41dd2
MULLDVCC R3, R4, R5 // 7ca41dd3
DIVD R3,R4 // 7c841bd2
DIVD R3, R4, R5 // 7ca41bd2
DIVDCC R3,R4, R5 // 7ca41bd3
DIVDU R3, R4, R5 // 7ca41b92
DIVDV R3, R4, R5 // 7ca41fd2
DIVDUCC R3, R4, R5 // 7ca41b93
DIVDVCC R3, R4, R5 // 7ca41fd3
DIVDUV R3, R4, R5 // 7ca41f92
DIVDUVCC R3, R4, R5 // 7ca41f93
DIVDE R3, R4, R5 // 7ca41b52
DIVDECC R3, R4, R5 // 7ca41b53
DIVDEU R3, R4, R5 // 7ca41b12
DIVDEUCC R3, R4, R5 // 7ca41b13
REM R3, R4, R5 // 7fe41bd67fff19d67cbf2050
REMU R3, R4, R5 // 7fe41b967fff19d67bff00287cbf2050
REMD R3, R4, R5 // 7fe41bd27fff19d27cbf2050
REMDU R3, R4, R5 // 7fe41b927fff19d27cbf2050
MODUD R3, R4, R5 // 7ca41a12
MODUW R3, R4, R5 // 7ca41a16
MODSD R3, R4, R5 // 7ca41e12
MODSW R3, R4, R5 // 7ca41e16
SLW $8, R3, R4 // 5464402e
SLW R3, R4, R5 // 7c851830
SLWCC R3, R4 // 7c841831
SLD $16, R3, R4 // 786483e4
SLD R3, R4, R5 // 7c851836
SLDCC R3, R4 // 7c841837
SRW $8, R3, R4 // 5464c23e
SRW R3, R4, R5 // 7c851c30
SRWCC R3, R4 // 7c841c31
SRAW $8, R3, R4 // 7c644670
SRAW R3, R4, R5 // 7c851e30
SRAWCC R3, R4 // 7c841e31
SRD $16, R3, R4 // 78648402
SRD R3, R4, R5 // 7c851c36
SRDCC R3, R4 // 7c841c37
SRAD $16, R3, R4 // 7c648674
SRAD R3, R4, R5 // 7c851e34
SRDCC R3, R4 // 7c841c37
ROTLW $16, R3, R4 // 5464803e
ROTLW R3, R4, R5 // 5c85183e
RLWMI $7, R3, $65535, R6 // 50663c3e
RLWMICC $7, R3, $65535, R6 // 50663c3f
RLWNM $3, R4, $7, R6 // 54861f7e
RLWNMCC $3, R4, $7, R6 // 54861f7f
RLDMI $0, R4, $7, R6 // 7886076c
RLDMICC $0, R4, $7, R6 // 7886076d
RLDIMI $0, R4, $7, R6 // 788601cc
RLDIMICC $0, R4, $7, R6 // 788601cd
RLDC $0, R4, $15, R6 // 78860728
RLDCCC $0, R4, $15, R6 // 78860729
RLDCL $0, R4, $7, R6 // 78860770
RLDCLCC $0, R4, $15, R6 // 78860721
RLDCR $0, R4, $-16, R6 // 788606f2
RLDCRCC $0, R4, $-16, R6 // 788606f3
RLDICL $0, R4, $15, R6 // 788603c0
RLDICLCC $0, R4, $15, R6 // 788603c1
RLDICR $0, R4, $15, R6 // 788603c4
RLDICRCC $0, R4, $15, R6 // 788603c5
BEQ 0(PC) // 41820000
BGE 0(PC) // 40800000
BGT 4(PC) // 41810030
BLE 0(PC) // 40810000
BLT 0(PC) // 41800000
BNE 0(PC) // 40820000
JMP 8(PC) // 48000020
CRAND CR1, CR2, CR3 // 4c620a02
CRANDN CR1, CR2, CR3 // 4c620902
CREQV CR1, CR2, CR3 // 4c620a42
CRNAND CR1, CR2, CR3 // 4c6209c2
CRNOR CR1, CR2, CR3 // 4c620842
CROR CR1, CR2, CR3 // 4c620b82
CRORN CR1, CR2, CR3 // 4c620b42
CRXOR CR1, CR2, CR3 // 4c620982
ISEL $1, R3, R4, R5 // 7ca3205e
ISEL $0, R3, R4, R5 // 7ca3201e
ISEL $2, R3, R4, R5 // 7ca3209e
ISEL $3, R3, R4, R5 // 7ca320de
ISEL $4, R3, R4, R5 // 7ca3211e
POPCNTB R3, R4 // 7c6400f4
POPCNTW R3, R4 // 7c6402f4
POPCNTD R3, R4 // 7c6403f4
PASTECC R3, R4 // 7c23270d
COPY R3, R4 // 7c23260c
// load-and-reserve
LBAR (R4)(R3*1),$1,R5 // 7ca32069
LBAR (R4),$0,R5 // 7ca02068
LBAR (R3),R5 // 7ca01868
LHAR (R4)(R3*1),$1,R5 // 7ca320e9
LHAR (R4),$0,R5 // 7ca020e8
LHAR (R3),R5 // 7ca018e8
LWAR (R4)(R3*1),$1,R5 // 7ca32029
LWAR (R4),$0,R5 // 7ca02028
LWAR (R3),R5 // 7ca01828
LDAR (R4)(R3*1),$1,R5 // 7ca320a9
LDAR (R4),$0,R5 // 7ca020a8
LDAR (R3),R5 // 7ca018a8
STBCCC R3, (R4)(R5) // 7c65256d
STWCCC R3, (R4)(R5) // 7c65212d
STDCCC R3, (R4)(R5) // 7c6521ad
STHCCC R3, (R4)(R5)
SYNC // 7c0004ac
ISYNC // 4c00012c
LWSYNC // 7c2004ac
DCBF (R3)(R4) // 7c0418ac
DCBI (R3)(R4) // 7c041bac
DCBST (R3)(R4) // 7c04186c
DCBZ (R3)(R4) // 7c041fec
DCBT (R3)(R4) // 7c041a2c
ICBI (R3)(R4) // 7c041fac
// float constants
FMOVD $(0.0), F1 // f0210cd0
FMOVD $(-0.0), F1 // f0210cd0fc200850
FMOVD 8(R3), F1 // c8230008
FMOVD (R3)(R4), F1 // 7c241cae
FMOVDU 8(R3), F1 // cc230008
FMOVDU (R3)(R4), F1 // 7c241cee
FMOVS 4(R3), F1 // c0230004
FMOVS (R3)(R4), F1 // 7c241c2e
FMOVSU 4(R3), F1 // c4230004
FMOVSU (R3)(R4), F1 // 7c241c6e
FMOVD F1, 8(R3) // d8230008
FMOVD F1, (R3)(R4) // 7c241dae
FMOVDU F1, 8(R3) // dc230008
FMOVDU F1, (R3)(R4) // 7c241dee
FMOVS F1, 4(R3) // d0230004
FMOVS F1, (R3)(R4) // 7c241d2e
FMOVSU F1, 4(R3) // d4230004
FMOVSU F1, (R3)(R4) // 7c241d6e
FADD F1, F2 // fc42082a
FADD F1, F2, F3 // fc62082a
FADDCC F1, F2, F3 // fc62082b
FADDS F1, F2 // ec42082a
FADDS F1, F2, F3 // ec62082a
FADDSCC F1, F2, F3 // ec62082b
FSUB F1, F2 // fc420828
FSUB F1, F2, F3 // fc620828
FSUBCC F1, F2, F3 // fc620829
FSUBS F1, F2 // ec420828
FSUBS F1, F2, F3 // ec620828
FSUBCC F1, F2, F3 // fc620829
FMUL F1, F2 // fc420072
FMUL F1, F2, F3 // fc620072
FMULCC F1, F2, F3 // fc620073
FMULS F1, F2 // ec420072
FMULS F1, F2, F3 // ec620072
FMULSCC F1, F2, F3 // ec620073
FDIV F1, F2 // fc420824
FDIV F1, F2, F3 // fc620824
FDIVCC F1, F2, F3 // fc620825
FDIVS F1, F2 // ec420824
FDIVS F1, F2, F3 // ec620824
FDIVSCC F1, F2, F3 // ec620825
FMADD F1, F2, F3, F4 // fc8110fa
FMADDCC F1, F2, F3, F4 // fc8110fb
FMADDS F1, F2, F3, F4 // ec8110fa
FMADDSCC F1, F2, F3, F4 // ec8110fb
FMSUB F1, F2, F3, F4 // fc8110f8
FMSUBCC F1, F2, F3, F4 // fc8110f9
FMSUBS F1, F2, F3, F4 // ec8110f8
FMSUBSCC F1, F2, F3, F4 // ec8110f9
FNMADD F1, F2, F3, F4 // fc8110fe
FNMADDCC F1, F2, F3, F4 // fc8110ff
FNMADDS F1, F2, F3, F4 // ec8110fe
FNMADDSCC F1, F2, F3, F4 // ec8110ff
FNMSUB F1, F2, F3, F4 // fc8110fc
FNMSUBCC F1, F2, F3, F4 // fc8110fd
FNMSUBS F1, F2, F3, F4 // ec8110fc
FNMSUBSCC F1, F2, F3, F4 // ec8110fd
FSEL F1, F2, F3, F4 // fc8110ee
FSELCC F1, F2, F3, F4 // fc8110ef
FABS F1, F2 // fc400a10
FABSCC F1, F2 // fc400a11
FNEG F1, F2 // fc400850
FABSCC F1, F2 // fc400a11
FRSP F1, F2 // fc400818
FRSPCC F1, F2 // fc400819
FCTIW F1, F2 // fc40081c
FCTIWCC F1, F2 // fc40081d
FCTIWZ F1, F2 // fc40081e
FCTIWZCC F1, F2 // fc40081f
FCTID F1, F2 // fc400e5c
FCTIDCC F1, F2 // fc400e5d
FCTIDZ F1, F2 // fc400e5e
FCTIDZCC F1, F2 // fc400e5f
FCFID F1, F2 // fc400e9c
FCFIDCC F1, F2 // fc400e9d
FCFIDU F1, F2 // fc400f9c
FCFIDUCC F1, F2 // fc400f9d
FCFIDS F1, F2 // ec400e9c
FCFIDSCC F1, F2 // ec400e9d
FRES F1, F2 // ec400830
FRESCC F1, F2 // ec400831
FRIM F1, F2 // fc400bd0
FRIMCC F1, F2 // fc400bd1
FRIP F1, F2 // fc400b90
FRIPCC F1, F2 // fc400b91
FRIZ F1, F2 // fc400b50
FRIZCC F1, F2 // fc400b51
FRIN F1, F2 // fc400b10
FRINCC F1, F2 // fc400b11
FRSQRTE F1, F2 // fc400834
FRSQRTECC F1, F2 // fc400835
FSQRT F1, F2 // fc40082c
FSQRTCC F1, F2 // fc40082d
FSQRTS F1, F2 // ec40082c
FSQRTSCC F1, F2 // ec40082d
FCPSGN F1, F2 // fc420810
FCPSGNCC F1, F2 // fc420811
FCMPO F1, F2 // fc011040
FCMPU F1, F2 // fc011000
LVX (R3)(R4), V1 // 7c2418ce
LVXL (R3)(R4), V1 // 7c241ace
LVSL (R3)(R4), V1 // 7c24180c
LVSR (R3)(R4), V1 // 7c24184c
LVEBX (R3)(R4), V1 // 7c24180e
LVEHX (R3)(R4), V1 // 7c24184e
LVEWX (R3)(R4), V1 // 7c24188e
STVX V1, (R3)(R4) // 7c2419ce
STVXL V1, (R3)(R4) // 7c241bce
STVEBX V1, (R3)(R4) // 7c24190e
STVEHX V1, (R3)(R4) // 7c24194e
STVEWX V1, (R3)(R4) // 7c24198e
VAND V1, V2, V3 // 10611404
VANDC V1, V2, V3 // 10611444
VNAND V1, V2, V3 // 10611584
VOR V1, V2, V3 // 10611484
VORC V1, V2, V3 // 10611544
VXOR V1, V2, V3 // 106114c4
VNOR V1, V2, V3 // 10611504
VEQV V1, V2, V3 // 10611684
VADDUBM V1, V2, V3 // 10611000
VADDUHM V1, V2, V3 // 10611040
VADDUWM V1, V2, V3 // 10611080
VADDUDM V1, V2, V3 // 106110c0
VADDUQM V1, V2, V3 // 10611100
VADDCUQ V1, V2, V3 // 10611140
VADDCUW V1, V2, V3 // 10611180
VADDUBS V1, V2, V3 // 10611200
VADDUHS V1, V2, V3 // 10611240
VADDUWS V1, V2, V3 // 10611280
VSUBUBM V1, V2, V3 // 10611400
VSUBUHM V1, V2, V3 // 10611440
VSUBUWM V1, V2, V3 // 10611480
VSUBUDM V1, V2, V3 // 106114c0
VSUBUQM V1, V2, V3 // 10611500
VSUBCUQ V1, V2, V3 // 10611540
VSUBCUW V1, V2, V3 // 10611580
VSUBUBS V1, V2, V3 // 10611600
VSUBUHS V1, V2, V3 // 10611640
VSUBUWS V1, V2, V3 // 10611680
VSUBSBS V1, V2, V3 // 10611700
VSUBSHS V1, V2, V3 // 10611740
VSUBSWS V1, V2, V3 // 10611780
VSUBEUQM V1, V2, V3, V4 // 108110fe
VSUBECUQ V1, V2, V3, V4 // 108110ff
VMULESB V1, V2, V3 // 10611308
VMULOSB V1, V2, V3 // 10611108
VMULEUB V1, V2, V3 // 10611208
VMULOUB V1, V2, V3 // 10611008
VMULESH V1, V2, V3 // 10611348
VMULOSH V1, V2, V3 // 10611148
VMULEUH V1, V2, V3 // 10611248
VMULOUH V1, V2, V3 // 10611048
VMULESH V1, V2, V3 // 10611348
VMULOSW V1, V2, V3 // 10611188
VMULEUW V1, V2, V3 // 10611288
VMULOUW V1, V2, V3 // 10611088
VMULUWM V1, V2, V3 // 10611089
VPMSUMB V1, V2, V3 // 10611408
VPMSUMH V1, V2, V3 // 10611448
VPMSUMW V1, V2, V3 // 10611488
VPMSUMD V1, V2, V3 // 106114c8
VMSUMUDM V1, V2, V3, V4 // 108110e3
VRLB V1, V2, V3 // 10611004
VRLH V1, V2, V3 // 10611044
VRLW V1, V2, V3 // 10611084
VRLD V1, V2, V3 // 106110c4
VSLB V1, V2, V3 // 10611104
VSLH V1, V2, V3 // 10611144
VSLW V1, V2, V3 // 10611184
VSL V1, V2, V3 // 106111c4
VSLO V1, V2, V3 // 1061140c
VSRB V1, V2, V3 // 10611204
VSRH V1, V2, V3 // 10611244
VSRW V1, V2, V3 // 10611284
VSR V1, V2, V3 // 106112c4
VSRO V1, V2, V3 // 1061144c
VSLD V1, V2, V3 // 106115c4
VSRAB V1, V2, V3 // 10611304
VSRAH V1, V2, V3 // 10611344
VSRAW V1, V2, V3 // 10611384
VSRAD V1, V2, V3 // 106113c4
VSLDOI $3, V1, V2, V3 // 106110ec
VCLZB V1, V2 // 10400f02
VCLZH V1, V2 // 10400f42
VCLZW V1, V2 // 10400f82
VCLZD V1, V2 // 10400fc2
VPOPCNTB V1, V2 // 10400f03
VPOPCNTH V1, V2 // 10400f43
VPOPCNTW V1, V2 // 10400f83
VPOPCNTD V1, V2 // 10400fc3
VCMPEQUB V1, V2, V3 // 10611006
VCMPEQUBCC V1, V2, V3 // 10611406
VCMPEQUH V1, V2, V3 // 10611046
VCMPEQUHCC V1, V2, V3 // 10611446
VCMPEQUW V1, V2, V3 // 10611086
VCMPEQUWCC V1, V2, V3 // 10611486
VCMPEQUD V1, V2, V3 // 106110c7
VCMPEQUDCC V1, V2, V3 // 106114c7
VCMPGTUB V1, V2, V3 // 10611206
VCMPGTUBCC V1, V2, V3 // 10611606
VCMPGTUH V1, V2, V3 // 10611246
VCMPGTUHCC V1, V2, V3 // 10611646
VCMPGTUW V1, V2, V3 // 10611286
VCMPGTUWCC V1, V2, V3 // 10611686
VCMPGTUD V1, V2, V3 // 106112c7
VCMPGTUDCC V1, V2, V3 // 106116c7
VCMPGTSB V1, V2, V3 // 10611306
VCMPGTSBCC V1, V2, V3 // 10611706
VCMPGTSH V1, V2, V3 // 10611346
VCMPGTSHCC V1, V2, V3 // 10611746
VCMPGTSW V1, V2, V3 // 10611386
VCMPGTSWCC V1, V2, V3 // 10611786
VCMPGTSD V1, V2, V3 // 106113c7
VCMPGTSDCC V1, V2, V3 // 106117c7
VCMPNEZB V1, V2, V3 // 10611107
VCMPNEZBCC V1, V2, V3 // 10611507
VCMPNEB V1, V2, V3 // 10611007
VCMPNEBCC V1, V2, V3 // 10611407
VCMPNEH V1, V2, V3 // 10611047
VCMPNEHCC V1, V2, V3 // 10611447
VCMPNEW V1, V2, V3 // 10611087
VCMPNEWCC V1, V2, V3 // 10611487
VPERM V1, V2, V3, V4 // 108110eb
VPERMR V1, V2, V3, V4 // 108110fb
VPERMXOR V1, V2, V3, V4 // 108110ed
VBPERMQ V1, V2, V3 // 1061154c
VBPERMD V1, V2, V3 // 106115cc
VSEL V1, V2, V3, V4 // 108110ea
VSPLTB $1, V1, V2 // 10410a0c
VSPLTH $1, V1, V2 // 10410a4c
VSPLTW $1, V1, V2 // 10410a8c
VSPLTISB $1, V1 // 1021030c
VSPLTISW $1, V1 // 1021038c
VSPLTISH $1, V1 // 1021034c
VCIPHER V1, V2, V3 // 10611508
VCIPHERLAST V1, V2, V3 // 10611509
VNCIPHER V1, V2, V3 // 10611548
VNCIPHERLAST V1, V2, V3 // 10611549
VSBOX V1, V2 // 104105c8
VSHASIGMAW $1, V1, $15, V2 // 10418e82
VSHASIGMAD $2, V1, $15, V2 // 104196c2
LXVD2X (R3)(R4), VS1 // 7c241e98
LXV 16(R3), VS1 // f4230011
LXVL R3, R4, VS1 // 7c23221a
LXVLL R3, R4, VS1 // 7c23225a
LXVX R3, R4, VS1 // 7c232218
LXSDX (R3)(R4), VS1 // 7c241c98
STXVD2X VS1, (R3)(R4) // 7c241f98
STXV VS1,16(R3) // f4230015
STXVL VS1, R3, R4 // 7c23231a
STXVLL VS1, R3, R4 // 7c23235a
STXVX VS1, R3, R4 // 7c232318
STXSDX VS1, (R3)(R4) // 7c241d98
LXSIWAX (R3)(R4), VS1 // 7c241898
STXSIWX VS1, (R3)(R4) // 7c241918
MFVSRD VS1, R3 // 7c230066
MTVSRD R3, VS1 // 7c230166
XXLAND VS1, VS2, VS3 // f0611410
XXLOR VS1, VS2, VS3 // f0611490
XXLORC VS1, VS2, VS3 // f0611550
XXLXOR VS1, VS2, VS3 // f06114d0
XXSEL VS1, VS2, VS3, VS4 // f08110f0
XXMRGHW VS1, VS2, VS3 // f0611090
XXSPLTW VS1, $1, VS2 // f0410a90
XXPERM VS1, VS2, VS3 // f06110d0
XXSLDWI VS1, VS2, $1, VS3 // f0611110
XSCVDPSP VS1, VS2 // f0400c24
XVCVDPSP VS1, VS2 // f0400e24
XSCVSXDDP VS1, VS2 // f0400de0
XVCVDPSXDS VS1, VS2 // f0400f60
XVCVSXDDP VS1, VS2 // f0400fe0
MOVD R3, LR // 7c6803a6
MOVD R3, CTR // 7c6903a6
MOVD R3, XER // 7c6103a6
MOVD LR, R3 // 7c6802a6
MOVD CTR, R3 // 7c6902a6
MOVD XER, R3 // 7c6102a6
MOVFL CR3, CR1 // 4c8c0000
RET

View File

@@ -297,13 +297,6 @@ start:
MOVW X5, (X6) // 23205300
MOVW X5, 4(X6) // 23225300
MOVB X5, X6 // 1393820313538343
MOVH X5, X6 // 1393020313530343
MOVW X5, X6 // 1b830200
MOVBU X5, X6 // 13f3f20f
MOVHU X5, X6 // 1393020313530303
MOVWU X5, X6 // 1393020213530302
MOVF 4(X5), F0 // 07a04200
MOVF F0, 4(X5) // 27a20200
MOVF F0, F1 // d3000020
@@ -325,7 +318,7 @@ start:
// These jumps can get printed as jumps to 2 because they go to the
// second instruction in the function (the first instruction is an
// invisible stack pointer adjustment).
JMP start // JMP 2 // 6ff09fc2
JMP start // JMP 2 // 6ff01fc5
JMP (X5) // 67800200
JMP 4(X5) // 67804200
@@ -338,16 +331,16 @@ start:
JMP asmtest(SB) // 970f0000
// Branch pseudo-instructions
BEQZ X5, start // BEQZ X5, 2 // e38602c0
BGEZ X5, start // BGEZ X5, 2 // e3d402c0
BGT X5, X6, start // BGT X5, X6, 2 // e3c262c0
BGTU X5, X6, start // BGTU X5, X6, 2 // e3e062c0
BGTZ X5, start // BGTZ X5, 2 // e34e50be
BLE X5, X6, start // BLE X5, X6, 2 // e3dc62be
BLEU X5, X6, start // BLEU X5, X6, 2 // e3fa62be
BLEZ X5, start // BLEZ X5, 2 // e35850be
BLTZ X5, start // BLTZ X5, 2 // e3c602be
BNEZ X5, start // BNEZ X5, 2 // e39402be
BEQZ X5, start // BEQZ X5, 2 // e38a02c2
BGEZ X5, start // BGEZ X5, 2 // e3d802c2
BGT X5, X6, start // BGT X5, X6, 2 // e3c662c2
BGTU X5, X6, start // BGTU X5, X6, 2 // e3e462c2
BGTZ X5, start // BGTZ X5, 2 // e34250c2
BLE X5, X6, start // BLE X5, X6, 2 // e3d062c2
BLEU X5, X6, start // BLEU X5, X6, 2 // e3fe62c0
BLEZ X5, start // BLEZ X5, 2 // e35c50c0
BLTZ X5, start // BLTZ X5, 2 // e3ca02c0
BNEZ X5, start // BNEZ X5, 2 // e39802c0
// Set pseudo-instructions
SEQZ X15, X15 // 93b71700

View File

@@ -15,29 +15,27 @@ import (
)
var (
Debug = flag.Bool("debug", false, "dump instructions as they are parsed")
OutputFile = flag.String("o", "", "output file; default foo.o for /a/b/c/foo.s as first argument")
TrimPath = flag.String("trimpath", "", "remove prefix from recorded source file paths")
Shared = flag.Bool("shared", false, "generate code that can be linked into a shared library")
Dynlink = flag.Bool("dynlink", false, "support references to Go symbols defined in other shared libraries")
AllErrors = flag.Bool("e", false, "no limit on number of errors reported")
SymABIs = flag.Bool("gensymabis", false, "write symbol ABI information to output file, don't assemble")
Importpath = flag.String("p", "", "set expected package import to path")
Spectre = flag.String("spectre", "", "enable spectre mitigations in `list` (all, ret)")
CompilingRuntime = flag.Bool("compiling-runtime", false, "source to be compiled is part of the Go runtime")
Debug = flag.Bool("debug", false, "dump instructions as they are parsed")
OutputFile = flag.String("o", "", "output file; default foo.o for /a/b/c/foo.s as first argument")
PrintOut = flag.Bool("S", false, "print assembly and machine code")
TrimPath = flag.String("trimpath", "", "remove prefix from recorded source file paths")
Shared = flag.Bool("shared", false, "generate code that can be linked into a shared library")
Dynlink = flag.Bool("dynlink", false, "support references to Go symbols defined in other shared libraries")
AllErrors = flag.Bool("e", false, "no limit on number of errors reported")
SymABIs = flag.Bool("gensymabis", false, "write symbol ABI information to output file, don't assemble")
Importpath = flag.String("p", "", "set expected package import to path")
Spectre = flag.String("spectre", "", "enable spectre mitigations in `list` (all, ret)")
)
var (
D MultiFlag
I MultiFlag
PrintOut int
D MultiFlag
I MultiFlag
)
func init() {
flag.Var(&D, "D", "predefined symbol with optional simple value -D=identifier=value; can be set multiple times")
flag.Var(&I, "I", "include directory; can be set multiple times")
objabi.AddVersionFlag() // -V
objabi.Flagcount("S", "print assembly and machine code", &PrintOut)
}
// MultiFlag allows setting a value multiple times to collect a list, as in -I=dir1 -I=dir2.

View File

@@ -109,9 +109,6 @@ func (in *Input) Next() ScanToken {
in.Error("'#' must be first item on line")
}
in.beginningOfLine = in.hash()
in.text = "#"
return '#'
case scanner.Ident:
// Is it a macro name?
name := in.Stack.Text()

View File

@@ -22,13 +22,11 @@ type ScanToken rune
const (
// Asm defines some two-character lexemes. We make up
// a rune/ScanToken value for them - ugly but simple.
LSH ScanToken = -1000 - iota // << Left shift.
RSH // >> Logical right shift.
ARR // -> Used on ARM for shift type 3, arithmetic right shift.
ROT // @> Used on ARM for shift type 4, rotate right.
Include // included file started here
BuildComment // //go:build or +build comment
macroName // name of macro that should not be expanded
LSH ScanToken = -1000 - iota // << Left shift.
RSH // >> Logical right shift.
ARR // -> Used on ARM for shift type 3, arithmetic right shift.
ROT // @> Used on ARM for shift type 4, rotate right.
macroName // name of macro that should not be expanded
)
// IsRegisterShift reports whether the token is one of the ARM register shift operators.

View File

@@ -281,9 +281,6 @@ func drain(input *Input) string {
if tok == scanner.EOF {
return buf.String()
}
if tok == '#' {
continue
}
if buf.Len() > 0 {
buf.WriteByte('.')
}

View File

@@ -107,13 +107,10 @@ func (t *Tokenizer) Next() ScanToken {
if t.tok != scanner.Comment {
break
}
text := s.TokenText()
t.line += strings.Count(text, "\n")
// TODO: Use constraint.IsGoBuild once it exists.
if strings.HasPrefix(text, "//go:build") {
t.tok = BuildComment
break
}
length := strings.Count(s.TokenText(), "\n")
t.line += length
// TODO: If we ever have //go: comments in assembly, will need to keep them here.
// For now, just discard all comments.
}
switch t.tok {
case '\n':

View File

@@ -35,7 +35,9 @@ func main() {
flags.Parse()
ctxt := obj.Linknew(architecture.LinkArch)
ctxt.Debugasm = flags.PrintOut
if *flags.PrintOut {
ctxt.Debugasm = 1
}
ctxt.Flag_dynlink = *flags.Dynlink
ctxt.Flag_shared = *flags.Shared || *flags.Dynlink
ctxt.IsAsm = true
@@ -74,8 +76,7 @@ func main() {
var failedFile string
for _, f := range flag.Args() {
lexer := lex.NewLexer(f)
parser := asm.NewParser(ctxt, architecture, lexer,
*flags.CompilingRuntime)
parser := asm.NewParser(ctxt, architecture, lexer)
ctxt.DiagFunc = func(format string, args ...interface{}) {
diag = true
log.Printf(format, args...)

View File

@@ -721,7 +721,7 @@ linkage to the desired libraries. The main function is provided by
_cgo_main.c:
int main() { return 0; }
void crosscall2(void(*fn)(void*), void *a, int c, uintptr_t ctxt) { }
void crosscall2(void(*fn)(void*, int, uintptr_t), void *a, int c, uintptr_t ctxt) { }
uintptr_t _cgo_wait_runtime_init_done(void) { return 0; }
void _cgo_release_context(uintptr_t ctxt) { }
char* _cgo_topofstack(void) { return (char*)0; }

View File

@@ -298,7 +298,7 @@ func (p *Package) guessKinds(f *File) []*Name {
continue
}
if (goos == "darwin" || goos == "ios") && strings.HasSuffix(n.C, "Ref") {
if goos == "darwin" && strings.HasSuffix(n.C, "Ref") {
// For FooRef, find out if FooGetTypeID exists.
s := n.C[:len(n.C)-3] + "GetTypeID"
n := &Name{Go: s, C: s}
@@ -2448,18 +2448,6 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
tt := *t
tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}}
tt.Go = c.Ident("struct{}")
if dt.Kind == "struct" {
// We don't know what the representation of this struct is, so don't let
// anyone allocate one on the Go side. As a side effect of this annotation,
// pointers to this type will not be considered pointers in Go. They won't
// get writebarrier-ed or adjusted during a stack copy. This should handle
// all the cases badPointerTypedef used to handle, but hopefully will
// continue to work going forward without any more need for cgo changes.
tt.NotInHeap = true
// TODO: we should probably do the same for unions. Unions can't live
// on the Go heap, right? It currently doesn't work for unions because
// they are defined as a type alias for struct{}, not a defined type.
}
typedef[name.Name] = &tt
break
}
@@ -2530,7 +2518,6 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
}
t.Go = name
t.BadPointer = sub.BadPointer
t.NotInHeap = sub.NotInHeap
if unionWithPointer[sub.Go] {
unionWithPointer[t.Go] = true
}
@@ -2541,7 +2528,6 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
tt := *t
tt.Go = sub.Go
tt.BadPointer = sub.BadPointer
tt.NotInHeap = sub.NotInHeap
typedef[name.Name] = &tt
}
@@ -2845,11 +2831,21 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
tgo := t.Go
size := t.Size
talign := t.Align
if f.BitOffset > 0 || f.BitSize > 0 {
// The layout of bitfields is implementation defined,
// so we don't know how they correspond to Go fields
// even if they are aligned at byte boundaries.
continue
if f.BitSize > 0 {
switch f.BitSize {
case 8, 16, 32, 64:
default:
continue
}
size = f.BitSize / 8
name := tgo.(*ast.Ident).String()
if strings.HasPrefix(name, "int") {
name = "int"
} else {
name = "uint"
}
tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize))
talign = size
}
if talign > 0 && f.ByteOffset%talign != 0 {
@@ -3040,7 +3036,6 @@ func (c *typeConv) anonymousStructTypedef(dt *dwarf.TypedefType) bool {
// non-pointers in this type.
// TODO: Currently our best solution is to find these manually and list them as
// they come up. A better solution is desired.
// Note: DEPRECATED. There is now a better solution. Search for NotInHeap in this file.
func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
if c.badCFType(dt) {
return true
@@ -3075,7 +3070,7 @@ func (c *typeConv) badCFType(dt *dwarf.TypedefType) bool {
// We identify the correct set of types as those ending in Ref and for which
// there exists a corresponding GetTypeID function.
// See comment below for details about the bad pointers.
if goos != "darwin" && goos != "ios" {
if goos != "darwin" {
return false
}
s := dt.Name

View File

@@ -151,8 +151,7 @@ type Type struct {
Go ast.Expr
EnumValues map[string]int64
Typedef string
BadPointer bool // this pointer type should be represented as a uintptr (deprecated)
NotInHeap bool // this type should have a go:notinheap annotation
BadPointer bool
}
// A FuncType collects information about a function type in both the C and Go worlds.
@@ -170,51 +169,35 @@ func usage() {
var ptrSizeMap = map[string]int64{
"386": 4,
"alpha": 8,
"amd64": 8,
"arm": 4,
"arm64": 8,
"m68k": 4,
"mips": 4,
"mipsle": 4,
"mips64": 8,
"mips64le": 8,
"nios2": 4,
"ppc": 4,
"ppc64": 8,
"ppc64le": 8,
"riscv": 4,
"riscv64": 8,
"s390": 4,
"s390x": 8,
"sh": 4,
"shbe": 4,
"sparc": 4,
"sparc64": 8,
}
var intSizeMap = map[string]int64{
"386": 4,
"alpha": 8,
"amd64": 8,
"arm": 4,
"arm64": 8,
"m68k": 4,
"mips": 4,
"mipsle": 4,
"mips64": 8,
"mips64le": 8,
"nios2": 4,
"ppc": 4,
"ppc64": 8,
"ppc64le": 8,
"riscv": 4,
"riscv64": 8,
"s390": 4,
"s390x": 8,
"sh": 4,
"shbe": 4,
"sparc": 4,
"sparc64": 8,
}
@@ -240,7 +223,8 @@ var exportHeader = flag.String("exportheader", "", "where to write export header
var gccgo = flag.Bool("gccgo", false, "generate files for use with gccgo")
var gccgoprefix = flag.String("gccgoprefix", "", "-fgo-prefix option used with gccgo")
var gccgopkgpath = flag.String("gccgopkgpath", "", "-fgo-pkgpath option used with gccgo")
var gccgoMangler func(string) string
var gccgoMangleCheckDone bool
var gccgoNewmanglingInEffect bool
var importRuntimeCgo = flag.Bool("import_runtime_cgo", true, "import runtime/cgo in generated code")
var importSyscall = flag.Bool("import_syscall", true, "import syscall in generated code")
var goarch, goos string

View File

@@ -6,7 +6,6 @@ package main
import (
"bytes"
"cmd/internal/pkgpath"
"debug/elf"
"debug/macho"
"debug/pe"
@@ -16,6 +15,7 @@ import (
"go/token"
"internal/xcoff"
"io"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -59,14 +59,14 @@ func (p *Package) writeDefs() {
// Write C main file for using gcc to resolve imports.
fmt.Fprintf(fm, "int main() { return 0; }\n")
if *importRuntimeCgo {
fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*), void *a, int c, __SIZE_TYPE__ ctxt) { }\n")
fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*, int, __SIZE_TYPE__), void *a, int c, __SIZE_TYPE__ ctxt) { }\n")
fmt.Fprintf(fm, "__SIZE_TYPE__ _cgo_wait_runtime_init_done(void) { return 0; }\n")
fmt.Fprintf(fm, "void _cgo_release_context(__SIZE_TYPE__ ctxt) { }\n")
fmt.Fprintf(fm, "char* _cgo_topofstack(void) { return (char*)0; }\n")
} else {
// If we're not importing runtime/cgo, we *are* runtime/cgo,
// which provides these functions. We just need a prototype.
fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*), void *a, int c, __SIZE_TYPE__ ctxt);\n")
fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*, int, __SIZE_TYPE__), void *a, int c, __SIZE_TYPE__ ctxt);\n")
fmt.Fprintf(fm, "__SIZE_TYPE__ _cgo_wait_runtime_init_done(void);\n")
fmt.Fprintf(fm, "void _cgo_release_context(__SIZE_TYPE__);\n")
}
@@ -108,9 +108,6 @@ func (p *Package) writeDefs() {
sort.Strings(typedefNames)
for _, name := range typedefNames {
def := typedef[name]
if def.NotInHeap {
fmt.Fprintf(fgo2, "//go:notinheap\n")
}
fmt.Fprintf(fgo2, "type %s ", name)
// We don't have source info for these types, so write them out without source info.
// Otherwise types would look like:
@@ -852,7 +849,7 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) {
fmt.Fprintf(fgcc, "#pragma GCC diagnostic ignored \"-Wpragmas\"\n")
fmt.Fprintf(fgcc, "#pragma GCC diagnostic ignored \"-Waddress-of-packed-member\"\n")
fmt.Fprintf(fgcc, "extern void crosscall2(void (*fn)(void *), void *, int, __SIZE_TYPE__);\n")
fmt.Fprintf(fgcc, "extern void crosscall2(void (*fn)(void *, int, __SIZE_TYPE__), void *, int, __SIZE_TYPE__);\n")
fmt.Fprintf(fgcc, "extern __SIZE_TYPE__ _cgo_wait_runtime_init_done(void);\n")
fmt.Fprintf(fgcc, "extern void _cgo_release_context(__SIZE_TYPE__);\n\n")
fmt.Fprintf(fgcc, "extern char* _cgo_topofstack(void);")
@@ -862,48 +859,59 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) {
for _, exp := range p.ExpFunc {
fn := exp.Func
// Construct a struct that will be used to communicate
// arguments from C to Go. The C and Go definitions
// just have to agree. The gcc struct will be compiled
// with __attribute__((packed)) so all padding must be
// accounted for explicitly.
// Construct a gcc struct matching the gc argument and
// result frame. The gcc struct will be compiled with
// __attribute__((packed)) so all padding must be accounted
// for explicitly.
ctype := "struct {\n"
gotype := new(bytes.Buffer)
fmt.Fprintf(gotype, "struct {\n")
off := int64(0)
npad := 0
argField := func(typ ast.Expr, namePat string, args ...interface{}) {
name := fmt.Sprintf(namePat, args...)
t := p.cgoType(typ)
if off%t.Align != 0 {
pad := t.Align - off%t.Align
ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad)
off += pad
npad++
}
ctype += fmt.Sprintf("\t\t%s %s;\n", t.C, name)
fmt.Fprintf(gotype, "\t\t%s ", name)
noSourceConf.Fprint(gotype, fset, typ)
fmt.Fprintf(gotype, "\n")
off += t.Size
}
if fn.Recv != nil {
argField(fn.Recv.List[0].Type, "recv")
t := p.cgoType(fn.Recv.List[0].Type)
ctype += fmt.Sprintf("\t\t%s recv;\n", t.C)
off += t.Size
}
fntype := fn.Type
forFieldList(fntype.Params,
func(i int, aname string, atype ast.Expr) {
argField(atype, "p%d", i)
t := p.cgoType(atype)
if off%t.Align != 0 {
pad := t.Align - off%t.Align
ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad)
off += pad
npad++
}
ctype += fmt.Sprintf("\t\t%s p%d;\n", t.C, i)
off += t.Size
})
if off%p.PtrSize != 0 {
pad := p.PtrSize - off%p.PtrSize
ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad)
off += pad
npad++
}
forFieldList(fntype.Results,
func(i int, aname string, atype ast.Expr) {
argField(atype, "r%d", i)
t := p.cgoType(atype)
if off%t.Align != 0 {
pad := t.Align - off%t.Align
ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad)
off += pad
npad++
}
ctype += fmt.Sprintf("\t\t%s r%d;\n", t.C, i)
off += t.Size
})
if off%p.PtrSize != 0 {
pad := p.PtrSize - off%p.PtrSize
ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad)
off += pad
npad++
}
if ctype == "struct {\n" {
ctype += "\t\tchar unused;\n" // avoid empty struct
}
ctype += "\t}"
fmt.Fprintf(gotype, "\t}")
// Get the return type of the wrapper function
// compiled by gcc.
@@ -928,11 +936,7 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) {
}
// Build the wrapper function compiled by gcc.
gccExport := ""
if goos == "windows" {
gccExport = "__declspec(dllexport)"
}
s := fmt.Sprintf("%s %s %s(", gccExport, gccResult, exp.ExpName)
s := fmt.Sprintf("%s %s(", gccResult, exp.ExpName)
if fn.Recv != nil {
s += p.cgoType(fn.Recv.List[0].Type).C.String()
s += " recv"
@@ -954,15 +958,12 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) {
}
fmt.Fprintf(fgcch, "extern %s;\n", s)
fmt.Fprintf(fgcc, "extern void _cgoexp%s_%s(void *);\n", cPrefix, exp.ExpName)
fmt.Fprintf(fgcc, "extern void _cgoexp%s_%s(void *, int, __SIZE_TYPE__);\n", cPrefix, exp.ExpName)
fmt.Fprintf(fgcc, "\nCGO_NO_SANITIZE_THREAD")
fmt.Fprintf(fgcc, "\n%s\n", s)
fmt.Fprintf(fgcc, "{\n")
fmt.Fprintf(fgcc, "\t__SIZE_TYPE__ _cgo_ctxt = _cgo_wait_runtime_init_done();\n")
// The results part of the argument structure must be
// initialized to 0 so the write barriers generated by
// the assignments to these fields in Go are safe.
fmt.Fprintf(fgcc, "\t%s %v _cgo_a = {0};\n", ctype, p.packedAttribute())
fmt.Fprintf(fgcc, "\t%s %v _cgo_a;\n", ctype, p.packedAttribute())
if gccResult != "void" && (len(fntype.Results.List) > 1 || len(fntype.Results.List[0].Names) > 1) {
fmt.Fprintf(fgcc, "\t%s r;\n", gccResult)
}
@@ -991,28 +992,82 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) {
fmt.Fprintf(fgcc, "}\n")
// Build the wrapper function compiled by cmd/compile.
// This unpacks the argument struct above and calls the Go function.
goname := "_cgoexpwrap" + cPrefix + "_"
if fn.Recv != nil {
goname += fn.Recv.List[0].Names[0].Name + "_"
}
goname += exp.Func.Name.Name
fmt.Fprintf(fgo2, "//go:cgo_export_dynamic %s\n", exp.ExpName)
fmt.Fprintf(fgo2, "//go:linkname _cgoexp%s_%s _cgoexp%s_%s\n", cPrefix, exp.ExpName, cPrefix, exp.ExpName)
fmt.Fprintf(fgo2, "//go:cgo_export_static _cgoexp%s_%s\n", cPrefix, exp.ExpName)
fmt.Fprintf(fgo2, "func _cgoexp%s_%s(a *%s) {\n", cPrefix, exp.ExpName, gotype)
fmt.Fprintf(fgo2, "//go:nosplit\n") // no split stack, so no use of m or g
fmt.Fprintf(fgo2, "//go:norace\n") // must not have race detector calls inserted
fmt.Fprintf(fgo2, "func _cgoexp%s_%s(a unsafe.Pointer, n int32, ctxt uintptr) {\n", cPrefix, exp.ExpName)
fmt.Fprintf(fgo2, "\tfn := %s\n", goname)
// The indirect here is converting from a Go function pointer to a C function pointer.
fmt.Fprintf(fgo2, "\t_cgo_runtime_cgocallback(**(**unsafe.Pointer)(unsafe.Pointer(&fn)), a, uintptr(n), ctxt);\n")
fmt.Fprintf(fgo2, "}\n")
fmt.Fprintf(fm, "int _cgoexp%s_%s;\n", cPrefix, exp.ExpName)
// This code uses printer.Fprint, not conf.Fprint,
// because we don't want //line comments in the middle
// of the function types.
fmt.Fprintf(fgo2, "\n")
fmt.Fprintf(fgo2, "func %s(", goname)
comma := false
if fn.Recv != nil {
fmt.Fprintf(fgo2, "recv ")
printer.Fprint(fgo2, fset, fn.Recv.List[0].Type)
comma = true
}
forFieldList(fntype.Params,
func(i int, aname string, atype ast.Expr) {
if comma {
fmt.Fprintf(fgo2, ", ")
}
fmt.Fprintf(fgo2, "p%d ", i)
printer.Fprint(fgo2, fset, atype)
comma = true
})
fmt.Fprintf(fgo2, ")")
if gccResult != "void" {
// Write results back to frame.
fmt.Fprintf(fgo2, "\t")
fmt.Fprint(fgo2, " (")
forFieldList(fntype.Results,
func(i int, aname string, atype ast.Expr) {
if i > 0 {
fmt.Fprintf(fgo2, ", ")
fmt.Fprint(fgo2, ", ")
}
fmt.Fprintf(fgo2, "a.r%d", i)
fmt.Fprintf(fgo2, "r%d ", i)
printer.Fprint(fgo2, fset, atype)
})
fmt.Fprintf(fgo2, " = ")
fmt.Fprint(fgo2, ")")
}
fmt.Fprint(fgo2, " {\n")
if gccResult == "void" {
fmt.Fprint(fgo2, "\t")
} else {
// Verify that any results don't contain any
// Go pointers.
addedDefer := false
forFieldList(fntype.Results,
func(i int, aname string, atype ast.Expr) {
if !p.hasPointer(nil, atype, false) {
return
}
if !addedDefer {
fmt.Fprint(fgo2, "\tdefer func() {\n")
addedDefer = true
}
fmt.Fprintf(fgo2, "\t\t_cgoCheckResult(r%d)\n", i)
})
if addedDefer {
fmt.Fprint(fgo2, "\t}()\n")
}
fmt.Fprint(fgo2, "\treturn ")
}
if fn.Recv != nil {
fmt.Fprintf(fgo2, "a.recv.")
fmt.Fprintf(fgo2, "recv.")
}
fmt.Fprintf(fgo2, "%s(", exp.Func.Name)
forFieldList(fntype.Params,
@@ -1020,20 +1075,9 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) {
if i > 0 {
fmt.Fprint(fgo2, ", ")
}
fmt.Fprintf(fgo2, "a.p%d", i)
fmt.Fprintf(fgo2, "p%d", i)
})
fmt.Fprint(fgo2, ")\n")
if gccResult != "void" {
// Verify that any results don't contain any
// Go pointers.
forFieldList(fntype.Results,
func(i int, aname string, atype ast.Expr) {
if !p.hasPointer(nil, atype, false) {
return
}
fmt.Fprintf(fgo2, "\t_cgoCheckResult(a.r%d)\n", i)
})
}
fmt.Fprint(fgo2, "}\n")
}
@@ -1235,24 +1279,112 @@ func (p *Package) writeExportHeader(fgcch io.Writer) {
fmt.Fprintf(fgcch, "%s\n", p.gccExportHeaderProlog())
}
// gccgoUsesNewMangling reports whether gccgo uses the new collision-free
// packagepath mangling scheme (see determineGccgoManglingScheme for more
// info).
func gccgoUsesNewMangling() bool {
if !gccgoMangleCheckDone {
gccgoNewmanglingInEffect = determineGccgoManglingScheme()
gccgoMangleCheckDone = true
}
return gccgoNewmanglingInEffect
}
const mangleCheckCode = `
package läufer
func Run(x int) int {
return 1
}
`
// determineGccgoManglingScheme performs a runtime test to see which
// flavor of packagepath mangling gccgo is using. Older versions of
// gccgo use a simple mangling scheme where there can be collisions
// between packages whose paths are different but mangle to the same
// string. More recent versions of gccgo use a new mangler that avoids
// these collisions. Return value is whether gccgo uses the new mangling.
func determineGccgoManglingScheme() bool {
// Emit a small Go file for gccgo to compile.
filepat := "*_gccgo_manglecheck.go"
var f *os.File
var err error
if f, err = ioutil.TempFile(*objDir, filepat); err != nil {
fatalf("%v", err)
}
gofilename := f.Name()
defer os.Remove(gofilename)
if err = ioutil.WriteFile(gofilename, []byte(mangleCheckCode), 0666); err != nil {
fatalf("%v", err)
}
// Compile with gccgo, capturing generated assembly.
gccgocmd := os.Getenv("GCCGO")
if gccgocmd == "" {
gpath, gerr := exec.LookPath("gccgo")
if gerr != nil {
fatalf("unable to locate gccgo: %v", gerr)
}
gccgocmd = gpath
}
cmd := exec.Command(gccgocmd, "-S", "-o", "-", gofilename)
buf, cerr := cmd.CombinedOutput()
if cerr != nil {
fatalf("%s", cerr)
}
// New mangling: expect go.l..u00e4ufer.Run
// Old mangling: expect go.l__ufer.Run
return regexp.MustCompile(`go\.l\.\.u00e4ufer\.Run`).Match(buf)
}
// gccgoPkgpathToSymbolNew converts a package path to a gccgo-style
// package symbol.
func gccgoPkgpathToSymbolNew(ppath string) string {
bsl := []byte{}
changed := false
for _, c := range []byte(ppath) {
switch {
case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z',
'0' <= c && c <= '9', c == '_':
bsl = append(bsl, c)
case c == '.':
bsl = append(bsl, ".x2e"...)
default:
changed = true
encbytes := []byte(fmt.Sprintf("..z%02x", c))
bsl = append(bsl, encbytes...)
}
}
if !changed {
return ppath
}
return string(bsl)
}
// gccgoPkgpathToSymbolOld converts a package path to a gccgo-style
// package symbol using the older mangling scheme.
func gccgoPkgpathToSymbolOld(ppath string) string {
clean := func(r rune) rune {
switch {
case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
'0' <= r && r <= '9':
return r
}
return '_'
}
return strings.Map(clean, ppath)
}
// gccgoPkgpathToSymbol converts a package path to a mangled packagepath
// symbol.
func gccgoPkgpathToSymbol(ppath string) string {
if gccgoMangler == nil {
var err error
cmd := os.Getenv("GCCGO")
if cmd == "" {
cmd, err = exec.LookPath("gccgo")
if err != nil {
fatalf("unable to locate gccgo: %v", err)
}
}
gccgoMangler, err = pkgpath.ToSymbolFunc(cmd, *objDir)
if err != nil {
fatalf("%v", err)
}
if gccgoUsesNewMangling() {
return gccgoPkgpathToSymbolNew(ppath)
} else {
return gccgoPkgpathToSymbolOld(ppath)
}
return gccgoMangler(ppath)
}
// Return the package prefix when using gccgo.
@@ -1531,6 +1663,9 @@ const goProlog = `
//go:linkname _cgo_runtime_cgocall runtime.cgocall
func _cgo_runtime_cgocall(unsafe.Pointer, uintptr) int32
//go:linkname _cgo_runtime_cgocallback runtime.cgocallback
func _cgo_runtime_cgocallback(unsafe.Pointer, unsafe.Pointer, uintptr, uintptr)
//go:linkname _cgoCheckPointer runtime.cgoCheckPointer
func _cgoCheckPointer(interface{}, interface{})

View File

@@ -136,7 +136,6 @@ var knownFormats = map[string]string{
"cmd/compile/internal/types.EType %s": "",
"cmd/compile/internal/types.EType %v": "",
"cmd/internal/obj.ABI %v": "",
"cmd/internal/src.XPos %v": "",
"error %v": "",
"float64 %.2f": "",
"float64 %.3f": "",

View File

@@ -1210,7 +1210,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p = s.Prog(x86.ASETEQ)
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg0()
case ssa.OpAMD64ANDBlock, ssa.OpAMD64ANDLlock, ssa.OpAMD64ORBlock, ssa.OpAMD64ORLlock:
case ssa.OpAMD64ANDBlock, ssa.OpAMD64ORBlock:
s.Prog(x86.ALOCK)
p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG

View File

@@ -11,7 +11,7 @@ import (
"cmd/internal/objabi"
)
var darwin = objabi.GOOS == "darwin" || objabi.GOOS == "ios"
var darwin = objabi.GOOS == "darwin"
func padframe(frame int64) int64 {
// arm64 requires that the frame size (not counting saved FP&LR)

View File

@@ -688,23 +688,15 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p5.To.Reg = out
gc.Patch(p2, p5)
case ssa.OpARM64LoweredAtomicAnd8,
ssa.OpARM64LoweredAtomicAnd32,
ssa.OpARM64LoweredAtomicOr8,
ssa.OpARM64LoweredAtomicOr32:
// LDAXRB/LDAXRW (Rarg0), Rout
ssa.OpARM64LoweredAtomicOr8:
// LDAXRB (Rarg0), Rout
// AND/OR Rarg1, Rout
// STLXRB/STLXRB Rout, (Rarg0), Rtmp
// STLXRB Rout, (Rarg0), Rtmp
// CBNZ Rtmp, -3(PC)
ld := arm64.ALDAXRB
st := arm64.ASTLXRB
if v.Op == ssa.OpARM64LoweredAtomicAnd32 || v.Op == ssa.OpARM64LoweredAtomicOr32 {
ld = arm64.ALDAXRW
st = arm64.ASTLXRW
}
r0 := v.Args[0].Reg()
r1 := v.Args[1].Reg()
out := v.Reg0()
p := s.Prog(ld)
p := s.Prog(arm64.ALDAXRB)
p.From.Type = obj.TYPE_MEM
p.From.Reg = r0
p.To.Type = obj.TYPE_REG
@@ -714,7 +706,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p1.From.Reg = r1
p1.To.Type = obj.TYPE_REG
p1.To.Reg = out
p2 := s.Prog(st)
p2 := s.Prog(arm64.ASTLXRB)
p2.From.Type = obj.TYPE_REG
p2.From.Reg = out
p2.To.Type = obj.TYPE_MEM

View File

@@ -282,7 +282,7 @@ func genhash(t *types.Type) *obj.LSym {
}
sym := typesymprefix(".hash", t)
if Debug.r != 0 {
if Debug['r'] != 0 {
fmt.Printf("genhash %v %v %v\n", closure, sym, t)
}
@@ -374,7 +374,7 @@ func genhash(t *types.Type) *obj.LSym {
r.List.Append(nh)
fn.Nbody.Append(r)
if Debug.r != 0 {
if Debug['r'] != 0 {
dumplist("genhash body", fn.Nbody)
}
@@ -392,7 +392,7 @@ func genhash(t *types.Type) *obj.LSym {
}
fn.Func.SetNilCheckDisabled(true)
xtop = append(xtop, fn)
funccompile(fn)
// Build closure. It doesn't close over any variables, so
// it contains just the function pointer.
@@ -509,7 +509,7 @@ func geneq(t *types.Type) *obj.LSym {
return closure
}
sym := typesymprefix(".eq", t)
if Debug.r != 0 {
if Debug['r'] != 0 {
fmt.Printf("geneq %v\n", t)
}
@@ -529,10 +529,6 @@ func geneq(t *types.Type) *obj.LSym {
fn := dclfunc(sym, tfn)
np := asNode(tfn.Type.Params().Field(0).Nname)
nq := asNode(tfn.Type.Params().Field(1).Nname)
nr := asNode(tfn.Type.Results().Field(0).Nname)
// Label to jump to if an equality test fails.
neq := autolabel(".neq")
// We reach here only for types that have equality but
// cannot be handled by the standard algorithms,
@@ -559,13 +555,13 @@ func geneq(t *types.Type) *obj.LSym {
// for i := 0; i < nelem; i++ {
// if eq(p[i], q[i]) {
// } else {
// goto neq
// return
// }
// }
//
// TODO(josharian): consider doing some loop unrolling
// for larger nelem as well, processing a few elements at a time in a loop.
checkAll := func(unroll int64, last bool, eq func(pi, qi *Node) *Node) {
checkAll := func(unroll int64, eq func(pi, qi *Node) *Node) {
// checkIdx generates a node to check for equality at index i.
checkIdx := func(i *Node) *Node {
// pi := p[i]
@@ -580,38 +576,37 @@ func geneq(t *types.Type) *obj.LSym {
}
if nelem <= unroll {
if last {
// Do last comparison in a different manner.
nelem--
}
// Generate a series of checks.
var cond *Node
for i := int64(0); i < nelem; i++ {
// if check {} else { goto neq }
nif := nod(OIF, checkIdx(nodintconst(i)), nil)
nif.Rlist.Append(nodSym(OGOTO, nil, neq))
fn.Nbody.Append(nif)
}
if last {
fn.Nbody.Append(nod(OAS, nr, checkIdx(nodintconst(nelem))))
}
} else {
// Generate a for loop.
// for i := 0; i < nelem; i++
i := temp(types.Types[TINT])
init := nod(OAS, i, nodintconst(0))
cond := nod(OLT, i, nodintconst(nelem))
post := nod(OAS, i, nod(OADD, i, nodintconst(1)))
loop := nod(OFOR, cond, post)
loop.Ninit.Append(init)
// if eq(pi, qi) {} else { goto neq }
nif := nod(OIF, checkIdx(i), nil)
nif.Rlist.Append(nodSym(OGOTO, nil, neq))
loop.Nbody.Append(nif)
fn.Nbody.Append(loop)
if last {
fn.Nbody.Append(nod(OAS, nr, nodbool(true)))
c := nodintconst(i)
check := checkIdx(c)
if cond == nil {
cond = check
continue
}
cond = nod(OANDAND, cond, check)
}
nif := nod(OIF, cond, nil)
nif.Rlist.Append(nod(ORETURN, nil, nil))
fn.Nbody.Append(nif)
return
}
// Generate a for loop.
// for i := 0; i < nelem; i++
i := temp(types.Types[TINT])
init := nod(OAS, i, nodintconst(0))
cond := nod(OLT, i, nodintconst(nelem))
post := nod(OAS, i, nod(OADD, i, nodintconst(1)))
loop := nod(OFOR, cond, post)
loop.Ninit.Append(init)
// if eq(pi, qi) {} else { return }
check := checkIdx(i)
nif := nod(OIF, check, nil)
nif.Rlist.Append(nod(ORETURN, nil, nil))
loop.Nbody.Append(nif)
fn.Nbody.Append(loop)
}
switch t.Elem().Etype {
@@ -619,28 +614,32 @@ func geneq(t *types.Type) *obj.LSym {
// Do two loops. First, check that all the lengths match (cheap).
// Second, check that all the contents match (expensive).
// TODO: when the array size is small, unroll the length match checks.
checkAll(3, false, func(pi, qi *Node) *Node {
checkAll(3, func(pi, qi *Node) *Node {
// Compare lengths.
eqlen, _ := eqstring(pi, qi)
return eqlen
})
checkAll(1, true, func(pi, qi *Node) *Node {
checkAll(1, func(pi, qi *Node) *Node {
// Compare contents.
_, eqmem := eqstring(pi, qi)
return eqmem
})
case TFLOAT32, TFLOAT64:
checkAll(2, true, func(pi, qi *Node) *Node {
checkAll(2, func(pi, qi *Node) *Node {
// p[i] == q[i]
return nod(OEQ, pi, qi)
})
// TODO: pick apart structs, do them piecemeal too
default:
checkAll(1, true, func(pi, qi *Node) *Node {
checkAll(1, func(pi, qi *Node) *Node {
// p[i] == q[i]
return nod(OEQ, pi, qi)
})
}
// return true
ret := nod(ORETURN, nil, nil)
ret.List.Append(nodbool(true))
fn.Nbody.Append(ret)
case TSTRUCT:
// Build a list of conditions to satisfy.
@@ -718,42 +717,22 @@ func geneq(t *types.Type) *obj.LSym {
flatConds = append(flatConds, c...)
}
var cond *Node
if len(flatConds) == 0 {
fn.Nbody.Append(nod(OAS, nr, nodbool(true)))
cond = nodbool(true)
} else {
for _, c := range flatConds[:len(flatConds)-1] {
// if cond {} else { goto neq }
n := nod(OIF, c, nil)
n.Rlist.Append(nodSym(OGOTO, nil, neq))
fn.Nbody.Append(n)
cond = flatConds[0]
for _, c := range flatConds[1:] {
cond = nod(OANDAND, cond, c)
}
fn.Nbody.Append(nod(OAS, nr, flatConds[len(flatConds)-1]))
}
ret := nod(ORETURN, nil, nil)
ret.List.Append(cond)
fn.Nbody.Append(ret)
}
// ret:
// return
ret := autolabel(".ret")
fn.Nbody.Append(nodSym(OLABEL, nil, ret))
fn.Nbody.Append(nod(ORETURN, nil, nil))
// neq:
// r = false
// return (or goto ret)
fn.Nbody.Append(nodSym(OLABEL, nil, neq))
fn.Nbody.Append(nod(OAS, nr, nodbool(false)))
if EqCanPanic(t) || hasCall(fn) {
// Epilogue is large, so share it with the equal case.
fn.Nbody.Append(nodSym(OGOTO, nil, ret))
} else {
// Epilogue is small, so don't bother sharing.
fn.Nbody.Append(nod(ORETURN, nil, nil))
}
// TODO(khr): the epilogue size detection condition above isn't perfect.
// We should really do a generic CL that shares epilogues across
// the board. See #24936.
if Debug.r != 0 {
if Debug['r'] != 0 {
dumplist("geneq body", fn.Nbody)
}
@@ -775,7 +754,7 @@ func geneq(t *types.Type) *obj.LSym {
// neither of which can be nil, and our comparisons
// are shallow.
fn.Func.SetNilCheckDisabled(true)
xtop = append(xtop, fn)
funccompile(fn)
// Generate a closure which points at the function we just generated.
dsymptr(closure, 0, sym.Linksym(), 0)
@@ -783,39 +762,6 @@ func geneq(t *types.Type) *obj.LSym {
return closure
}
func hasCall(n *Node) bool {
if n.Op == OCALL || n.Op == OCALLFUNC {
return true
}
if n.Left != nil && hasCall(n.Left) {
return true
}
if n.Right != nil && hasCall(n.Right) {
return true
}
for _, x := range n.Ninit.Slice() {
if hasCall(x) {
return true
}
}
for _, x := range n.Nbody.Slice() {
if hasCall(x) {
return true
}
}
for _, x := range n.List.Slice() {
if hasCall(x) {
return true
}
}
for _, x := range n.Rlist.Slice() {
if hasCall(x) {
return true
}
}
return false
}
// eqfield returns the node
// p.field == q.field
func eqfield(p *Node, q *Node, field *types.Sym) *Node {

View File

@@ -5,9 +5,7 @@
package gc
import (
"bytes"
"cmd/compile/internal/types"
"fmt"
"sort"
)
@@ -86,7 +84,7 @@ func expandiface(t *types.Type) {
sort.Sort(methcmp(methods))
if int64(len(methods)) >= thearch.MAXWIDTH/int64(Widthptr) {
yyerrorl(typePos(t), "interface too large")
yyerror("interface too large")
}
for i, m := range methods {
m.Offset = int64(i) * int64(Widthptr)
@@ -150,7 +148,7 @@ func widstruct(errtype *types.Type, t *types.Type, o int64, flag int) int64 {
maxwidth = 1<<31 - 1
}
if o >= maxwidth {
yyerrorl(typePos(errtype), "type %L too large", errtype)
yyerror("type %L too large", errtype)
o = 8 // small but nonzero
}
}
@@ -175,91 +173,6 @@ func widstruct(errtype *types.Type, t *types.Type, o int64, flag int) int64 {
return o
}
// findTypeLoop searches for an invalid type declaration loop involving
// type t and reports whether one is found. If so, path contains the
// loop.
//
// path points to a slice used for tracking the sequence of types
// visited. Using a pointer to a slice allows the slice capacity to
// grow and limit reallocations.
func findTypeLoop(t *types.Type, path *[]*types.Type) bool {
// We implement a simple DFS loop-finding algorithm. This
// could be faster, but type cycles are rare.
if t.Sym != nil {
// Declared type. Check for loops and otherwise
// recurse on the type expression used in the type
// declaration.
for i, x := range *path {
if x == t {
*path = (*path)[i:]
return true
}
}
*path = append(*path, t)
if p := asNode(t.Nod).Name.Param; p != nil && findTypeLoop(p.Ntype.Type, path) {
return true
}
*path = (*path)[:len(*path)-1]
} else {
// Anonymous type. Recurse on contained types.
switch t.Etype {
case TARRAY:
if findTypeLoop(t.Elem(), path) {
return true
}
case TSTRUCT:
for _, f := range t.Fields().Slice() {
if findTypeLoop(f.Type, path) {
return true
}
}
case TINTER:
for _, m := range t.Methods().Slice() {
if m.Type.IsInterface() { // embedded interface
if findTypeLoop(m.Type, path) {
return true
}
}
}
}
}
return false
}
func reportTypeLoop(t *types.Type) {
if t.Broke() {
return
}
var l []*types.Type
if !findTypeLoop(t, &l) {
Fatalf("failed to find type loop for: %v", t)
}
// Rotate loop so that the earliest type declaration is first.
i := 0
for j, t := range l[1:] {
if typePos(t).Before(typePos(l[i])) {
i = j + 1
}
}
l = append(l[i:], l[:i]...)
var msg bytes.Buffer
fmt.Fprintf(&msg, "invalid recursive type %v\n", l[0])
for _, t := range l {
fmt.Fprintf(&msg, "\t%v: %v refers to\n", linestr(typePos(t)), t)
t.SetBroke(true)
}
fmt.Fprintf(&msg, "\t%v: %v", linestr(typePos(l[0])), l[0])
yyerrorl(typePos(l[0]), msg.String())
}
// dowidth calculates and stores the size and alignment for t.
// If sizeCalculationDisabled is set, and the size/alignment
// have not already been calculated, it calls Fatal.
@@ -279,7 +192,11 @@ func dowidth(t *types.Type) {
}
if t.Width == -2 {
reportTypeLoop(t)
if !t.Broke() {
t.SetBroke(true)
yyerrorl(asNode(t.Nod).Pos, "invalid recursive type %v", t)
}
t.Width = 0
t.Align = 1
return
@@ -381,7 +298,7 @@ func dowidth(t *types.Type) {
t1 := t.ChanArgs()
dowidth(t1) // just in case
if t1.Elem().Width >= 1<<16 {
yyerrorl(typePos(t1), "channel element type too large (>64kB)")
yyerror("channel element type too large (>64kB)")
}
w = 1 // anything will do
@@ -391,7 +308,10 @@ func dowidth(t *types.Type) {
checkwidth(t.Key())
case TFORW: // should have been filled in
reportTypeLoop(t)
if !t.Broke() {
t.SetBroke(true)
yyerror("invalid recursive type %v", t)
}
w = 1 // anything will do
case TANY:
@@ -414,7 +334,7 @@ func dowidth(t *types.Type) {
if t.Elem().Width != 0 {
cap := (uint64(thearch.MAXWIDTH) - 1) / uint64(t.Elem().Width)
if uint64(t.NumElem()) > cap {
yyerrorl(typePos(t), "type %L larger than address space", t)
yyerror("type %L larger than address space", t)
}
}
w = t.NumElem() * t.Elem().Width
@@ -456,7 +376,7 @@ func dowidth(t *types.Type) {
}
if Widthptr == 4 && w != int64(int32(w)) {
yyerrorl(typePos(t), "type %v too large", t)
yyerror("type %v too large", t)
}
t.Width = w

View File

@@ -7,7 +7,6 @@ package gc
import "testing"
var globl int64
var globl32 int32
func BenchmarkLoadAdd(b *testing.B) {
x := make([]int64, 1024)
@@ -21,18 +20,6 @@ func BenchmarkLoadAdd(b *testing.B) {
}
}
// Added for ppc64 extswsli on power9
func BenchmarkExtShift(b *testing.B) {
x := make([]int32, 1024)
for i := 0; i < b.N; i++ {
var s int64
for i := range x {
s ^= int64(x[i]+32) * 8
}
globl = s
}
}
func BenchmarkModify(b *testing.B) {
a := make([]int64, 1024)
v := globl
@@ -43,17 +30,6 @@ func BenchmarkModify(b *testing.B) {
}
}
func BenchmarkMullImm(b *testing.B) {
x := make([]int32, 1024)
for i := 0; i < b.N; i++ {
var s int32
for i := range x {
s += x[i] * 100
}
globl32 = s
}
}
func BenchmarkConstModify(b *testing.B) {
a := make([]int64, 1024)
for i := 0; i < b.N; i++ {

View File

@@ -81,6 +81,11 @@ func (p *exporter) markType(t *types.Type) {
}
}
// deltaNewFile is a magic line delta offset indicating a new file.
// We use -64 because it is rare; see issue 20080 and CL 41619.
// -64 is the smallest int that fits in a single byte as a varint.
const deltaNewFile = -64
// ----------------------------------------------------------------------------
// Export format
@@ -121,6 +126,30 @@ const (
aliasTag
)
// untype returns the "pseudo" untyped type for a Ctype (import/export use only).
// (we can't use a pre-initialized array because we must be sure all types are
// set up)
func untype(ctype Ctype) *types.Type {
switch ctype {
case CTINT:
return types.Idealint
case CTRUNE:
return types.Idealrune
case CTFLT:
return types.Idealfloat
case CTCPLX:
return types.Idealcomplex
case CTSTR:
return types.Idealstring
case CTBOOL:
return types.Idealbool
case CTNIL:
return types.Types[TNIL]
}
Fatalf("exporter: unknown Ctype")
return nil
}
var predecl []*types.Type // initialized lazily
func predeclared() []*types.Type {
@@ -155,13 +184,13 @@ func predeclared() []*types.Type {
types.Errortype,
// untyped types
types.UntypedBool,
types.UntypedInt,
types.UntypedRune,
types.UntypedFloat,
types.UntypedComplex,
types.UntypedString,
types.Types[TNIL],
untype(CTBOOL),
untype(CTINT),
untype(CTRUNE),
untype(CTFLT),
untype(CTCPLX),
untype(CTSTR),
untype(CTNIL),
// package unsafe
types.Types[TUNSAFEPTR],

View File

@@ -44,7 +44,6 @@ var runtimeDecls = [...]struct {
{"printcomplex", funcTag, 27},
{"printstring", funcTag, 29},
{"printpointer", funcTag, 30},
{"printuintptr", funcTag, 31},
{"printiface", funcTag, 30},
{"printeface", funcTag, 30},
{"printslice", funcTag, 30},
@@ -52,19 +51,20 @@ var runtimeDecls = [...]struct {
{"printsp", funcTag, 9},
{"printlock", funcTag, 9},
{"printunlock", funcTag, 9},
{"concatstring2", funcTag, 34},
{"concatstring3", funcTag, 35},
{"concatstring4", funcTag, 36},
{"concatstring5", funcTag, 37},
{"concatstrings", funcTag, 39},
{"cmpstring", funcTag, 40},
{"intstring", funcTag, 43},
{"slicebytetostring", funcTag, 44},
{"slicebytetostringtmp", funcTag, 45},
{"slicerunetostring", funcTag, 48},
{"stringtoslicebyte", funcTag, 50},
{"stringtoslicerune", funcTag, 53},
{"slicecopy", funcTag, 54},
{"concatstring2", funcTag, 33},
{"concatstring3", funcTag, 34},
{"concatstring4", funcTag, 35},
{"concatstring5", funcTag, 36},
{"concatstrings", funcTag, 38},
{"cmpstring", funcTag, 39},
{"intstring", funcTag, 42},
{"slicebytetostring", funcTag, 43},
{"slicebytetostringtmp", funcTag, 44},
{"slicerunetostring", funcTag, 47},
{"stringtoslicebyte", funcTag, 49},
{"stringtoslicerune", funcTag, 52},
{"slicecopy", funcTag, 53},
{"slicestringcopy", funcTag, 54},
{"decoderune", funcTag, 55},
{"countrunes", funcTag, 56},
{"convI2I", funcTag, 57},
@@ -175,25 +175,25 @@ var runtimeDecls = [...]struct {
{"uint64tofloat64", funcTag, 118},
{"uint32tofloat64", funcTag, 119},
{"complex128div", funcTag, 120},
{"racefuncenter", funcTag, 31},
{"racefuncenter", funcTag, 121},
{"racefuncenterfp", funcTag, 9},
{"racefuncexit", funcTag, 9},
{"raceread", funcTag, 31},
{"racewrite", funcTag, 31},
{"racereadrange", funcTag, 121},
{"racewriterange", funcTag, 121},
{"msanread", funcTag, 121},
{"msanwrite", funcTag, 121},
{"checkptrAlignment", funcTag, 122},
{"checkptrArithmetic", funcTag, 124},
{"libfuzzerTraceCmp1", funcTag, 126},
{"libfuzzerTraceCmp2", funcTag, 128},
{"libfuzzerTraceCmp4", funcTag, 129},
{"libfuzzerTraceCmp8", funcTag, 130},
{"libfuzzerTraceConstCmp1", funcTag, 126},
{"libfuzzerTraceConstCmp2", funcTag, 128},
{"libfuzzerTraceConstCmp4", funcTag, 129},
{"libfuzzerTraceConstCmp8", funcTag, 130},
{"raceread", funcTag, 121},
{"racewrite", funcTag, 121},
{"racereadrange", funcTag, 122},
{"racewriterange", funcTag, 122},
{"msanread", funcTag, 122},
{"msanwrite", funcTag, 122},
{"checkptrAlignment", funcTag, 123},
{"checkptrArithmetic", funcTag, 125},
{"libfuzzerTraceCmp1", funcTag, 127},
{"libfuzzerTraceCmp2", funcTag, 129},
{"libfuzzerTraceCmp4", funcTag, 130},
{"libfuzzerTraceCmp8", funcTag, 131},
{"libfuzzerTraceConstCmp1", funcTag, 127},
{"libfuzzerTraceConstCmp2", funcTag, 129},
{"libfuzzerTraceConstCmp4", funcTag, 130},
{"libfuzzerTraceConstCmp8", funcTag, 131},
{"x86HasPOPCNT", varTag, 6},
{"x86HasSSE41", varTag, 6},
{"x86HasFMA", varTag, 6},
@@ -202,7 +202,7 @@ var runtimeDecls = [...]struct {
}
func runtimeTypes() []*types.Type {
var typs [131]*types.Type
var typs [132]*types.Type
typs[0] = types.Bytetype
typs[1] = types.NewPtr(typs[0])
typs[2] = types.Types[TANY]
@@ -234,31 +234,31 @@ func runtimeTypes() []*types.Type {
typs[28] = types.Types[TSTRING]
typs[29] = functype(nil, []*Node{anonfield(typs[28])}, nil)
typs[30] = functype(nil, []*Node{anonfield(typs[2])}, nil)
typs[31] = functype(nil, []*Node{anonfield(typs[5])}, nil)
typs[32] = types.NewArray(typs[0], 32)
typs[33] = types.NewPtr(typs[32])
typs[34] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
typs[35] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
typs[36] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
typs[37] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
typs[38] = types.NewSlice(typs[28])
typs[39] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[38])}, []*Node{anonfield(typs[28])})
typs[40] = functype(nil, []*Node{anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[15])})
typs[41] = types.NewArray(typs[0], 4)
typs[42] = types.NewPtr(typs[41])
typs[43] = functype(nil, []*Node{anonfield(typs[42]), anonfield(typs[22])}, []*Node{anonfield(typs[28])})
typs[44] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[28])})
typs[45] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[28])})
typs[46] = types.Runetype
typs[47] = types.NewSlice(typs[46])
typs[48] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[47])}, []*Node{anonfield(typs[28])})
typs[49] = types.NewSlice(typs[0])
typs[50] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28])}, []*Node{anonfield(typs[49])})
typs[51] = types.NewArray(typs[46], 32)
typs[52] = types.NewPtr(typs[51])
typs[53] = functype(nil, []*Node{anonfield(typs[52]), anonfield(typs[28])}, []*Node{anonfield(typs[47])})
typs[54] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[5])}, []*Node{anonfield(typs[15])})
typs[55] = functype(nil, []*Node{anonfield(typs[28]), anonfield(typs[15])}, []*Node{anonfield(typs[46]), anonfield(typs[15])})
typs[31] = types.NewArray(typs[0], 32)
typs[32] = types.NewPtr(typs[31])
typs[33] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
typs[34] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
typs[35] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
typs[36] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
typs[37] = types.NewSlice(typs[28])
typs[38] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[37])}, []*Node{anonfield(typs[28])})
typs[39] = functype(nil, []*Node{anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[15])})
typs[40] = types.NewArray(typs[0], 4)
typs[41] = types.NewPtr(typs[40])
typs[42] = functype(nil, []*Node{anonfield(typs[41]), anonfield(typs[22])}, []*Node{anonfield(typs[28])})
typs[43] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[28])})
typs[44] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[28])})
typs[45] = types.Runetype
typs[46] = types.NewSlice(typs[45])
typs[47] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[46])}, []*Node{anonfield(typs[28])})
typs[48] = types.NewSlice(typs[0])
typs[49] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[28])}, []*Node{anonfield(typs[48])})
typs[50] = types.NewArray(typs[45], 32)
typs[51] = types.NewPtr(typs[50])
typs[52] = functype(nil, []*Node{anonfield(typs[51]), anonfield(typs[28])}, []*Node{anonfield(typs[46])})
typs[53] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[5])}, []*Node{anonfield(typs[15])})
typs[54] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[28])}, []*Node{anonfield(typs[15])})
typs[55] = functype(nil, []*Node{anonfield(typs[28]), anonfield(typs[15])}, []*Node{anonfield(typs[45]), anonfield(typs[15])})
typs[56] = functype(nil, []*Node{anonfield(typs[28])}, []*Node{anonfield(typs[15])})
typs[57] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])})
typs[58] = functype(nil, []*Node{anonfield(typs[2])}, []*Node{anonfield(typs[7])})
@@ -324,15 +324,16 @@ func runtimeTypes() []*types.Type {
typs[118] = functype(nil, []*Node{anonfield(typs[24])}, []*Node{anonfield(typs[20])})
typs[119] = functype(nil, []*Node{anonfield(typs[65])}, []*Node{anonfield(typs[20])})
typs[120] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[26])}, []*Node{anonfield(typs[26])})
typs[121] = functype(nil, []*Node{anonfield(typs[5]), anonfield(typs[5])}, nil)
typs[122] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil)
typs[123] = types.NewSlice(typs[7])
typs[124] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[123])}, nil)
typs[125] = types.Types[TUINT8]
typs[126] = functype(nil, []*Node{anonfield(typs[125]), anonfield(typs[125])}, nil)
typs[127] = types.Types[TUINT16]
typs[128] = functype(nil, []*Node{anonfield(typs[127]), anonfield(typs[127])}, nil)
typs[129] = functype(nil, []*Node{anonfield(typs[65]), anonfield(typs[65])}, nil)
typs[130] = functype(nil, []*Node{anonfield(typs[24]), anonfield(typs[24])}, nil)
typs[121] = functype(nil, []*Node{anonfield(typs[5])}, nil)
typs[122] = functype(nil, []*Node{anonfield(typs[5]), anonfield(typs[5])}, nil)
typs[123] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil)
typs[124] = types.NewSlice(typs[7])
typs[125] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[124])}, nil)
typs[126] = types.Types[TUINT8]
typs[127] = functype(nil, []*Node{anonfield(typs[126]), anonfield(typs[126])}, nil)
typs[128] = types.Types[TUINT16]
typs[129] = functype(nil, []*Node{anonfield(typs[128]), anonfield(typs[128])}, nil)
typs[130] = functype(nil, []*Node{anonfield(typs[65]), anonfield(typs[65])}, nil)
typs[131] = functype(nil, []*Node{anonfield(typs[24]), anonfield(typs[24])}, nil)
return typs[:]
}

View File

@@ -54,7 +54,6 @@ func printuint(uint64)
func printcomplex(complex128)
func printstring(string)
func printpointer(any)
func printuintptr(uintptr)
func printiface(any)
func printeface(any)
func printslice(any)
@@ -76,7 +75,8 @@ func slicebytetostringtmp(ptr *byte, n int) string
func slicerunetostring(*[32]byte, []rune) string
func stringtoslicebyte(*[32]byte, string) []byte
func stringtoslicerune(*[32]rune, string) []rune
func slicecopy(toPtr *any, toLen int, fromPtr *any, fromLen int, wid uintptr) int
func slicecopy(toPtr *any, toLen int, frPtr *any, frLen int, wid uintptr) int
func slicestringcopy(toPtr *byte, toLen int, fr string) int
func decoderune(string, int) (retv rune, retk int)
func countrunes(string) int

View File

@@ -198,7 +198,7 @@ func capturevars(xfunc *Node) {
outer = nod(OADDR, outer, nil)
}
if Debug.m > 1 {
if Debug['m'] > 1 {
var name *types.Sym
if v.Name.Curfn != nil && v.Name.Curfn.Func.Nname != nil {
name = v.Name.Curfn.Func.Nname.Sym
@@ -434,8 +434,6 @@ func typecheckpartialcall(fn *Node, sym *types.Sym) {
fn.Type = xfunc.Type
}
// makepartialcall returns a DCLFUNC node representing the wrapper function (*-fm) needed
// for partial calls.
func makepartialcall(fn *Node, t0 *types.Type, meth *types.Sym) *Node {
rcvrtype := fn.Left.Type
sym := methodSymSuffix(rcvrtype, meth, "-fm")
@@ -502,10 +500,6 @@ func makepartialcall(fn *Node, t0 *types.Type, meth *types.Sym) *Node {
funcbody()
xfunc = typecheck(xfunc, ctxStmt)
// Need to typecheck the body of the just-generated wrapper.
// typecheckslice() requires that Curfn is set when processing an ORETURN.
Curfn = xfunc
typecheckslice(xfunc.Nbody.Slice(), ctxStmt)
sym.Def = asTypesNode(xfunc)
xtop = append(xtop, xfunc)
Curfn = savecurfn

View File

@@ -44,7 +44,7 @@ func (v Val) Ctype() Ctype {
Fatalf("unexpected Ctype for %T", v.U)
panic("unreachable")
case nil:
return CTxxx
return 0
case *NilVal:
return CTNIL
case bool:
@@ -114,16 +114,16 @@ func (v Val) Interface() interface{} {
type NilVal struct{}
// Int64Val returns n as an int64.
// Int64 returns n as an int64.
// n must be an integer or rune constant.
func (n *Node) Int64Val() int64 {
func (n *Node) Int64() int64 {
if !Isconst(n, CTINT) {
Fatalf("Int64Val(%v)", n)
Fatalf("Int64(%v)", n)
}
return n.Val().U.(*Mpint).Int64()
}
// CanInt64 reports whether it is safe to call Int64Val() on n.
// CanInt64 reports whether it is safe to call Int64() on n.
func (n *Node) CanInt64() bool {
if !Isconst(n, CTINT) {
return false
@@ -131,27 +131,18 @@ func (n *Node) CanInt64() bool {
// if the value inside n cannot be represented as an int64, the
// return value of Int64 is undefined
return n.Val().U.(*Mpint).CmpInt64(n.Int64Val()) == 0
return n.Val().U.(*Mpint).CmpInt64(n.Int64()) == 0
}
// BoolVal returns n as a bool.
// Bool returns n as a bool.
// n must be a boolean constant.
func (n *Node) BoolVal() bool {
func (n *Node) Bool() bool {
if !Isconst(n, CTBOOL) {
Fatalf("BoolVal(%v)", n)
Fatalf("Bool(%v)", n)
}
return n.Val().U.(bool)
}
// StringVal returns the value of a literal string Node as a string.
// n must be a string constant.
func (n *Node) StringVal() string {
if !Isconst(n, CTSTR) {
Fatalf("StringVal(%v)", n)
}
return n.Val().U.(string)
}
// truncate float literal fv to 32-bit or 64-bit precision
// according to type; return truncated value.
func truncfltlit(oldv *Mpflt, t *types.Type) *Mpflt {
@@ -270,7 +261,7 @@ func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Nod
}
if t == nil || !okforconst[t.Etype] {
t = defaultType(n.Type)
t = defaultType(idealkind(n))
}
switch n.Op {
@@ -621,7 +612,7 @@ func evconst(n *Node) {
var strs []string
i2 := i1
for i2 < len(s) && Isconst(s[i2], CTSTR) {
strs = append(strs, s[i2].StringVal())
strs = append(strs, strlit(s[i2]))
i2++
}
@@ -644,7 +635,7 @@ func evconst(n *Node) {
switch nl.Type.Etype {
case TSTRING:
if Isconst(nl, CTSTR) {
setintconst(n, int64(len(nl.StringVal())))
setintconst(n, int64(len(strlit(nl))))
}
case TARRAY:
if !hascallchan(nl) {
@@ -847,6 +838,10 @@ Outer:
return Val{}
}
u.Quo(y)
case OMOD, OOR, OAND, OANDNOT, OXOR:
// TODO(mdempsky): Move to typecheck; see #31060.
yyerror("invalid operation: operator %v not defined on untyped float", op)
return Val{}
default:
break Outer
}
@@ -872,6 +867,10 @@ Outer:
yyerror("complex division by zero")
return Val{}
}
case OMOD, OOR, OAND, OANDNOT, OXOR:
// TODO(mdempsky): Move to typecheck; see #31060.
yyerror("invalid operation: operator %v not defined on untyped complex", op)
return Val{}
default:
break Outer
}
@@ -933,6 +932,15 @@ func unaryOp(op Op, x Val, t *types.Type) Val {
}
u.Xor(x)
return Val{U: u}
case CTFLT:
// TODO(mdempsky): Move to typecheck; see #31060.
yyerror("invalid operation: operator %v not defined on untyped float", op)
return Val{}
case CTCPLX:
// TODO(mdempsky): Move to typecheck; see #31060.
yyerror("invalid operation: operator %v not defined on untyped complex", op)
return Val{}
}
case ONOT:
@@ -986,8 +994,10 @@ func setconst(n *Node, v Val) {
Xoffset: BADWIDTH,
}
n.SetVal(v)
if vt := idealType(v.Ctype()); n.Type.IsUntyped() && n.Type != vt {
Fatalf("untyped type mismatch, have: %v, want: %v", n.Type, vt)
if n.Type.IsUntyped() {
// TODO(mdempsky): Make typecheck responsible for setting
// the correct untyped type.
n.Type = idealType(v.Ctype())
}
// Check range.
@@ -1028,17 +1038,17 @@ func nodlit(v Val) *Node {
func idealType(ct Ctype) *types.Type {
switch ct {
case CTSTR:
return types.UntypedString
return types.Idealstring
case CTBOOL:
return types.UntypedBool
return types.Idealbool
case CTINT:
return types.UntypedInt
return types.Idealint
case CTRUNE:
return types.UntypedRune
return types.Idealrune
case CTFLT:
return types.UntypedFloat
return types.Idealfloat
case CTCPLX:
return types.UntypedComplex
return types.Idealcomplex
case CTNIL:
return types.Types[TNIL]
}
@@ -1046,6 +1056,67 @@ func idealType(ct Ctype) *types.Type {
return nil
}
// idealkind returns a constant kind like consttype
// but for an arbitrary "ideal" (untyped constant) expression.
func idealkind(n *Node) Ctype {
if n == nil || !n.Type.IsUntyped() {
return CTxxx
}
switch n.Op {
default:
return CTxxx
case OLITERAL:
return n.Val().Ctype()
// numeric kinds.
case OADD,
OAND,
OANDNOT,
OBITNOT,
ODIV,
ONEG,
OMOD,
OMUL,
OSUB,
OXOR,
OOR,
OPLUS:
k1 := idealkind(n.Left)
k2 := idealkind(n.Right)
if k1 > k2 {
return k1
} else {
return k2
}
case OREAL, OIMAG:
return CTFLT
case OCOMPLEX:
return CTCPLX
case OADDSTR:
return CTSTR
case OANDAND,
OEQ,
OGE,
OGT,
OLE,
OLT,
ONE,
ONOT,
OOROR:
return CTBOOL
// shifts (beware!).
case OLSH, ORSH:
return idealkind(n.Left)
}
}
// defaultlit on both nodes simultaneously;
// if they're both ideal going in they better
// get the same type going out.
@@ -1081,63 +1152,41 @@ func defaultlit2(l *Node, r *Node, force bool) (*Node, *Node) {
return l, r
}
t := defaultType(mixUntyped(l.Type, r.Type))
k := idealkind(l)
if rk := idealkind(r); rk > k {
k = rk
}
t := defaultType(k)
l = convlit(l, t)
r = convlit(r, t)
return l, r
}
func ctype(t *types.Type) Ctype {
switch t {
case types.UntypedBool:
return CTBOOL
case types.UntypedString:
return CTSTR
case types.UntypedInt:
return CTINT
case types.UntypedRune:
return CTRUNE
case types.UntypedFloat:
return CTFLT
case types.UntypedComplex:
return CTCPLX
}
Fatalf("bad type %v", t)
panic("unreachable")
}
func mixUntyped(t1, t2 *types.Type) *types.Type {
t := t1
if ctype(t2) > ctype(t1) {
t = t2
}
return t
}
func defaultType(t *types.Type) *types.Type {
if !t.IsUntyped() || t.Etype == TNIL {
return t
}
switch t {
case types.UntypedBool:
func defaultType(k Ctype) *types.Type {
switch k {
case CTBOOL:
return types.Types[TBOOL]
case types.UntypedString:
case CTSTR:
return types.Types[TSTRING]
case types.UntypedInt:
case CTINT:
return types.Types[TINT]
case types.UntypedRune:
case CTRUNE:
return types.Runetype
case types.UntypedFloat:
case CTFLT:
return types.Types[TFLOAT64]
case types.UntypedComplex:
case CTCPLX:
return types.Types[TCOMPLEX128]
}
Fatalf("bad type %v", t)
Fatalf("bad idealkind: %v", k)
return nil
}
// strlit returns the value of a literal string Node as a string.
func strlit(n *Node) string {
return n.Val().U.(string)
}
// TODO(gri) smallintconst is only used in one place - can we used indexconst?
func smallintconst(n *Node) bool {
if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil {
switch simtype[n.Type.Etype] {

View File

@@ -283,7 +283,7 @@ func oldname(s *types.Sym) *Node {
c.Name.Defn = n
// Link into list of active closure variables.
// Popped from list in func funcLit.
// Popped from list in func closurebody.
c.Name.Param.Outer = n.Name.Param.Innermost
n.Name.Param.Innermost = c
@@ -382,11 +382,14 @@ func ifacedcl(n *Node) {
// returns in auto-declaration context.
func funchdr(n *Node) {
// change the declaration context from extern to auto
funcStack = append(funcStack, funcStackEnt{Curfn, dclcontext})
Curfn = n
dclcontext = PAUTO
if Curfn == nil && dclcontext != PEXTERN {
Fatalf("funchdr: dclcontext = %d", dclcontext)
}
dclcontext = PAUTO
types.Markdcl()
funcstack = append(funcstack, Curfn)
Curfn = n
if n.Func.Nname != nil {
funcargs(n.Func.Nname.Name.Param.Ntype)
@@ -494,22 +497,21 @@ func funcarg2(f *types.Field, ctxt Class) {
declare(n, ctxt)
}
var funcStack []funcStackEnt // stack of previous values of Curfn/dclcontext
type funcStackEnt struct {
curfn *Node
dclcontext Class
}
var funcstack []*Node // stack of previous values of Curfn
// finish the body.
// called in auto-declaration context.
// returns in extern-declaration context.
func funcbody() {
// change the declaration context from auto to previous context
// change the declaration context from auto to extern
if dclcontext != PAUTO {
Fatalf("funcbody: unexpected dclcontext %d", dclcontext)
}
types.Popdcl()
var e funcStackEnt
funcStack, e = funcStack[:len(funcStack)-1], funcStack[len(funcStack)-1]
Curfn, dclcontext = e.curfn, e.dclcontext
funcstack, Curfn = funcstack[:len(funcstack)-1], funcstack[len(funcstack)-1]
if Curfn == nil {
dclcontext = PEXTERN
}
}
// structs, functions, and methods.

View File

@@ -34,7 +34,7 @@ func assembleInlines(fnsym *obj.LSym, dwVars []*dwarf.Var) dwarf.InlCalls {
// Walk progs to build up the InlCalls data structure
var prevpos src.XPos
for p := fnsym.Func().Text; p != nil; p = p.Link {
for p := fnsym.Func.Text; p != nil; p = p.Link {
if p.Pos == prevpos {
continue
}
@@ -150,7 +150,7 @@ func assembleInlines(fnsym *obj.LSym, dwVars []*dwarf.Var) dwarf.InlCalls {
start := int64(-1)
curii := -1
var prevp *obj.Prog
for p := fnsym.Func().Text; p != nil; prevp, p = p, p.Link {
for p := fnsym.Func.Text; p != nil; prevp, p = p, p.Link {
if prevp != nil && p.Pos == prevp.Pos {
continue
}

View File

@@ -1,273 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gc
import (
"cmd/compile/internal/syntax"
"cmd/compile/internal/types"
"cmd/internal/obj"
"encoding/json"
"io/ioutil"
"log"
"path"
"sort"
"strconv"
"strings"
)
var embedlist []*Node
var embedCfg struct {
Patterns map[string][]string
Files map[string]string
}
func readEmbedCfg(file string) {
data, err := ioutil.ReadFile(file)
if err != nil {
log.Fatalf("-embedcfg: %v", err)
}
if err := json.Unmarshal(data, &embedCfg); err != nil {
log.Fatalf("%s: %v", file, err)
}
if embedCfg.Patterns == nil {
log.Fatalf("%s: invalid embedcfg: missing Patterns", file)
}
if embedCfg.Files == nil {
log.Fatalf("%s: invalid embedcfg: missing Files", file)
}
}
const (
embedUnknown = iota
embedBytes
embedString
embedFiles
)
var numLocalEmbed int
func varEmbed(p *noder, names []*Node, typ *Node, exprs []*Node, embeds []PragmaEmbed) (newExprs []*Node) {
haveEmbed := false
for _, decl := range p.file.DeclList {
imp, ok := decl.(*syntax.ImportDecl)
if !ok {
// imports always come first
break
}
path, _ := strconv.Unquote(imp.Path.Value)
if path == "embed" {
haveEmbed = true
break
}
}
pos := embeds[0].Pos
if !haveEmbed {
p.yyerrorpos(pos, "invalid go:embed: missing import \"embed\"")
return exprs
}
if embedCfg.Patterns == nil {
p.yyerrorpos(pos, "invalid go:embed: build system did not supply embed configuration")
return exprs
}
if len(names) > 1 {
p.yyerrorpos(pos, "go:embed cannot apply to multiple vars")
return exprs
}
if len(exprs) > 0 {
p.yyerrorpos(pos, "go:embed cannot apply to var with initializer")
return exprs
}
if typ == nil {
// Should not happen, since len(exprs) == 0 now.
p.yyerrorpos(pos, "go:embed cannot apply to var without type")
return exprs
}
kind := embedKindApprox(typ)
if kind == embedUnknown {
p.yyerrorpos(pos, "go:embed cannot apply to var of type %v", typ)
return exprs
}
// Build list of files to store.
have := make(map[string]bool)
var list []string
for _, e := range embeds {
for _, pattern := range e.Patterns {
files, ok := embedCfg.Patterns[pattern]
if !ok {
p.yyerrorpos(e.Pos, "invalid go:embed: build system did not map pattern: %s", pattern)
}
for _, file := range files {
if embedCfg.Files[file] == "" {
p.yyerrorpos(e.Pos, "invalid go:embed: build system did not map file: %s", file)
continue
}
if !have[file] {
have[file] = true
list = append(list, file)
}
if kind == embedFiles {
for dir := path.Dir(file); dir != "." && !have[dir]; dir = path.Dir(dir) {
have[dir] = true
list = append(list, dir+"/")
}
}
}
}
}
sort.Slice(list, func(i, j int) bool {
return embedFileLess(list[i], list[j])
})
if kind == embedString || kind == embedBytes {
if len(list) > 1 {
p.yyerrorpos(pos, "invalid go:embed: multiple files for type %v", typ)
return exprs
}
}
v := names[0]
if dclcontext != PEXTERN {
numLocalEmbed++
v = newnamel(v.Pos, lookupN("embed.", numLocalEmbed))
v.Sym.Def = asTypesNode(v)
v.Name.Param.Ntype = typ
v.SetClass(PEXTERN)
externdcl = append(externdcl, v)
exprs = []*Node{v}
}
v.Name.Param.SetEmbedFiles(list)
embedlist = append(embedlist, v)
return exprs
}
// embedKindApprox determines the kind of embedding variable, approximately.
// The match is approximate because we haven't done scope resolution yet and
// can't tell whether "string" and "byte" really mean "string" and "byte".
// The result must be confirmed later, after type checking, using embedKind.
func embedKindApprox(typ *Node) int {
if typ.Sym != nil && typ.Sym.Name == "FS" && (typ.Sym.Pkg.Path == "embed" || (typ.Sym.Pkg == localpkg && myimportpath == "embed")) {
return embedFiles
}
// These are not guaranteed to match only string and []byte -
// maybe the local package has redefined one of those words.
// But it's the best we can do now during the noder.
// The stricter check happens later, in initEmbed calling embedKind.
if typ.Sym != nil && typ.Sym.Name == "string" && typ.Sym.Pkg == localpkg {
return embedString
}
if typ.Op == OTARRAY && typ.Left == nil && typ.Right.Sym != nil && typ.Right.Sym.Name == "byte" && typ.Right.Sym.Pkg == localpkg {
return embedBytes
}
return embedUnknown
}
// embedKind determines the kind of embedding variable.
func embedKind(typ *types.Type) int {
if typ.Sym != nil && typ.Sym.Name == "FS" && (typ.Sym.Pkg.Path == "embed" || (typ.Sym.Pkg == localpkg && myimportpath == "embed")) {
return embedFiles
}
if typ == types.Types[TSTRING] {
return embedString
}
if typ.Sym == nil && typ.IsSlice() && typ.Elem() == types.Bytetype {
return embedBytes
}
return embedUnknown
}
func embedFileNameSplit(name string) (dir, elem string, isDir bool) {
if name[len(name)-1] == '/' {
isDir = true
name = name[:len(name)-1]
}
i := len(name) - 1
for i >= 0 && name[i] != '/' {
i--
}
if i < 0 {
return ".", name, isDir
}
return name[:i], name[i+1:], isDir
}
// embedFileLess implements the sort order for a list of embedded files.
// See the comment inside ../../../../embed/embed.go's Files struct for rationale.
func embedFileLess(x, y string) bool {
xdir, xelem, _ := embedFileNameSplit(x)
ydir, yelem, _ := embedFileNameSplit(y)
return xdir < ydir || xdir == ydir && xelem < yelem
}
func dumpembeds() {
for _, v := range embedlist {
initEmbed(v)
}
}
// initEmbed emits the init data for a //go:embed variable,
// which is either a string, a []byte, or an embed.FS.
func initEmbed(v *Node) {
files := v.Name.Param.EmbedFiles()
switch kind := embedKind(v.Type); kind {
case embedUnknown:
yyerrorl(v.Pos, "go:embed cannot apply to var of type %v", v.Type)
case embedString, embedBytes:
file := files[0]
fsym, size, err := fileStringSym(v.Pos, embedCfg.Files[file], kind == embedString, nil)
if err != nil {
yyerrorl(v.Pos, "embed %s: %v", file, err)
}
sym := v.Sym.Linksym()
off := 0
off = dsymptr(sym, off, fsym, 0) // data string
off = duintptr(sym, off, uint64(size)) // len
if kind == embedBytes {
duintptr(sym, off, uint64(size)) // cap for slice
}
case embedFiles:
slicedata := Ctxt.Lookup(`"".` + v.Sym.Name + `.files`)
off := 0
// []files pointed at by Files
off = dsymptr(slicedata, off, slicedata, 3*Widthptr) // []file, pointing just past slice
off = duintptr(slicedata, off, uint64(len(files)))
off = duintptr(slicedata, off, uint64(len(files)))
// embed/embed.go type file is:
// name string
// data string
// hash [16]byte
// Emit one of these per file in the set.
const hashSize = 16
hash := make([]byte, hashSize)
for _, file := range files {
off = dsymptr(slicedata, off, stringsym(v.Pos, file), 0) // file string
off = duintptr(slicedata, off, uint64(len(file)))
if strings.HasSuffix(file, "/") {
// entry for directory - no data
off = duintptr(slicedata, off, 0)
off = duintptr(slicedata, off, 0)
off += hashSize
} else {
fsym, size, err := fileStringSym(v.Pos, embedCfg.Files[file], true, hash)
if err != nil {
yyerrorl(v.Pos, "embed %s: %v", file, err)
}
off = dsymptr(slicedata, off, fsym, 0) // data string
off = duintptr(slicedata, off, uint64(size))
off = int(slicedata.WriteBytes(Ctxt, int64(off), hash))
}
}
ggloblsym(slicedata, int32(off), obj.RODATA|obj.LOCAL)
sym := v.Sym.Linksym()
dsymptr(sym, 0, slicedata, 0)
}
}

View File

@@ -169,47 +169,36 @@ func mayAffectMemory(n *Node) bool {
}
}
// heapAllocReason returns the reason the given Node must be heap
// allocated, or the empty string if it doesn't.
func heapAllocReason(n *Node) string {
func mustHeapAlloc(n *Node) bool {
if n.Type == nil {
return ""
return false
}
// Parameters are always passed via the stack.
if n.Op == ONAME && (n.Class() == PPARAM || n.Class() == PPARAMOUT) {
return ""
return false
}
if n.Type.Width > maxStackVarSize {
return "too large for stack"
return true
}
if (n.Op == ONEW || n.Op == OPTRLIT) && n.Type.Elem().Width >= maxImplicitStackVarSize {
return "too large for stack"
return true
}
if n.Op == OCLOSURE && closureType(n).Size() >= maxImplicitStackVarSize {
return "too large for stack"
return true
}
if n.Op == OCALLPART && partialCallType(n).Size() >= maxImplicitStackVarSize {
return "too large for stack"
return true
}
if n.Op == OMAKESLICE {
r := n.Right
if r == nil {
r = n.Left
}
if !smallintconst(r) {
return "non-constant size"
}
if t := n.Type; t.Elem().Width != 0 && r.Int64Val() >= maxImplicitStackVarSize/t.Elem().Width {
return "too large for stack"
}
if n.Op == OMAKESLICE && !isSmallMakeSlice(n) {
return true
}
return ""
return false
}
// addrescapes tags node n as having had its address taken
@@ -282,7 +271,7 @@ func addrescapes(n *Node) {
// moveToHeap records the parameter or local variable n as moved to the heap.
func moveToHeap(n *Node) {
if Debug.r != 0 {
if Debug['r'] != 0 {
Dump("MOVE", n)
}
if compiling_runtime {
@@ -359,7 +348,7 @@ func moveToHeap(n *Node) {
n.Xoffset = 0
n.Name.Param.Heapaddr = heapaddr
n.Esc = EscHeap
if Debug.m != 0 {
if Debug['m'] != 0 {
Warnl(n.Pos, "moved to heap: %v", n)
}
}
@@ -389,7 +378,7 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string {
// but we are reusing the ability to annotate an individual function
// argument and pass those annotations along to importing code.
if f.Type.IsUintptr() {
if Debug.m != 0 {
if Debug['m'] != 0 {
Warnl(f.Pos, "assuming %v is unsafe uintptr", name())
}
return unsafeUintptrTag
@@ -404,11 +393,11 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string {
// External functions are assumed unsafe, unless
// //go:noescape is given before the declaration.
if fn.Func.Pragma&Noescape != 0 {
if Debug.m != 0 && f.Sym != nil {
if Debug['m'] != 0 && f.Sym != nil {
Warnl(f.Pos, "%v does not escape", name())
}
} else {
if Debug.m != 0 && f.Sym != nil {
if Debug['m'] != 0 && f.Sym != nil {
Warnl(f.Pos, "leaking param: %v", name())
}
esc.AddHeap(0)
@@ -419,14 +408,14 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string {
if fn.Func.Pragma&UintptrEscapes != 0 {
if f.Type.IsUintptr() {
if Debug.m != 0 {
if Debug['m'] != 0 {
Warnl(f.Pos, "marking %v as escaping uintptr", name())
}
return uintptrEscapesTag
}
if f.IsDDD() && f.Type.Elem().IsUintptr() {
// final argument is ...uintptr.
if Debug.m != 0 {
if Debug['m'] != 0 {
Warnl(f.Pos, "marking %v as escaping ...uintptr", name())
}
return uintptrEscapesTag
@@ -448,7 +437,7 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string {
esc := loc.paramEsc
esc.Optimize()
if Debug.m != 0 && !loc.escapes {
if Debug['m'] != 0 && !loc.escapes {
if esc.Empty() {
Warnl(f.Pos, "%v does not escape", name())
}

View File

@@ -170,7 +170,7 @@ func (e *Escape) initFunc(fn *Node) {
Fatalf("unexpected node: %v", fn)
}
fn.Esc = EscFuncPlanned
if Debug.m > 3 {
if Debug['m'] > 3 {
Dump("escAnalyze", fn)
}
@@ -247,7 +247,7 @@ func (e *Escape) stmt(n *Node) {
lineno = lno
}()
if Debug.m > 2 {
if Debug['m'] > 2 {
fmt.Printf("%v:[%d] %v stmt: %v\n", linestr(lineno), e.loopDepth, funcSym(e.curfn), n)
}
@@ -275,11 +275,11 @@ func (e *Escape) stmt(n *Node) {
case OLABEL:
switch asNode(n.Sym.Label) {
case &nonlooping:
if Debug.m > 2 {
if Debug['m'] > 2 {
fmt.Printf("%v:%v non-looping label\n", linestr(lineno), n)
}
case &looping:
if Debug.m > 2 {
if Debug['m'] > 2 {
fmt.Printf("%v: %v looping label\n", linestr(lineno), n)
}
e.loopDepth++
@@ -717,7 +717,7 @@ func (e *Escape) addrs(l Nodes) []EscHole {
func (e *Escape) assign(dst, src *Node, why string, where *Node) {
// Filter out some no-op assignments for escape analysis.
ignore := dst != nil && src != nil && isSelfAssign(dst, src)
if ignore && Debug.m != 0 {
if ignore && Debug['m'] != 0 {
Warnl(where.Pos, "%v ignoring self-assignment in %S", funcSym(e.curfn), where)
}
@@ -771,11 +771,10 @@ func (e *Escape) call(ks []EscHole, call, where *Node) {
var fn *Node
switch call.Op {
case OCALLFUNC:
switch v := staticValue(call.Left); {
case v.Op == ONAME && v.Class() == PFUNC:
fn = v
case v.Op == OCLOSURE:
fn = v.Func.Closure.Func.Nname
if call.Left.Op == ONAME && call.Left.Class() == PFUNC {
fn = call.Left
} else if call.Left.Op == OCLOSURE {
fn = call.Left.Func.Closure.Func.Nname
}
case OCALLMETH:
fn = asNode(call.Left.Type.FuncType().Nname)
@@ -931,7 +930,7 @@ func (k EscHole) note(where *Node, why string) EscHole {
if where == nil || why == "" {
Fatalf("note: missing where/why")
}
if Debug.m >= 2 || logopt.Enabled() {
if Debug['m'] >= 2 || logopt.Enabled() {
k.notes = &EscNote{
next: k.notes,
where: where,
@@ -1031,7 +1030,7 @@ func (e *Escape) newLoc(n *Node, transient bool) *EscLocation {
Fatalf("e.curfn isn't set")
}
if n != nil && n.Type != nil && n.Type.NotInHeap() {
yyerrorl(n.Pos, "%v is incomplete (or unallocatable); stack allocation disallowed", n.Type)
yyerrorl(n.Pos, "%v is go:notinheap; stack allocation disallowed", n.Type)
}
n = canonicalNode(n)
@@ -1052,7 +1051,11 @@ func (e *Escape) newLoc(n *Node, transient bool) *EscLocation {
}
n.SetOpt(loc)
if why := heapAllocReason(n); why != "" {
if mustHeapAlloc(n) {
why := "too large for stack"
if n.Op == OMAKESLICE && (!Isconst(n.Left, CTINT) || !Isconst(n.Right, CTINT)) {
why = "non-constant size"
}
e.flow(e.heapHole().addr(n, why), loc)
}
}
@@ -1077,9 +1080,9 @@ func (e *Escape) flow(k EscHole, src *EscLocation) {
return
}
if dst.escapes && k.derefs < 0 { // dst = &src
if Debug.m >= 2 || logopt.Enabled() {
if Debug['m'] >= 2 || logopt.Enabled() {
pos := linestr(src.n.Pos)
if Debug.m >= 2 {
if Debug['m'] >= 2 {
fmt.Printf("%s: %v escapes to heap:\n", pos, src.n)
}
explanation := e.explainFlow(pos, dst, src, k.derefs, k.notes, []*logopt.LoggedOpt{})
@@ -1179,8 +1182,8 @@ func (e *Escape) walkOne(root *EscLocation, walkgen uint32, enqueue func(*EscLoc
// that value flow for tagging the function
// later.
if l.isName(PPARAM) {
if (logopt.Enabled() || Debug.m >= 2) && !l.escapes {
if Debug.m >= 2 {
if (logopt.Enabled() || Debug['m'] >= 2) && !l.escapes {
if Debug['m'] >= 2 {
fmt.Printf("%s: parameter %v leaks to %s with derefs=%d:\n", linestr(l.n.Pos), l.n, e.explainLoc(root), base)
}
explanation := e.explainPath(root, l)
@@ -1196,8 +1199,8 @@ func (e *Escape) walkOne(root *EscLocation, walkgen uint32, enqueue func(*EscLoc
// outlives it, then l needs to be heap
// allocated.
if addressOf && !l.escapes {
if logopt.Enabled() || Debug.m >= 2 {
if Debug.m >= 2 {
if logopt.Enabled() || Debug['m'] >= 2 {
if Debug['m'] >= 2 {
fmt.Printf("%s: %v escapes to heap:\n", linestr(l.n.Pos), l.n)
}
explanation := e.explainPath(root, l)
@@ -1235,7 +1238,7 @@ func (e *Escape) explainPath(root, src *EscLocation) []*logopt.LoggedOpt {
for {
// Prevent infinite loop.
if visited[src] {
if Debug.m >= 2 {
if Debug['m'] >= 2 {
fmt.Printf("%s: warning: truncated explanation due to assignment cycle; see golang.org/issue/35518\n", pos)
}
break
@@ -1263,7 +1266,7 @@ func (e *Escape) explainFlow(pos string, dst, srcloc *EscLocation, derefs int, n
if derefs >= 0 {
ops = strings.Repeat("*", derefs)
}
print := Debug.m >= 2
print := Debug['m'] >= 2
flow := fmt.Sprintf(" flow: %s = %s%v:", e.explainLoc(dst), ops, e.explainLoc(srcloc))
if print {
@@ -1417,7 +1420,7 @@ func (e *Escape) finish(fns []*Node) {
if loc.escapes {
if n.Op != ONAME {
if Debug.m != 0 {
if Debug['m'] != 0 {
Warnl(n.Pos, "%S escapes to heap", n)
}
if logopt.Enabled() {
@@ -1427,7 +1430,7 @@ func (e *Escape) finish(fns []*Node) {
n.Esc = EscHeap
addrescapes(n)
} else {
if Debug.m != 0 && n.Op != ONAME {
if Debug['m'] != 0 && n.Op != ONAME {
Warnl(n.Pos, "%S does not escape", n)
}
n.Esc = EscNone

View File

@@ -31,7 +31,7 @@ func exportsym(n *Node) {
}
n.Sym.SetOnExportList(true)
if Debug.E != 0 {
if Debug['E'] != 0 {
fmt.Printf("export symbol %v\n", n.Sym)
}
@@ -96,7 +96,7 @@ func importsym(ipkg *types.Pkg, s *types.Sym, op Op) *Node {
return n
}
// importtype returns the named type declared by symbol s.
// pkgtype returns the named type declared by symbol s.
// If no such type has been declared yet, a forward declaration is returned.
// ipkg is the package being imported
func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *types.Type {
@@ -150,7 +150,7 @@ func importconst(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type, val
n.SetVal(val)
if Debug.E != 0 {
if Debug['E'] != 0 {
fmt.Printf("import const %v %L = %v\n", s, t, val)
}
}
@@ -166,7 +166,7 @@ func importfunc(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
n.Func = new(Func)
t.SetNname(asTypesNode(n))
if Debug.E != 0 {
if Debug['E'] != 0 {
fmt.Printf("import func %v%S\n", s, t)
}
}
@@ -179,7 +179,7 @@ func importvar(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
return
}
if Debug.E != 0 {
if Debug['E'] != 0 {
fmt.Printf("import var %v %L\n", s, t)
}
}
@@ -192,7 +192,7 @@ func importalias(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
return
}
if Debug.E != 0 {
if Debug['E'] != 0 {
fmt.Printf("import type %v = %L\n", s, t)
}
}

View File

@@ -6,9 +6,17 @@ package gc
import (
"math"
"os"
"runtime"
"testing"
)
// For GO386=387, make sure fucomi* opcodes are not used
// for comparison operations.
// Note that this test will fail only on a Pentium MMX
// processor (with GOARCH=386 GO386=387), as it just runs
// some code and looks for an unimplemented instruction fault.
//go:noinline
func compare1(a, b float64) bool {
return a < b
@@ -129,6 +137,9 @@ func TestFloatCompareFolded(t *testing.T) {
}
}
// For GO386=387, make sure fucomi* opcodes are not used
// for float->int conversions.
//go:noinline
func cvt1(a float64) uint64 {
return uint64(a)
@@ -359,6 +370,14 @@ func TestFloat32StoreToLoadConstantFold(t *testing.T) {
// are not converted to quiet NaN (qNaN) values during compilation.
// See issue #27193 for more information.
// TODO: this method for detecting 387 won't work if the compiler has been
// built using GOARCH=386 GO386=387 and either the target is a different
// architecture or the GO386=387 environment variable is not set when the
// test is run.
if runtime.GOARCH == "386" && os.Getenv("GO386") == "387" {
t.Skip("signaling NaNs are not propagated on 387 (issue #27516)")
}
// signaling NaNs
{
const nan = uint32(0x7f800001) // sNaN

View File

@@ -711,17 +711,6 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited
return
}
if t.Etype == types.TRESULTS {
tys := t.Extra.(*types.Results).Types
for i, et := range tys {
if i > 0 {
b.WriteByte(',')
}
b.WriteString(et.String())
}
return
}
flag, mode = flag.update(mode)
if mode == FTypeIdName {
flag |= FmtUnsigned
@@ -773,17 +762,17 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited
if int(t.Etype) < len(basicnames) && basicnames[t.Etype] != "" {
var name string
switch t {
case types.UntypedBool:
case types.Idealbool:
name = "untyped bool"
case types.UntypedString:
case types.Idealstring:
name = "untyped string"
case types.UntypedInt:
case types.Idealint:
name = "untyped int"
case types.UntypedRune:
case types.Idealrune:
name = "untyped rune"
case types.UntypedFloat:
case types.Idealfloat:
name = "untyped float"
case types.UntypedComplex:
case types.Idealcomplex:
name = "untyped complex"
default:
name = basicnames[t.Etype]
@@ -792,13 +781,6 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited
return
}
if mode == FDbg {
b.WriteString(t.Etype.String())
b.WriteByte('-')
tconv2(b, t, flag, FErr, visited)
return
}
// At this point, we might call tconv2 recursively. Add the current type to the visited list so we don't
// try to print it recursively.
// We record the offset in the result buffer where the type's text starts. This offset serves as a reference
@@ -812,6 +794,12 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited
visited[t] = b.Len()
defer delete(visited, t)
if mode == FDbg {
b.WriteString(t.Etype.String())
b.WriteByte('-')
tconv2(b, t, flag, FErr, visited)
return
}
switch t.Etype {
case TPTR:
b.WriteByte('*')
@@ -1334,7 +1322,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
n.Orig.exprfmt(s, prec, mode)
return
}
if n.Type != nil && !n.Type.IsUntyped() {
if n.Type != nil && n.Type.Etype != TIDEAL && n.Type.Etype != TNIL && n.Type != types.Idealbool && n.Type != types.Idealstring {
// Need parens when type begins with what might
// be misinterpreted as a unary operator: * or <-.
if n.Type.IsPtr() || (n.Type.IsChan() && n.Type.ChanDir() == types.Crecv) {
@@ -1419,7 +1407,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
return
}
if n.Right != nil {
mode.Fprintf(s, "%v{%s}", n.Right, ellipsisIf(n.List.Len() != 0))
mode.Fprintf(s, "%v literal", n.Right)
return
}
@@ -1433,7 +1421,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT:
if mode == FErr {
mode.Fprintf(s, "%v{%s}", n.Type, ellipsisIf(n.List.Len() != 0))
mode.Fprintf(s, "%v literal", n.Type)
return
}
mode.Fprintf(s, "(%v{ %.v })", n.Type, n.List)
@@ -1946,10 +1934,3 @@ func indent(s fmt.State) {
fmt.Fprint(s, ". ")
}
}
func ellipsisIf(b bool) string {
if b {
return "..."
}
return ""
}

View File

@@ -61,12 +61,12 @@ type Class uint8
//go:generate stringer -type=Class
const (
Pxxx Class = iota // no class; used during ssa conversion to indicate pseudo-variables
PEXTERN // global variables
PEXTERN // global variable
PAUTO // local variables
PAUTOHEAP // local variables or parameters moved to heap
PAUTOHEAP // local variable or parameter moved to heap
PPARAM // input arguments
PPARAMOUT // output results
PFUNC // global functions
PFUNC // global function
// Careful: Class is stored in three bits in Node.flags.
_ = uint((1 << 3) - iota) // static assert for iota <= (1 << 3)
@@ -116,15 +116,7 @@ var decldepth int32
var nolocalimports bool
// gc debug flags
type DebugFlags struct {
P, B, C, E,
K, L, N, S,
W, e, h, j,
l, m, r, w int
}
var Debug DebugFlags
var Debug [256]int
var debugstr string
@@ -267,6 +259,7 @@ type Arch struct {
REGSP int
MAXWIDTH int64
Use387 bool // should 386 backend use 387 FP instructions instead of sse2.
SoftFloat bool
PadFrame func(int64) int64
@@ -335,6 +328,10 @@ var (
BoundsCheckFunc [ssa.BoundsKindCount]*obj.LSym
ExtendCheckFunc [ssa.BoundsKindCount]*obj.LSym
// GO386=387
ControlWord64trunc,
ControlWord32 *obj.LSym
// Wasm
WasmMove,
WasmZero,

View File

@@ -153,7 +153,7 @@ func (pp *Progs) Prog(as obj.As) *obj.Prog {
pp.clearp(pp.next)
p.Link = pp.next
if !pp.pos.IsKnown() && Debug.K != 0 {
if !pp.pos.IsKnown() && Debug['K'] != 0 {
Warn("prog: unknown position (line 0)")
}
@@ -199,7 +199,7 @@ func (pp *Progs) settext(fn *Node) {
ptxt := pp.Prog(obj.ATEXT)
pp.Text = ptxt
fn.Func.lsym.Func().Text = ptxt
fn.Func.lsym.Func.Text = ptxt
ptxt.From.Type = obj.TYPE_MEM
ptxt.From.Name = obj.NAME_EXTERN
ptxt.From.Sym = fn.Func.lsym

View File

@@ -751,11 +751,11 @@ func (w *exportWriter) param(f *types.Field) {
func constTypeOf(typ *types.Type) Ctype {
switch typ {
case types.UntypedInt, types.UntypedRune:
case types.Idealint, types.Idealrune:
return CTINT
case types.UntypedFloat:
case types.Idealfloat:
return CTFLT
case types.UntypedComplex:
case types.Idealcomplex:
return CTCPLX
}
@@ -780,8 +780,8 @@ func constTypeOf(typ *types.Type) Ctype {
}
func (w *exportWriter) value(typ *types.Type, v Val) {
if vt := idealType(v.Ctype()); typ.IsUntyped() && typ != vt {
Fatalf("exporter: untyped type mismatch, have: %v, want: %v", typ, vt)
if typ.IsUntyped() {
typ = untype(v.Ctype())
}
w.typ(typ)
@@ -1017,8 +1017,6 @@ func (w *exportWriter) symIdx(s *types.Sym) {
}
func (w *exportWriter) typeExt(t *types.Type) {
// Export whether this type is marked notinheap.
w.bool(t.NotInHeap())
// For type T, export the index of type descriptor symbols of T and *T.
if i, ok := typeSymIdx[t]; ok {
w.int64(i[0])
@@ -1266,13 +1264,8 @@ func (w *exportWriter) expr(n *Node) {
// case OSTRUCTKEY:
// unreachable - handled in case OSTRUCTLIT by elemList
case OCALLPART:
// An OCALLPART is an OXDOT before type checking.
w.op(OXDOT)
w.pos(n.Pos)
w.expr(n.Left)
// Right node should be ONAME
w.selector(n.Right.Sym)
// case OCALLPART:
// unimplemented - handled by default case
case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
w.op(OXDOT)

View File

@@ -375,7 +375,7 @@ func (p *importReader) value() (typ *types.Type, v Val) {
v.U = p.string()
case CTINT:
x := new(Mpint)
x.Rune = typ == types.UntypedRune
x.Rune = typ == types.Idealrune
p.mpint(&x.Val, typ)
v.U = x
case CTFLT:
@@ -596,6 +596,7 @@ func (r *importReader) typ1() *types.Type {
// Ensure we expand the interface in the frontend (#25055).
checkwidth(t)
return t
}
}
@@ -710,7 +711,6 @@ func (r *importReader) symIdx(s *types.Sym) {
}
func (r *importReader) typeExt(t *types.Type) {
t.SetNotInHeap(r.bool())
i, pi := r.int64(), r.int64()
if i != -1 && pi != -1 {
typeSymIdx[t] = [2]int64{i, pi}
@@ -742,8 +742,8 @@ func (r *importReader) doInline(n *Node) {
importlist = append(importlist, n)
if Debug.E > 0 && Debug.m > 2 {
if Debug.m > 3 {
if Debug['E'] > 0 && Debug['m'] > 2 {
if Debug['m'] > 3 {
fmt.Printf("inl body for %v %#v: %+v\n", n, n.Type, asNodes(n.Func.Inl.Body))
} else {
fmt.Printf("inl body for %v %#v: %v\n", n, n.Type, asNodes(n.Func.Inl.Body))
@@ -866,7 +866,7 @@ func (r *importReader) node() *Node {
// unreachable - handled in case OSTRUCTLIT by elemList
// case OCALLPART:
// unreachable - mapped to case OXDOT below by exporter
// unimplemented
// case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
// unreachable - mapped to case OXDOT below by exporter

Some files were not shown because too many files have changed in this diff Show More