static Buf *output;
#define EOF -1
+enum
+{
+ use64bitint = 0,
+};
+
static int
xgetchar(void)
{
char *name;
int size;
} type_table[] = {
- /* variable sized first, for easy replacement */
- /* order matches enum above */
- /* default is 32-bit architecture sizes */
- {"bool", 1},
+ /*
+ * variable sized first, for easy replacement.
+ * order matches enum above.
+ * default is 32-bit architecture sizes.
+ * spelling as in package runtime, so intgo/uintgo not int/uint.
+ */
+ {"bool", 1},
{"float", 4},
- {"int", 4},
- {"uint", 4},
+ {"intgo", 4},
+ {"uintgo", 4},
{"uintptr", 4},
{"String", 8},
{"Slice", 12},
/* fixed size */
{"float32", 4},
{"float64", 8},
- {"byte", 1},
- {"int8", 1},
+ {"byte", 1},
+ {"int8", 1},
{"uint8", 1},
{"int16", 2},
{"uint16", 2},
{"int32", 4},
+ {"rune", 4},
{"uint32", 4},
{"int64", 8},
{"uint64", 8},
unsigned int len;
p = read_token_no_eof();
- if (*p != '*')
+ if (*p != '*' && !streq(p, "int") && !streq(p, "uint"))
return p;
op = p;
pointer_count = 0;
++p;
}
len = xstrlen(p);
- q = xmalloc(len + pointer_count + 1);
+ q = xmalloc(len + 2 + pointer_count + 1);
xmemmove(q, p, len);
- while (pointer_count > 0) {
- q[len] = '*';
- ++len;
- --pointer_count;
+
+ // Turn int/uint into intgo/uintgo.
+ if((len == 3 && xmemcmp(q, "int", 3) == 0) || (len == 4 && xmemcmp(q, "uint", 4) == 0)) {
+ q[len++] = 'g';
+ q[len++] = 'o';
}
+
+ while (pointer_count-- > 0)
+ q[len++] = '*';
+
q[len] = '\0';
xfree(op);
return q;
if(!gcc) {
if(streq(goarch, "amd64")) {
type_table[Uintptr].size = 8;
- type_table[String].size = 16;
- type_table[Slice].size = 8+4+4;
type_table[Eface].size = 8+8;
+ type_table[String].size = 16;
+ if(use64bitint) {
+ type_table[Int].size = 8;
+ type_table[Uint].size = 8;
+ }
+ type_table[Slice].size = 8+2*type_table[Int].size;
structround = 8;
} else {
+ // NOTE: These are set in the initializer,
+ // but they might have been changed by a
+ // previous invocation of goc2c, so we have
+ // to restore them.
type_table[Uintptr].size = 4;
type_table[String].size = 8;
type_table[Slice].size = 16;
type_table[Eface].size = 4+4;
+ type_table[Int].size = 4;
+ type_table[Uint].size = 4;
structround = 4;
}
}
tt := (*arrayType)(unsafe.Pointer(v.typ))
return int(tt.len)
case Chan:
- return int(chanlen(v.iword()))
+ return chanlen(v.iword())
case Map:
- return int(maplen(v.iword()))
+ return maplen(v.iword())
case Slice:
// Slice is bigger than a word; assume flagIndir.
return (*SliceHeader)(v.val).Len
}
m := v.iword()
- mlen := int32(0)
+ mlen := int(0)
if m != nil {
mlen = maplen(m)
}
if typ.ChanDir() != BothDir {
panic("reflect.MakeChan: unidirectional channel type")
}
- ch := makechan(typ.runtimeType(), uint32(buffer))
+ ch := makechan(typ.runtimeType(), uint64(buffer))
return Value{typ.common(), unsafe.Pointer(ch), flag(Chan) << flagKindShift}
}
}
// implemented in ../pkg/runtime
-func chancap(ch iword) int32
+func chancap(ch iword) int
func chanclose(ch iword)
-func chanlen(ch iword) int32
+func chanlen(ch iword) int
func chanrecv(t *runtimeType, ch iword, nb bool) (val iword, selected, received bool)
func chansend(t *runtimeType, ch iword, val iword, nb bool) bool
-func makechan(typ *runtimeType, size uint32) (ch iword)
+func makechan(typ *runtimeType, size uint64) (ch iword)
func makemap(t *runtimeType) (m iword)
func mapaccess(t *runtimeType, m iword, key iword) (val iword, ok bool)
func mapassign(t *runtimeType, m iword, key, val iword, ok bool)
func mapiterinit(t *runtimeType, m iword) *byte
func mapiterkey(it *byte) (key iword, ok bool)
func mapiternext(it *byte)
-func maplen(m iword) int32
+func maplen(m iword) int
func call(fn, arg unsafe.Pointer, n uint32)
func ifaceE2I(t *runtimeType, src interface{}, dst unsafe.Pointer)
void
runtime·strequal(bool *eq, uintptr s, void *a, void *b)
{
- int32 alen;
+ intgo alen;
USED(s);
alen = ((String*)a)->len;
// license that can be found in the LICENSE file.
#include "runtime.h"
+#include "arch_GOARCH.h"
#include "type.h"
+#include "malloc.h"
#define MAXALIGN 7
#define NOSELGEN 1
struct Hchan
{
- uint32 qcount; // total data in the q
- uint32 dataqsiz; // size of the circular q
+ uintgo qcount; // total data in the q
+ uintgo dataqsiz; // size of the circular q
uint16 elemsize;
bool closed;
uint8 elemalign;
Alg* elemalg; // interface for element type
- uint32 sendx; // send index
- uint32 recvx; // receive index
+ uintgo sendx; // send index
+ uintgo recvx; // receive index
WaitQ recvq; // list of recv waiters
WaitQ sendq; // list of send waiters
Lock;
runtime·makechan_c(ChanType *t, int64 hint)
{
Hchan *c;
- int32 n;
+ uintptr n;
Type *elem;
elem = t->elem;
- if(hint < 0 || (int32)hint != hint || (elem->size > 0 && hint > ((uintptr)-1) / elem->size))
+ // compiler checks this but be safe.
+ if(elem->size >= (1<<16))
+ runtime·throw("makechan: invalid channel element type");
+
+ if(hint < 0 || (intgo)hint != hint || (elem->size > 0 && hint > MaxMem / elem->size))
runtime·panicstring("makechan: size out of range");
// calculate rounded size of Hchan
c->dataqsiz = hint;
if(debug)
- runtime·printf("makechan: chan=%p; elemsize=%D; elemalg=%p; elemalign=%d; dataqsiz=%d\n",
- c, (int64)elem->size, elem->alg, elem->align, c->dataqsiz);
+ runtime·printf("makechan: chan=%p; elemsize=%D; elemalg=%p; elemalign=%d; dataqsiz=%D\n",
+ c, (int64)elem->size, elem->alg, elem->align, (int64)c->dataqsiz);
return c;
}
// For reflect
-// func makechan(typ *ChanType, size uint32) (chan)
+// func makechan(typ *ChanType, size uint64) (chan)
void
-reflect·makechan(ChanType *t, uint32 size, Hchan *c)
+reflect·makechan(ChanType *t, uint64 size, Hchan *c)
{
c = runtime·makechan_c(t, size);
FLUSH(&c);
// func rselect(cases []runtimeSelect) (chosen int, word uintptr, recvOK bool)
void
-reflect·rselect(Slice cases, int32 chosen, uintptr word, bool recvOK)
+reflect·rselect(Slice cases, intgo chosen, uintptr word, bool recvOK)
{
int32 i;
Select *sel;
}
}
- chosen = (int32)(uintptr)selectgo(&sel);
+ chosen = (intgo)(uintptr)selectgo(&sel);
if(rcase[chosen].dir == SelectRecv && rcase[chosen].typ->elem->size > sizeof(void*))
word = (uintptr)recvptr;
}
// For reflect
-// func chanlen(c chan) (len int32)
+// func chanlen(c chan) (len int)
void
-reflect·chanlen(Hchan *c, int32 len)
+reflect·chanlen(Hchan *c, intgo len)
{
if(c == nil)
len = 0;
}
// For reflect
-// func chancap(c chan) (cap int32)
+// func chancap(c chan) int
void
-reflect·chancap(Hchan *c, int32 cap)
+reflect·chancap(Hchan *c, intgo cap)
{
if(c == nil)
cap = 0;
// SetCPUProfileRate sets the CPU profiling rate.
// The user documentation is in debug.go.
void
-runtime·SetCPUProfileRate(int32 hz)
+runtime·SetCPUProfileRate(intgo hz)
{
uintptr *p;
uintptr n;
#define CanFreeKey (1<<3) /* okay to free pointers to keys */
struct Hmap { /* a hash table; initialize with hash_init() */
- uint32 count; /* elements in table - must be first */
+ uintgo count; /* elements in table - must be first */
uint8 datasize; /* amount of data to store in entry */
uint8 flag;
uint8 valoff; /* offset of value in key+value data block */
static int32 debug = 0;
-// makemap(typ *Type, hint uint32) (hmap *map[any]any);
Hmap*
runtime·makemap_c(MapType *typ, int64 hint)
{
}
// For reflect:
-// func maplen(h map) (len int32)
+// func maplen(h map) (len int)
// Like len(m) in the actual language, we treat the nil map as length 0.
void
-reflect·maplen(Hmap *h, int32 len)
+reflect·maplen(Hmap *h, intgo len)
{
if(h == nil)
len = 0;
}
void
-reflect·unsafe_NewArray(Eface typ, uint32 n, void *ret)
+reflect·unsafe_NewArray(Eface typ, intgo n, void *ret)
{
uint64 size;
Type *t;
extern MStats mstats; // defined in extern.go
-extern volatile int32 runtime·MemProfileRate;
+extern volatile intgo runtime·MemProfileRate;
// Allocate an object of at least size bytes.
// Small objects are allocated from the per-thread cache's free lists.
void*
runtime·mallocgc(uintptr size, uint32 flag, int32 dogc, int32 zeroed)
{
- int32 sizeclass, rate;
+ int32 sizeclass;
+ intgo rate;
MCache *c;
uintptr npages;
MSpan *s;
MCache*
runtime·allocmcache(void)
{
- int32 rate;
+ intgo rate;
MCache *c;
runtime·lock(&runtime·mheap);
byte *base;
uintptr size;
FuncType *ft;
- int32 i, nret;
+ int32 i;
+ uintptr nret;
Type *t;
if(obj.type == nil) {
MaxGcproc = 8,
};
+// Maximum memory allocation size, a hint for callers.
+// This must be a #define instead of an enum because it
+// is so large.
+#ifdef _64BIT
+#define MaxMem (16ULL<<30) /* 16 GB */
+#else
+#define MaxMem ((uintptr)-1)
+#endif
+
// A generic linked list of blocks. (Typically the block is bigger than sizeof(MLink).)
struct MLink
{
void runtime·helpgc(int32 nproc);
void runtime·gchelper(void);
-bool runtime·getfinalizer(void *p, bool del, void (**fn)(void*), int32 *nret);
+bool runtime·getfinalizer(void *p, bool del, void (**fn)(void*), uintptr *nret);
void runtime·walkfintab(void (*fn)(void*));
struct Fin
{
void (*fn)(void*);
- int32 nret;
+ uintptr nret;
};
// Finalizer hash table. Direct hash, linear scan, at most 3/4 full.
} fintab[TABSZ];
static void
-addfintab(Fintab *t, void *k, void (*fn)(void*), int32 nret)
+addfintab(Fintab *t, void *k, void (*fn)(void*), uintptr nret)
{
int32 i, j;
}
bool
-runtime·addfinalizer(void *p, void (*f)(void*), int32 nret)
+runtime·addfinalizer(void *p, void (*f)(void*), uintptr nret)
{
Fintab *tab;
byte *base;
// get finalizer; if del, delete finalizer.
// caller is responsible for updating RefHasFinalizer (special) bit.
bool
-runtime·getfinalizer(void *p, bool del, void (**fn)(void*), int32 *nret)
+runtime·getfinalizer(void *p, bool del, void (**fn)(void*), uintptr *nret)
{
Fintab *tab;
bool res;
{
void (*fn)(void*);
void *arg;
- int32 nret;
+ uintptr nret;
};
typedef struct FinBlock FinBlock;
handlespecial(byte *p, uintptr size)
{
void (*fn)(void*);
- int32 nret;
+ uintptr nret;
FinBlock *block;
Finalizer *f;
r->stk[i] = 0;
}
-func MemProfile(p Slice, include_inuse_zero bool) (n int32, ok bool) {
+func MemProfile(p Slice, include_inuse_zero bool) (n int, ok bool) {
Bucket *b;
Record *r;
uintptr stk[32];
};
-func ThreadCreateProfile(p Slice) (n int32, ok bool) {
+func ThreadCreateProfile(p Slice) (n int, ok bool) {
TRecord *r;
M *first, *m;
}
}
-func Stack(b Slice, all bool) (n int32) {
+func Stack(b Slice, all bool) (n int) {
byte *pc, *sp;
sp = runtime·getcallersp(&b);
r->stk[n] = 0;
}
-func GoroutineProfile(b Slice) (n int32, ok bool) {
+func GoroutineProfile(b Slice) (n int, ok bool) {
byte *pc, *sp;
TRecord *r;
G *gp;
extern uint32 runtime·maxstring;
if(v.len > runtime·maxstring) {
- gwrite("[invalid string]", 16);
+ gwrite("[string too long]", 17);
return;
}
if(v.len > 0)
}
void
-runtime·NumGoroutine(int32 ret)
+runtime·NumGoroutine(intgo ret)
{
ret = runtime·sched.gcount;
FLUSH(&ret);
}
void
-runtime·Caller(int32 skip, uintptr retpc, String retfile, int32 retline, bool retbool)
+runtime·Caller(intgo skip, uintptr retpc, String retfile, intgo retline, bool retbool)
{
Func *f, *g;
uintptr pc;
}
void
-runtime·Callers(int32 skip, Slice pc, int32 retn)
+runtime·Callers(intgo skip, Slice pc, intgo retn)
{
// runtime.callers uses pc.array==nil as a signal
// to print a stack trace. Pick off 0-length pc here
#ifdef _64BIT
typedef uint64 uintptr;
typedef int64 intptr;
+typedef int32 intgo; // Go's int
+typedef uint32 uintgo; // Go's uint
#else
typedef uint32 uintptr;
-typedef int32 intptr;
+typedef int32 intptr;
+typedef int32 intgo; // Go's int
+typedef uint32 uintgo; // Go's uint
#endif
/*
struct String
{
byte* str;
- int32 len;
+ intgo len;
};
struct Iface
{
struct Slice
{ // must not move anything
byte* array; // actual data
- uint32 len; // number of elements
- uint32 cap; // allocated number of elements
+ uintgo len; // number of elements
+ uintgo cap; // allocated number of elements
};
struct Gobuf
{
int8* runtime·goos;
int32 runtime·ncpu;
extern bool runtime·iscgo;
-extern void (*runtime·sysargs)(int32, uint8**);
+extern void (*runtime·sysargs)(int32, uint8**);
+extern uint32 runtime·maxstring;
/*
* common functions and data
void* runtime·mal(uintptr);
String runtime·catstring(String, String);
String runtime·gostring(byte*);
-String runtime·gostringn(byte*, int32);
-Slice runtime·gobytes(byte*, int32);
+String runtime·gostringn(byte*, intgo);
+Slice runtime·gobytes(byte*, intgo);
String runtime·gostringnocopy(byte*);
String runtime·gostringw(uint16*);
void runtime·initsig(void);
uintptr runtime·efacehash(Eface);
void* runtime·malloc(uintptr size);
void runtime·free(void *v);
-bool runtime·addfinalizer(void*, void(*fn)(void*), int32);
+bool runtime·addfinalizer(void*, void(*fn)(void*), uintptr);
void runtime·runpanic(Panic*);
void* runtime·getcallersp(void*);
int32 runtime·mcount(void);
Hchan* runtime·makechan_c(ChanType*, int64);
void runtime·chansend(ChanType*, Hchan*, byte*, bool*);
void runtime·chanrecv(ChanType*, Hchan*, byte*, bool*, bool*);
-int32 runtime·chanlen(Hchan*);
-int32 runtime·chancap(Hchan*);
bool runtime·showframe(Func*);
void runtime·ifaceE2I(struct InterfaceType*, Eface, Iface*);
package runtime
#include "runtime.h"
-func GOMAXPROCS(n int32) (ret int32) {
+func GOMAXPROCS(n int) (ret int) {
ret = runtime·gomaxprocsfunc(n);
}
-func NumCPU() (ret int32) {
+func NumCPU() (ret int) {
ret = runtime·ncpu;
}
#include "typekind.h"
#include "malloc.h"
-static int32 debug = 0;
+static bool debug = 0;
-static void makeslice1(SliceType*, int32, int32, Slice*);
-static void growslice1(SliceType*, Slice, int32, Slice *);
- void runtime·copy(Slice to, Slice fm, uintptr width, int32 ret);
+static void makeslice1(SliceType*, intgo, intgo, Slice*);
+static void growslice1(SliceType*, Slice, intgo, Slice *);
+ void runtime·copy(Slice to, Slice fm, uintptr width, intgo ret);
// see also unsafe·NewArray
// makeslice(typ *Type, len, cap int64) (ary []any);
void
runtime·makeslice(SliceType *t, int64 len, int64 cap, Slice ret)
{
- if(len < 0 || (int32)len != len)
+ if(len < 0 || (intgo)len != len)
runtime·panicstring("makeslice: len out of range");
- if(cap < len || (int32)cap != cap || t->elem->size > 0 && cap > ((uintptr)-1) / t->elem->size)
+
+ if(cap < len || (intgo)cap != cap || t->elem->size > 0 && cap > MaxMem / t->elem->size)
runtime·panicstring("makeslice: cap out of range");
makeslice1(t, len, cap, &ret);
static uintptr zerobase;
static void
-makeslice1(SliceType *t, int32 len, int32 cap, Slice *ret)
+makeslice1(SliceType *t, intgo len, intgo cap, Slice *ret)
{
uintptr size;
void
runtime·appendslice(SliceType *t, Slice x, Slice y, Slice ret)
{
- int32 m;
+ intgo m;
uintptr w;
m = x.len+y.len;
void
runtime·appendstr(SliceType *t, Slice x, String y, Slice ret)
{
- int32 m;
+ intgo m;
m = x.len+y.len;
cap = old.cap + n;
- if((int32)cap != cap || cap > ((uintptr)-1) / t->elem->size)
+ if((intgo)cap != cap || cap < old.cap || cap > MaxMem / t->elem->size)
runtime·panicstring("growslice: cap out of range");
growslice1(t, old, cap, &ret);
}
static void
-growslice1(SliceType *t, Slice x, int32 newcap, Slice *ret)
+growslice1(SliceType *t, Slice x, intgo newcap, Slice *ret)
{
- int32 m;
+ intgo m;
m = x.cap;
- if(m == 0)
+
+ // Using newcap directly for m+m < newcap handles
+ // both the case where m == 0 and also the case where
+ // m+m/4 wraps around, in which case the loop
+ // below might never terminate.
+ if(m+m < newcap)
m = newcap;
else {
do {
runtime·memmove(ret->array, x.array, ret->len * t->elem->size);
}
-// copy(to any, fr any, wid uint32) int
+// copy(to any, fr any, wid uintptr) int
void
-runtime·copy(Slice to, Slice fm, uintptr width, int32 ret)
+runtime·copy(Slice to, Slice fm, uintptr width, intgo ret)
{
if(fm.len == 0 || to.len == 0 || width == 0) {
ret = 0;
}
void
-runtime·slicestringcopy(Slice to, String fm, int32 ret)
+runtime·slicestringcopy(Slice to, String fm, intgo ret)
{
if(fm.len == 0 || to.len == 0) {
ret = 0;
return l;
}
-uint32 runtime·maxstring = 256;
+uint32 runtime·maxstring = 256; // a hint for print
static String
-gostringsize(int32 l)
+gostringsize(intgo l)
{
String s;
uint32 ms;
String
runtime·gostring(byte *str)
{
- int32 l;
+ intgo l;
String s;
l = runtime·findnull(str);
}
String
-runtime·gostringn(byte *str, int32 l)
+runtime·gostringn(byte *str, intgo l)
{
String s;
}
Slice
-runtime·gobytes(byte *p, int32 n)
+runtime·gobytes(byte *p, intgo n)
{
Slice sl;
String
runtime·gostringw(uint16 *str)
{
- int32 n1, n2, i;
+ intgo n1, n2, i;
byte buf[8];
String s;
}
static String
-concatstring(int32 n, String *s)
+concatstring(intgo n, String *s)
{
- int32 i, l, count;
+ intgo i, l, count;
String out;
l = 0;
#pragma textflag 7
// s1 is the first of n strings.
// the output string follows.
-func concatstring(n int32, s1 String) {
+func concatstring(n int, s1 String) {
(&s1)[n] = concatstring(n, &s1);
}
static int32
cmpstring(String s1, String s2)
{
- uint32 i, l;
+ uintgo i, l;
byte c1, c2;
l = s1.len;
return 0;
}
-func cmpstring(s1 String, s2 String) (v int32) {
+func cmpstring(s1 String, s2 String) (v int) {
v = cmpstring(s1, s2);
}
func eqstring(s1 String, s2 String) (v bool) {
- uint32 i, l;
+ uintgo i, l;
if(s1.len != s2.len) {
v = false;
int32
runtime·strcmp(byte *s1, byte *s2)
{
- uint32 i;
+ uintptr i;
byte c1, c2;
for(i=0;; i++) {
}
func slicerunetostring(b Slice) (s String) {
- int32 siz1, siz2, i;
+ intgo siz1, siz2, i;
int32 *a;
byte dum[8];
}
func stringtoslicerune(s String) (b Slice) {
- int32 n;
+ intgo n;
int32 dum, *r;
uint8 *p, *ep;
Runeself = 0x80,
};
-func stringiter(s String, k int32) (retk int32) {
+func stringiter(s String, k int) (retk int) {
int32 l;
if(k >= s.len) {
out:
}
-func stringiter2(s String, k int32) (retk int32, retv int32) {
+func stringiter2(s String, k int) (retk int, retv int32) {
if(k >= s.len) {
// retk=0 is end of iteration
retk = 0;
}
void
-runtime·funcline_go(Func *f, uintptr targetpc, String retfile, int32 retline)
+runtime·funcline_go(Func *f, uintptr targetpc, String retfile, intgo retline)
{
retfile = f->src;
retline = runtime·funcline(f, targetpc);