gmp

package
v0.0.0-...-e0c80c8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 23, 2020 License: BSD-3-Clause Imports: 3 Imported by: 0

Documentation

Overview

An example of wrapping a C library in Go. This is the GNU multiprecision library gmp's integer type mpz_t wrapped to look like the Go package big's integer type Int.

This is a syntactically valid Go program—it can be parsed with the Go parser and processed by godoc—but it is not compiled directly by gc. Instead, a separate tool, cgo, processes it to produce three output files. The first two, 6g.go and 6c.c, are a Go source file for 6g and a C source file for 6c; both compile as part of the named package (gmp, in this example). The third, gcc.c, is a C source file for gcc; it compiles into a shared object (.so) that is dynamically linked into any 6.out that imports the first two files.

The stanza

// #include <gmp.h>
import "C"

is a signal to cgo. The doc comment on the import of "C" provides additional context for the C file. Here it is just a single #include but it could contain arbitrary C definitions to be imported and used.

Cgo recognizes any use of a qualified identifier C.xxx and uses gcc to find the definition of xxx. If xxx is a type, cgo replaces C.xxx with a Go translation. C arithmetic types translate to precisely-sized Go arithmetic types. A C struct translates to a Go struct, field by field; unrepresentable fields are replaced with opaque byte arrays. A C union translates into a struct containing the first union member and perhaps additional padding. C arrays become Go arrays. C pointers become Go pointers. C function pointers become Go's uintptr. C void pointers become Go's unsafe.Pointer.

For example, mpz_t is defined in <gmp.h> as:

typedef unsigned long int mp_limb_t;

typedef struct
{
	int _mp_alloc;
	int _mp_size;
	mp_limb_t *_mp_d;
} __mpz_struct;

typedef __mpz_struct mpz_t[1];

Cgo generates:

type _C_int int32
type _C_mp_limb_t uint64
type _C___mpz_struct struct {
	_mp_alloc _C_int;
	_mp_size _C_int;
	_mp_d *_C_mp_limb_t;
}
type _C_mpz_t [1]_C___mpz_struct

and then replaces each occurrence of a type C.xxx with _C_xxx.

If xxx is data, cgo arranges for C.xxx to refer to the C variable, with the type translated as described above. To do this, cgo must introduce a Go variable that points at the C variable (the linker can be told to initialize this pointer). For example, if the gmp library provided

mpz_t zero;

then cgo would rewrite a reference to C.zero by introducing

var _C_zero *C.mpz_t

and then replacing all instances of C.zero with (*_C_zero).

Cgo's most interesting translation is for functions. If xxx is a C function, then cgo rewrites C.xxx into a new function _C_xxx that calls the C xxx in a standard pthread. The new function translates its arguments, calls xxx, and translates the return value.

Translation of parameters and the return value follows the type translation above except that arrays passed as parameters translate explicitly in Go to pointers to arrays, as they do (implicitly) in C.

Garbage collection is the big problem. It is fine for the Go world to have pointers into the C world and to free those pointers when they are no longer needed. To help, the Go code can define Go objects holding the C pointers and use runtime.SetFinalizer on those Go objects.

It is much more difficult for the C world to have pointers into the Go world, because the Go garbage collector is unaware of the memory allocated by C. The most important consideration is not to constrain future implementations, so the rule is that Go code can hand a Go pointer to C code but must separately arrange for Go to hang on to a reference to the pointer until C is done with it.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CmpInt

func CmpInt(x, y *Int) int

CmpInt compares x and y. The result is

-1 if x <  y
 0 if x == y
+1 if x >  y

func DivModInt

func DivModInt(q, r, x, y *Int)

DivModInt sets q = x / y and r = x % y.

func GcdInt

func GcdInt(d, x, y, a, b *Int)

GcdInt sets d to the greatest common divisor of a and b, which must be positive numbers. If x and y are not nil, GcdInt sets x and y such that d = a*x + b*y. If either a or b is not positive, GcdInt sets d = x = y = 0.

Types

type Int

type Int struct {
	// contains filtered or unexported fields
}

An Int represents a signed multi-precision integer. The zero value for an Int represents the value 0.

func NewInt

func NewInt(x int64) *Int

NewInt returns a new Int initialized to x.

func (*Int) Abs

func (z *Int) Abs(x *Int) *Int

Abs sets z to the absolute value of x and returns z.

func (*Int) Add

func (z *Int) Add(x, y *Int) *Int

Add sets z = x + y and returns z.

func (*Int) Bytes

func (z *Int) Bytes() []byte

Bytes returns z's representation as a big-endian byte array.

func (*Int) Div

func (z *Int) Div(x, y *Int) *Int

Div sets z = x / y, rounding toward zero, and returns z.

func (*Int) Exp

func (z *Int) Exp(x, y, m *Int) *Int

Exp sets z = x^y % m and returns z. If m == nil, Exp sets z = x^y.

func (*Int) Int64

func (z *Int) Int64() int64

func (*Int) Len

func (z *Int) Len() int

Len returns the length of z in bits. 0 is considered to have length 1.

func (*Int) Lsh

func (z *Int) Lsh(x *Int, s uint) *Int

Lsh sets z = x << s and returns z.

func (*Int) Mod

func (z *Int) Mod(x, y *Int) *Int

Mod sets z = x % y and returns z. Like the result of the Go % operator, z has the same sign as x.

func (*Int) Mul

func (z *Int) Mul(x, y *Int) *Int

Mul sets z = x * y and returns z.

func (*Int) Neg

func (z *Int) Neg(x *Int) *Int

Neg sets z = -x and returns z.

func (*Int) ProbablyPrime

func (z *Int) ProbablyPrime(n int) bool

ProbablyPrime performs n Miller-Rabin tests to check whether z is prime. If it returns true, z is prime with probability 1 - 1/4^n. If it returns false, z is not prime.

func (*Int) Rsh

func (z *Int) Rsh(x *Int, s uint) *Int

Rsh sets z = x >> s and returns z.

func (*Int) Set

func (z *Int) Set(x *Int) *Int

Set sets z = x and returns z.

func (*Int) SetBytes

func (z *Int) SetBytes(b []byte) *Int

SetBytes interprets b as the bytes of a big-endian integer and sets z to that value.

func (*Int) SetInt64

func (z *Int) SetInt64(x int64) *Int

SetInt64 sets z = x and returns z.

func (*Int) SetString

func (z *Int) SetString(s string, base int) error

SetString interprets s as a number in the given base and sets z to that value. The base must be in the range [2,36]. SetString returns an error if s cannot be parsed or the base is invalid.

func (*Int) String

func (z *Int) String() string

String returns the decimal representation of z.

func (*Int) Sub

func (z *Int) Sub(x, y *Int) *Int

Sub sets z = x - y and returns z.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL