Commit 5501a097 authored by Russ Cox's avatar Russ Cox

cmd/cgo: prepare for 64-bit ints

This CL makes the size of an int controlled by a variable
in cgo instead of hard-coding 4 (or 32 bits) in various places.

Update #2188.

R=iant, r, dave
CC=golang-dev
https://golang.org/cl/6548061
parent 0a006b49
...@@ -601,7 +601,7 @@ func (p *Package) loadDWARF(f *File, names []*Name) { ...@@ -601,7 +601,7 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
// Record types and typedef information. // Record types and typedef information.
var conv typeConv var conv typeConv
conv.Init(p.PtrSize) conv.Init(p.PtrSize, p.IntSize)
for i, n := range names { for i, n := range names {
if types[i] == nil { if types[i] == nil {
continue continue
...@@ -928,14 +928,16 @@ type typeConv struct { ...@@ -928,14 +928,16 @@ type typeConv struct {
string ast.Expr string ast.Expr
ptrSize int64 ptrSize int64
intSize int64
} }
var tagGen int var tagGen int
var typedef = make(map[string]*Type) var typedef = make(map[string]*Type)
var goIdent = make(map[string]*ast.Ident) var goIdent = make(map[string]*ast.Ident)
func (c *typeConv) Init(ptrSize int64) { func (c *typeConv) Init(ptrSize, intSize int64) {
c.ptrSize = ptrSize c.ptrSize = ptrSize
c.intSize = intSize
c.m = make(map[dwarf.Type]*Type) c.m = make(map[dwarf.Type]*Type)
c.bool = c.Ident("bool") c.bool = c.Ident("bool")
c.byte = c.Ident("byte") c.byte = c.Ident("byte")
......
...@@ -31,6 +31,7 @@ type Package struct { ...@@ -31,6 +31,7 @@ type Package struct {
PackageName string // name of package PackageName string // name of package
PackagePath string PackagePath string
PtrSize int64 PtrSize int64
IntSize int64
GccOptions []string GccOptions []string
CgoFlags map[string]string // #cgo flags (CFLAGS, LDFLAGS) CgoFlags map[string]string // #cgo flags (CFLAGS, LDFLAGS)
Written map[string]bool Written map[string]bool
...@@ -129,6 +130,12 @@ var ptrSizeMap = map[string]int64{ ...@@ -129,6 +130,12 @@ var ptrSizeMap = map[string]int64{
"arm": 4, "arm": 4,
} }
var intSizeMap = map[string]int64{
"386": 4,
"amd64": 4,
"arm": 4,
}
var cPrefix string var cPrefix string
var fset = token.NewFileSet() var fset = token.NewFileSet()
...@@ -289,7 +296,11 @@ func newPackage(args []string) *Package { ...@@ -289,7 +296,11 @@ func newPackage(args []string) *Package {
} }
ptrSize := ptrSizeMap[goarch] ptrSize := ptrSizeMap[goarch]
if ptrSize == 0 { if ptrSize == 0 {
fatalf("unknown $GOARCH %q", goarch) fatalf("unknown ptrSize for $GOARCH %q", goarch)
}
intSize := intSizeMap[goarch]
if intSize == 0 {
fatalf("unknown intSize for $GOARCH %q", goarch)
} }
// Reset locale variables so gcc emits English errors [sic]. // Reset locale variables so gcc emits English errors [sic].
...@@ -298,6 +309,7 @@ func newPackage(args []string) *Package { ...@@ -298,6 +309,7 @@ func newPackage(args []string) *Package {
p := &Package{ p := &Package{
PtrSize: ptrSize, PtrSize: ptrSize,
IntSize: intSize,
GccOptions: gccOptions, GccOptions: gccOptions,
CgoFlags: make(map[string]string), CgoFlags: make(map[string]string),
Written: make(map[string]bool), Written: make(map[string]bool),
......
...@@ -59,7 +59,7 @@ func (p *Package) writeDefs() { ...@@ -59,7 +59,7 @@ func (p *Package) writeDefs() {
} }
fmt.Fprintf(fgo2, "type _ unsafe.Pointer\n\n") fmt.Fprintf(fgo2, "type _ unsafe.Pointer\n\n")
if *importSyscall { if *importSyscall {
fmt.Fprintf(fgo2, "func _Cerrno(dst *error, x int) { *dst = syscall.Errno(x) }\n") fmt.Fprintf(fgo2, "func _Cerrno(dst *error, x int32) { *dst = syscall.Errno(x) }\n")
} }
typedefNames := make([]string, 0, len(typedef)) typedefNames := make([]string, 0, len(typedef))
...@@ -473,7 +473,7 @@ func (p *Package) writeExports(fgo2, fc, fm *os.File) { ...@@ -473,7 +473,7 @@ func (p *Package) writeExports(fgo2, fc, fm *os.File) {
fmt.Fprintf(fgcch, "/* Created by cgo - DO NOT EDIT. */\n") fmt.Fprintf(fgcch, "/* Created by cgo - DO NOT EDIT. */\n")
fmt.Fprintf(fgcch, "%s\n", p.Preamble) fmt.Fprintf(fgcch, "%s\n", p.Preamble)
fmt.Fprintf(fgcch, "%s\n", gccExportHeaderProlog) fmt.Fprintf(fgcch, "%s\n", p.gccExportHeaderProlog())
fmt.Fprintf(fgcc, "/* Created by cgo - DO NOT EDIT. */\n") fmt.Fprintf(fgcc, "/* Created by cgo - DO NOT EDIT. */\n")
fmt.Fprintf(fgcc, "#include \"_cgo_export.h\"\n") fmt.Fprintf(fgcc, "#include \"_cgo_export.h\"\n")
...@@ -664,7 +664,7 @@ func (p *Package) writeGccgoExports(fgo2, fc, fm *os.File) { ...@@ -664,7 +664,7 @@ func (p *Package) writeGccgoExports(fgo2, fc, fm *os.File) {
fmt.Fprintf(fgcch, "/* Created by cgo - DO NOT EDIT. */\n") fmt.Fprintf(fgcch, "/* Created by cgo - DO NOT EDIT. */\n")
fmt.Fprintf(fgcch, "%s\n", p.Preamble) fmt.Fprintf(fgcch, "%s\n", p.Preamble)
fmt.Fprintf(fgcch, "%s\n", gccExportHeaderProlog) fmt.Fprintf(fgcch, "%s\n", p.gccExportHeaderProlog())
fmt.Fprintf(fm, "#include \"_cgo_export.h\"\n") fmt.Fprintf(fm, "#include \"_cgo_export.h\"\n")
clean := func(r rune) rune { clean := func(r rune) rune {
...@@ -775,8 +775,8 @@ func c(repr string, args ...interface{}) *TypeRepr { ...@@ -775,8 +775,8 @@ func c(repr string, args ...interface{}) *TypeRepr {
var goTypes = map[string]*Type{ var goTypes = map[string]*Type{
"bool": {Size: 1, Align: 1, C: c("GoUint8")}, "bool": {Size: 1, Align: 1, C: c("GoUint8")},
"byte": {Size: 1, Align: 1, C: c("GoUint8")}, "byte": {Size: 1, Align: 1, C: c("GoUint8")},
"int": {Size: 4, Align: 4, C: c("GoInt")}, "int": {Size: 0, Align: 0, C: c("GoInt")},
"uint": {Size: 4, Align: 4, C: c("GoUint")}, "uint": {Size: 0, Align: 0, C: c("GoUint")},
"rune": {Size: 4, Align: 4, C: c("GoInt32")}, "rune": {Size: 4, Align: 4, C: c("GoInt32")},
"int8": {Size: 1, Align: 1, C: c("GoInt8")}, "int8": {Size: 1, Align: 1, C: c("GoInt8")},
"uint8": {Size: 1, Align: 1, C: c("GoUint8")}, "uint8": {Size: 1, Align: 1, C: c("GoUint8")},
...@@ -837,12 +837,21 @@ func (p *Package) cgoType(e ast.Expr) *Type { ...@@ -837,12 +837,21 @@ func (p *Package) cgoType(e ast.Expr) *Type {
return &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("GoUintptr")} return &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("GoUintptr")}
} }
if t.Name == "string" { if t.Name == "string" {
return &Type{Size: p.PtrSize + 4, Align: p.PtrSize, C: c("GoString")} // The string data is 1 pointer + 1 int, but this always
// rounds to 2 pointers due to alignment.
return &Type{Size: 2 * p.PtrSize, Align: p.PtrSize, C: c("GoString")}
} }
if t.Name == "error" { if t.Name == "error" {
return &Type{Size: 2 * p.PtrSize, Align: p.PtrSize, C: c("GoInterface")} return &Type{Size: 2 * p.PtrSize, Align: p.PtrSize, C: c("GoInterface")}
} }
if r, ok := goTypes[t.Name]; ok { if r, ok := goTypes[t.Name]; ok {
if r.Size == 0 { // int or uint
rr := new(Type)
*rr = *r
rr.Size = p.IntSize
rr.Align = p.IntSize
r = rr
}
if r.Align > p.PtrSize { if r.Align > p.PtrSize {
r.Align = p.PtrSize r.Align = p.PtrSize
} }
...@@ -964,9 +973,11 @@ Slice GoBytes(char *p, int n) { ...@@ -964,9 +973,11 @@ Slice GoBytes(char *p, int n) {
} }
` `
func (p *Package) gccExportHeaderProlog() string {
return strings.Replace(gccExportHeaderProlog, "GOINTBITS", fmt.Sprint(8*p.IntSize), -1)
}
const gccExportHeaderProlog = ` const gccExportHeaderProlog = `
typedef int GoInt;
typedef unsigned int GoUint;
typedef signed char GoInt8; typedef signed char GoInt8;
typedef unsigned char GoUint8; typedef unsigned char GoUint8;
typedef short GoInt16; typedef short GoInt16;
...@@ -975,6 +986,8 @@ typedef int GoInt32; ...@@ -975,6 +986,8 @@ typedef int GoInt32;
typedef unsigned int GoUint32; typedef unsigned int GoUint32;
typedef long long GoInt64; typedef long long GoInt64;
typedef unsigned long long GoUint64; typedef unsigned long long GoUint64;
typedef GoIntGOINTBITS GoInt;
typedef GoUintGOINTBITS GoUint;
typedef __SIZE_TYPE__ GoUintptr; typedef __SIZE_TYPE__ GoUintptr;
typedef float GoFloat32; typedef float GoFloat32;
typedef double GoFloat64; typedef double GoFloat64;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment