mirror of
https://github.com/golang/go
synced 2024-11-24 21:00:09 -07:00
cgo: add GoBytes, fix gmp example
Fixes #1640. Fixes #2007. R=golang-dev, adg CC=golang-dev https://golang.org/cl/4815063
This commit is contained in:
parent
acb02ebc30
commit
db9229def8
@ -265,7 +265,7 @@ func (z *Int) Mod(x, y *Int) *Int {
|
|||||||
func (z *Int) Lsh(x *Int, s uint) *Int {
|
func (z *Int) Lsh(x *Int, s uint) *Int {
|
||||||
x.doinit()
|
x.doinit()
|
||||||
z.doinit()
|
z.doinit()
|
||||||
C.mpz_mul_2exp(&z.i[0], &x.i[0], C.ulong(s))
|
C.mpz_mul_2exp(&z.i[0], &x.i[0], C.mp_bitcnt_t(s))
|
||||||
return z
|
return z
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,7 +273,7 @@ func (z *Int) Lsh(x *Int, s uint) *Int {
|
|||||||
func (z *Int) Rsh(x *Int, s uint) *Int {
|
func (z *Int) Rsh(x *Int, s uint) *Int {
|
||||||
x.doinit()
|
x.doinit()
|
||||||
z.doinit()
|
z.doinit()
|
||||||
C.mpz_div_2exp(&z.i[0], &x.i[0], C.ulong(s))
|
C.mpz_div_2exp(&z.i[0], &x.i[0], C.mp_bitcnt_t(s))
|
||||||
return z
|
return z
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,3 +42,4 @@ func (f *File) Flush() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var Greeting = C.GoString(C.greeting)
|
var Greeting = C.GoString(C.greeting)
|
||||||
|
var Gbytes = C.GoBytes(unsafe.Pointer(C.greeting), C.int(len(Greeting)))
|
||||||
|
@ -189,6 +189,10 @@ func (f *File) saveExport(x interface{}, context string) {
|
|||||||
error(c.Pos(), "export missing name")
|
error(c.Pos(), "export missing name")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if name != n.Name.Name {
|
||||||
|
error(c.Pos(), "export comment has wrong name %q, want %q", name, n.Name.Name)
|
||||||
|
}
|
||||||
|
|
||||||
f.ExpFunc = append(f.ExpFunc, &ExpFunc{
|
f.ExpFunc = append(f.ExpFunc, &ExpFunc{
|
||||||
Func: n,
|
Func: n,
|
||||||
ExpName: name,
|
ExpName: name,
|
||||||
|
@ -52,6 +52,7 @@ C.char, C.schar (signed char), C.uchar (unsigned char),
|
|||||||
C.short, C.ushort (unsigned short), C.int, C.uint (unsigned int),
|
C.short, C.ushort (unsigned short), C.int, C.uint (unsigned int),
|
||||||
C.long, C.ulong (unsigned long), C.longlong (long long),
|
C.long, C.ulong (unsigned long), C.longlong (long long),
|
||||||
C.ulonglong (unsigned long long), C.float, C.double.
|
C.ulonglong (unsigned long long), C.float, C.double.
|
||||||
|
The C type void* is represented by Go's unsafe.Pointer.
|
||||||
|
|
||||||
To access a struct, union, or enum type directly, prefix it with
|
To access a struct, union, or enum type directly, prefix it with
|
||||||
struct_, union_, or enum_, as in C.struct_stat.
|
struct_, union_, or enum_, as in C.struct_stat.
|
||||||
@ -68,6 +69,21 @@ C compilers are aware of this calling convention and adjust
|
|||||||
the call accordingly, but Go cannot. In Go, you must pass
|
the call accordingly, but Go cannot. In Go, you must pass
|
||||||
the pointer to the first element explicitly: C.f(&x[0]).
|
the pointer to the first element explicitly: C.f(&x[0]).
|
||||||
|
|
||||||
|
A few special functions convert between Go and C types
|
||||||
|
by making copies of the data. In pseudo-Go definitions:
|
||||||
|
|
||||||
|
// Go string to C string
|
||||||
|
func C.CString(string) *C.char
|
||||||
|
|
||||||
|
// C string to Go string
|
||||||
|
func C.GoString(*C.char) string
|
||||||
|
|
||||||
|
// C string, length to Go string
|
||||||
|
func C.GoStringN(*C.char, C.int) string
|
||||||
|
|
||||||
|
// C pointer, length to Go []byte
|
||||||
|
func C.GoBytes(unsafe.Pointer, C.int) []byte
|
||||||
|
|
||||||
Cgo transforms the input file into four output files: two Go source
|
Cgo transforms the input file into four output files: two Go source
|
||||||
files, a C file for 6c (or 8c or 5c), and a C file for gcc.
|
files, a C file for 6c (or 8c or 5c), and a C file for gcc.
|
||||||
|
|
||||||
|
@ -1140,6 +1140,14 @@ func (c *typeConv) Type(dtype dwarf.Type) *Type {
|
|||||||
t.Align = c.ptrSize
|
t.Align = c.ptrSize
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if dt.Name == "_GoBytes_" {
|
||||||
|
// Special C name for Go []byte type.
|
||||||
|
// Knows slice layout used by compilers: pointer, length, cap.
|
||||||
|
t.Go = c.Ident("[]byte")
|
||||||
|
t.Size = c.ptrSize + 4 + 4
|
||||||
|
t.Align = c.ptrSize
|
||||||
|
break
|
||||||
|
}
|
||||||
name := c.Ident("_Ctypedef_" + dt.Name)
|
name := c.Ident("_Ctypedef_" + dt.Name)
|
||||||
t.Go = name // publish before recursive call
|
t.Go = name // publish before recursive call
|
||||||
sub := c.Type(dt.Type)
|
sub := c.Type(dt.Type)
|
||||||
|
@ -236,7 +236,7 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
|
|||||||
printer.Fprint(fgo2, fset, d)
|
printer.Fprint(fgo2, fset, d)
|
||||||
fmt.Fprintf(fgo2, "\n")
|
fmt.Fprintf(fgo2, "\n")
|
||||||
|
|
||||||
if name == "CString" || name == "GoString" || name == "GoStringN" {
|
if name == "CString" || name == "GoString" || name == "GoStringN" || name == "GoBytes" {
|
||||||
// The builtins are already defined in the C prolog.
|
// The builtins are already defined in the C prolog.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -316,7 +316,7 @@ func (p *Package) writeOutput(f *File, srcfile string) {
|
|||||||
|
|
||||||
func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
|
func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
|
||||||
name := n.Mangle
|
name := n.Mangle
|
||||||
if name == "_Cfunc_CString" || name == "_Cfunc_GoString" || name == "_Cfunc_GoStringN" || p.Written[name] {
|
if name == "_Cfunc_CString" || name == "_Cfunc_GoString" || name == "_Cfunc_GoStringN" || name == "_Cfunc_GoBytes" || p.Written[name] {
|
||||||
// The builtins are already defined in the C prolog, and we don't
|
// The builtins are already defined in the C prolog, and we don't
|
||||||
// want to duplicate function definitions we've already done.
|
// want to duplicate function definitions we've already done.
|
||||||
return
|
return
|
||||||
@ -646,6 +646,8 @@ func (p *Package) cgoType(e ast.Expr) *Type {
|
|||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
error(e.Pos(), "unrecognized Go type %s", t.Name)
|
||||||
|
return &Type{Size: 4, Align: 4, C: c("int")}
|
||||||
case *ast.SelectorExpr:
|
case *ast.SelectorExpr:
|
||||||
id, ok := t.X.(*ast.Ident)
|
id, ok := t.X.(*ast.Ident)
|
||||||
if ok && id.Name == "unsafe" && t.Sel.Name == "Pointer" {
|
if ok && id.Name == "unsafe" && t.Sel.Name == "Pointer" {
|
||||||
@ -679,8 +681,10 @@ __cgo_size_assert(double, 8)
|
|||||||
|
|
||||||
const builtinProlog = `
|
const builtinProlog = `
|
||||||
typedef struct { char *p; int n; } _GoString_;
|
typedef struct { char *p; int n; } _GoString_;
|
||||||
|
typedef struct { char *p; int n; int c; } _GoBytes_;
|
||||||
_GoString_ GoString(char *p);
|
_GoString_ GoString(char *p);
|
||||||
_GoString_ GoStringN(char *p, int l);
|
_GoString_ GoStringN(char *p, int l);
|
||||||
|
_GoBytes_ GoBytes(void *p, int n);
|
||||||
char *CString(_GoString_);
|
char *CString(_GoString_);
|
||||||
`
|
`
|
||||||
|
|
||||||
@ -704,6 +708,13 @@ void
|
|||||||
FLUSH(&s);
|
FLUSH(&s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
·_Cfunc_GoBytes(int8 *p, int32 l, Slice s)
|
||||||
|
{
|
||||||
|
s = runtime·gobytes((byte*)p, l);
|
||||||
|
FLUSH(&s);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
·_Cfunc_CString(String s, int8 *p)
|
·_Cfunc_CString(String s, int8 *p)
|
||||||
{
|
{
|
||||||
|
@ -413,6 +413,7 @@ void* runtime·mal(uintptr);
|
|||||||
String runtime·catstring(String, String);
|
String runtime·catstring(String, String);
|
||||||
String runtime·gostring(byte*);
|
String runtime·gostring(byte*);
|
||||||
String runtime·gostringn(byte*, int32);
|
String runtime·gostringn(byte*, int32);
|
||||||
|
Slice runtime·gobytes(byte*, int32);
|
||||||
String runtime·gostringnocopy(byte*);
|
String runtime·gostringnocopy(byte*);
|
||||||
String runtime·gostringw(uint16*);
|
String runtime·gostringw(uint16*);
|
||||||
void runtime·initsig(int32);
|
void runtime·initsig(int32);
|
||||||
|
@ -74,6 +74,16 @@ runtime·gostringn(byte *str, int32 l)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Slice
|
||||||
|
runtime·gobytes(byte *p, int32 n)
|
||||||
|
{
|
||||||
|
Slice sl;
|
||||||
|
|
||||||
|
sl.array = runtime·mallocgc(n, FlagNoPointers, 1, 0);
|
||||||
|
runtime·memmove(sl.array, p, n);
|
||||||
|
return sl;
|
||||||
|
}
|
||||||
|
|
||||||
String
|
String
|
||||||
runtime·gostringnocopy(byte *str)
|
runtime·gostringnocopy(byte *str)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user