diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-10-10 23:13:39 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-10-10 23:13:39 +0000 |
commit | 65180edc5661b1324a53ac9ebbe03f44cda524e4 (patch) | |
tree | 661f2ef36aee0c3ee5866edd2bcf540260a98506 /libgo/runtime/print.c | |
parent | 73f01cca846d729848e793689389bcaa0dec3045 (diff) | |
download | gcc-65180edc5661b1324a53ac9ebbe03f44cda524e4.zip gcc-65180edc5661b1324a53ac9ebbe03f44cda524e4.tar.gz gcc-65180edc5661b1324a53ac9ebbe03f44cda524e4.tar.bz2 |
runtime: copy print/println support from Go 1.7
Update the compiler to use the new names. Add calls to printlock and
printunlock around print statements. Move expression evaluation before
the call to printlock. Update g's writebuf field to a slice, and adjust
C code accordingly.
Reviewed-on: https://go-review.googlesource.com/30717
From-SVN: r240956
Diffstat (limited to 'libgo/runtime/print.c')
-rw-r--r-- | libgo/runtime/print.c | 301 |
1 files changed, 66 insertions, 235 deletions
diff --git a/libgo/runtime/print.c b/libgo/runtime/print.c index 69b1f81..4da8796 100644 --- a/libgo/runtime/print.c +++ b/libgo/runtime/print.c @@ -9,58 +9,60 @@ #include "array.h" #include "go-type.h" -//static Lock debuglock; +extern void runtime_printlock(void) + __asm__(GOSYM_PREFIX "runtime.printlock"); +extern void runtime_printunlock(void) + __asm__(GOSYM_PREFIX "runtime.printunlock"); +extern void gwrite(Slice) + __asm__(GOSYM_PREFIX "runtime.gwrite"); +extern void runtime_printint(int64) + __asm__(GOSYM_PREFIX "runtime.printint"); +extern void runtime_printuint(uint64) + __asm__(GOSYM_PREFIX "runtime.printuint"); +extern void runtime_printhex(uint64) + __asm__(GOSYM_PREFIX "runtime.printhex"); +extern void runtime_printfloat(float64) + __asm__(GOSYM_PREFIX "runtime.printfloat"); +extern void runtime_printcomplex(complex double) + __asm__(GOSYM_PREFIX "runtime.printcomplex"); +extern void runtime_printbool(_Bool) + __asm__(GOSYM_PREFIX "runtime.printbool"); +extern void runtime_printstring(String) + __asm__(GOSYM_PREFIX "runtime.printstring"); +extern void runtime_printpointer(void *) + __asm__(GOSYM_PREFIX "runtime.printpointer"); +extern void runtime_printslice(Slice) + __asm__(GOSYM_PREFIX "runtime.printslice"); +extern void runtime_printeface(Eface) + __asm__(GOSYM_PREFIX "runtime.printeface"); +extern void runtime_printiface(Iface) + __asm__(GOSYM_PREFIX "runtime.printiface"); // Clang requires this function to not be inlined (see below). static void go_vprintf(const char*, va_list) __attribute__((noinline)); -// write to goroutine-local buffer if diverting output, -// or else standard error. static void -gwrite(const void *v, intgo n) +runtime_prints(const char *s) { - G* g = runtime_g(); - - if(g == nil || g->writebuf == nil) { - // Avoid -D_FORTIFY_SOURCE problems. - int rv __attribute__((unused)); - - rv = runtime_write(2, v, n); - return; - } - - if(g->writenbuf == 0) - return; + Slice sl; - if(n > g->writenbuf) - n = g->writenbuf; - runtime_memmove(g->writebuf, v, n); - g->writebuf += n; - g->writenbuf -= n; + // Use memcpy to avoid const-cast warning. + memcpy(&sl.__values, &s, sizeof(char*)); + sl.__count = runtime_findnull((const byte*)s); + sl.__capacity = sl.__count; + gwrite(sl); } -void -runtime_dump(byte *p, int32 n) +static void +runtime_printbyte(int8 c) { - int32 i; - - for(i=0; i<n; i++) { - runtime_printpointer((byte*)(uintptr)(p[i]>>4)); - runtime_printpointer((byte*)(uintptr)(p[i]&0xf)); - if((i&15) == 15) - runtime_prints("\n"); - else - runtime_prints(" "); - } - if(n & 15) - runtime_prints("\n"); -} + Slice sl; -void -runtime_prints(const char *s) -{ - gwrite(s, runtime_findnull((const byte*)s)); + sl.__values = &c; + sl.__count = 1; + sl.__capacity = 1; + gwrite(sl); } #if defined (__clang__) && (defined (__i386__) || defined (__x86_64__)) @@ -104,15 +106,17 @@ runtime_snprintf(byte *buf, int32 n, const char *s, ...) va_list va; int32 m; - g->writebuf = buf; - g->writenbuf = n-1; + g->writebuf.__values = buf; + g->writebuf.__count = 0; + g->writebuf.__capacity = n-1; va_start(va, s); go_vprintf(s, va); va_end(va); - *g->writebuf = '\0'; - m = g->writebuf - buf; - g->writenbuf = 0; - g->writebuf = nil; + m = g->writebuf.__count; + ((byte*)g->writebuf.__values)[m] = '\0'; + g->writebuf.__values = nil; + g->writebuf.__count = 0; + g->writebuf.__capacity = 0; return m; } @@ -122,15 +126,21 @@ static void go_vprintf(const char *s, va_list va) { const char *p, *lp; + Slice sl; - //runtime_lock(&debuglock); + runtime_printlock(); lp = p = s; for(; *p; p++) { if(*p != '%') continue; - if(p > lp) - gwrite(lp, p-lp); + if(p > lp) { + // Use memcpy to avoid const-cast warning. + memcpy(&sl.__values, &lp, sizeof(char*)); + sl.__count = p - lp; + sl.__capacity = p - lp; + gwrite(sl); + } p++; switch(*p) { case 'a': @@ -181,192 +191,13 @@ go_vprintf(const char *s, va_list va) } lp = p+1; } - if(p > lp) - gwrite(lp, p-lp); - - //runtime_unlock(&debuglock); -} - -void -runtime_printpc(void *p __attribute__ ((unused))) -{ - runtime_prints("PC="); - runtime_printhex((uint64)(uintptr)runtime_getcallerpc(p)); -} - -void -runtime_printbool(_Bool v) -{ - if(v) { - gwrite("true", 4); - return; - } - gwrite("false", 5); -} - -void -runtime_printbyte(int8 c) -{ - gwrite(&c, 1); -} - -void -runtime_printfloat(double v) -{ - byte buf[20]; - int32 e, s, i, n; - float64 h; - - if(ISNAN(v)) { - gwrite("NaN", 3); - return; - } - if(isinf(v)) { - if(signbit(v)) { - gwrite("-Inf", 4); - } else { - gwrite("+Inf", 4); - } - return; + if(p > lp) { + // Use memcpy to avoid const-cast warning. + memcpy(&sl.__values, &lp, sizeof(char*)); + sl.__count = p - lp; + sl.__capacity = p - lp; + gwrite(sl); } - n = 7; // digits printed - e = 0; // exp - s = 0; // sign - if(v == 0) { - if(isinf(1/v) && 1/v < 0) - s = 1; - } else { - // sign - if(v < 0) { - v = -v; - s = 1; - } - - // normalize - while(v >= 10) { - e++; - v /= 10; - } - while(v < 1) { - e--; - v *= 10; - } - - // round - h = 5; - for(i=0; i<n; i++) - h /= 10; - - v += h; - if(v >= 10) { - e++; - v /= 10; - } - } - - // format +d.dddd+edd - buf[0] = '+'; - if(s) - buf[0] = '-'; - for(i=0; i<n; i++) { - s = v; - buf[i+2] = s+'0'; - v -= s; - v *= 10.; - } - buf[1] = buf[2]; - buf[2] = '.'; - - buf[n+2] = 'e'; - buf[n+3] = '+'; - if(e < 0) { - e = -e; - buf[n+3] = '-'; - } - - buf[n+4] = (e/100) + '0'; - buf[n+5] = (e/10)%10 + '0'; - buf[n+6] = (e%10) + '0'; - gwrite(buf, n+7); -} - -void -runtime_printcomplex(complex double v) -{ - gwrite("(", 1); - runtime_printfloat(creal(v)); - runtime_printfloat(cimag(v)); - gwrite("i)", 2); -} - -void -runtime_printuint(uint64 v) -{ - byte buf[100]; - int32 i; - - for(i=nelem(buf)-1; i>0; i--) { - buf[i] = v%10 + '0'; - if(v < 10) - break; - v = v/10; - } - gwrite(buf+i, nelem(buf)-i); -} - -void -runtime_printint(int64 v) -{ - if(v < 0) { - gwrite("-", 1); - v = -v; - } - runtime_printuint(v); -} - -void -runtime_printhex(uint64 v) -{ - static const char *dig = "0123456789abcdef"; - byte buf[100]; - int32 i; - - i=nelem(buf); - for(; v>0; v/=16) - buf[--i] = dig[v%16]; - if(i == nelem(buf)) - buf[--i] = '0'; - buf[--i] = 'x'; - buf[--i] = '0'; - gwrite(buf+i, nelem(buf)-i); -} - -void -runtime_printpointer(void *p) -{ - runtime_printhex((uintptr)p); -} - -void -runtime_printstring(String v) -{ - // if(v.len > runtime_maxstring) { - // gwrite("[string too long]", 17); - // return; - // } - if(v.len > 0) - gwrite(v.str, v.len); -} - -void -__go_print_space(void) -{ - gwrite(" ", 1); -} - -void -__go_print_nl(void) -{ - gwrite("\n", 1); + runtime_printunlock(); } |