aboutsummaryrefslogtreecommitdiff
path: root/libgo/runtime/print.c
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2016-10-10 23:13:39 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2016-10-10 23:13:39 +0000
commit65180edc5661b1324a53ac9ebbe03f44cda524e4 (patch)
tree661f2ef36aee0c3ee5866edd2bcf540260a98506 /libgo/runtime/print.c
parent73f01cca846d729848e793689389bcaa0dec3045 (diff)
downloadgcc-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.c301
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();
}