mirror of
https://github.com/golang/go
synced 2024-11-23 15:20:03 -07:00
runtime: convert print.c to Go
LGTM=iant R=golang-codereviews, iant CC=dvyukov, golang-codereviews, khr, r https://golang.org/cl/135930043
This commit is contained in:
parent
de7fea0d61
commit
597b266eaf
@ -29,7 +29,7 @@ runtime·memprint(uintptr s, void *a)
|
||||
v = *(uint64*)a;
|
||||
break;
|
||||
}
|
||||
runtime·printint_c(v);
|
||||
runtime·printint(v);
|
||||
}
|
||||
|
||||
void
|
||||
@ -126,7 +126,7 @@ void
|
||||
runtime·strprint(uintptr s, void *a)
|
||||
{
|
||||
USED(s);
|
||||
runtime·printstring_c(*(String*)a);
|
||||
runtime·printstring(*(String*)a);
|
||||
}
|
||||
|
||||
void
|
||||
@ -146,7 +146,7 @@ void
|
||||
runtime·interprint(uintptr s, void *a)
|
||||
{
|
||||
USED(s);
|
||||
runtime·printiface_c(*(Iface*)a);
|
||||
runtime·printiface(*(Iface*)a);
|
||||
}
|
||||
|
||||
void
|
||||
@ -166,7 +166,7 @@ void
|
||||
runtime·nilinterprint(uintptr s, void *a)
|
||||
{
|
||||
USED(s);
|
||||
runtime·printeface_c(*(Eface*)a);
|
||||
runtime·printeface(*(Eface*)a);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -162,16 +162,14 @@ func Stack(buf []byte, all bool) int {
|
||||
|
||||
n := 0
|
||||
if len(buf) > 0 {
|
||||
gp.writebuf = &buf[0]
|
||||
gp.writenbuf = int32(len(buf))
|
||||
gp.writebuf = buf
|
||||
goroutineheader(gp)
|
||||
traceback(pc, sp, 0, gp)
|
||||
if all {
|
||||
tracebackothers(gp)
|
||||
}
|
||||
n = len(buf) - int(gp.writenbuf)
|
||||
n = len(buf) - len(gp.writebuf)
|
||||
gp.writebuf = nil
|
||||
gp.writenbuf = 0
|
||||
}
|
||||
|
||||
if all {
|
||||
|
@ -150,7 +150,7 @@ macherror(int32 r, int8 *fn)
|
||||
runtime·prints("mach error ");
|
||||
runtime·prints(fn);
|
||||
runtime·prints(": ");
|
||||
runtime·printint_c(r);
|
||||
runtime·printint(r);
|
||||
runtime·prints("\n");
|
||||
runtime·throw("mach error");
|
||||
}
|
||||
@ -218,7 +218,7 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize)
|
||||
runtime·prints("send:\t");
|
||||
for(i=0; i<h->msgh_size/sizeof(p[0]); i++){
|
||||
runtime·prints(" ");
|
||||
runtime·printpointer_c((void*)p[i]);
|
||||
runtime·printpointer((void*)p[i]);
|
||||
if(i%8 == 7)
|
||||
runtime·prints("\n\t");
|
||||
}
|
||||
@ -231,7 +231,7 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize)
|
||||
if(ret != 0){
|
||||
if(DebugMach){
|
||||
runtime·prints("mach_msg error ");
|
||||
runtime·printint_c(ret);
|
||||
runtime·printint(ret);
|
||||
runtime·prints("\n");
|
||||
}
|
||||
return ret;
|
||||
@ -242,7 +242,7 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize)
|
||||
runtime·prints("recv:\t");
|
||||
for(i=0; i<h->msgh_size/sizeof(p[0]); i++){
|
||||
runtime·prints(" ");
|
||||
runtime·printpointer_c((void*)p[i]);
|
||||
runtime·printpointer((void*)p[i]);
|
||||
if(i%8 == 7)
|
||||
runtime·prints("\n\t");
|
||||
}
|
||||
@ -253,9 +253,9 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize)
|
||||
if(h->msgh_id != id+Reply){
|
||||
if(DebugMach){
|
||||
runtime·prints("mach_msg reply id mismatch ");
|
||||
runtime·printint_c(h->msgh_id);
|
||||
runtime·printint(h->msgh_id);
|
||||
runtime·prints(" != ");
|
||||
runtime·printint_c(id+Reply);
|
||||
runtime·printint(id+Reply);
|
||||
runtime·prints("\n");
|
||||
}
|
||||
return -303; // MIG_REPLY_MISMATCH
|
||||
@ -272,7 +272,7 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize)
|
||||
&& !(h->msgh_bits & MACH_MSGH_BITS_COMPLEX)){
|
||||
if(DebugMach){
|
||||
runtime·prints("mig result ");
|
||||
runtime·printint_c(c->code);
|
||||
runtime·printint(c->code);
|
||||
runtime·prints("\n");
|
||||
}
|
||||
return c->code;
|
||||
@ -281,9 +281,9 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize)
|
||||
if(h->msgh_size != rxsize){
|
||||
if(DebugMach){
|
||||
runtime·prints("mach_msg reply size mismatch ");
|
||||
runtime·printint_c(h->msgh_size);
|
||||
runtime·printint(h->msgh_size);
|
||||
runtime·prints(" != ");
|
||||
runtime·printint_c(rxsize);
|
||||
runtime·printint(rxsize);
|
||||
runtime·prints("\n");
|
||||
}
|
||||
return -307; // MIG_ARRAY_TOO_LARGE
|
||||
|
@ -63,11 +63,11 @@ runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
|
||||
return;
|
||||
|
||||
runtime·prints("umtx_wait addr=");
|
||||
runtime·printpointer_c(addr);
|
||||
runtime·printpointer(addr);
|
||||
runtime·prints(" val=");
|
||||
runtime·printint_c(val);
|
||||
runtime·printint(val);
|
||||
runtime·prints(" ret=");
|
||||
runtime·printint_c(ret);
|
||||
runtime·printint(ret);
|
||||
runtime·prints("\n");
|
||||
*(int32*)0x1005 = 0x1005;
|
||||
}
|
||||
|
@ -64,11 +64,11 @@ runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
|
||||
|
||||
fail:
|
||||
runtime·prints("umtx_wait addr=");
|
||||
runtime·printpointer_c(addr);
|
||||
runtime·printpointer(addr);
|
||||
runtime·prints(" val=");
|
||||
runtime·printint_c(val);
|
||||
runtime·printint(val);
|
||||
runtime·prints(" ret=");
|
||||
runtime·printint_c(ret);
|
||||
runtime·printint(ret);
|
||||
runtime·prints("\n");
|
||||
*(int32*)0x1005 = 0x1005;
|
||||
}
|
||||
|
@ -390,8 +390,11 @@ runtime·startpanic(void)
|
||||
switch(g->m->dying) {
|
||||
case 0:
|
||||
g->m->dying = 1;
|
||||
if(g != nil)
|
||||
g->writebuf = nil;
|
||||
if(g != nil) {
|
||||
g->writebuf.array = nil;
|
||||
g->writebuf.len = 0;
|
||||
g->writebuf.cap = 0;
|
||||
}
|
||||
runtime·xadd(&runtime·panicking, 1);
|
||||
runtime·lock(&paniclk);
|
||||
if(runtime·debug.schedtrace > 0 || runtime·debug.scheddetail > 0)
|
||||
|
@ -1,443 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "runtime.h"
|
||||
#include "type.h"
|
||||
#include "../../cmd/ld/textflag.h"
|
||||
|
||||
//static Mutex debuglock;
|
||||
|
||||
static void vprintf(int8*, byte*);
|
||||
|
||||
// write to goroutine-local buffer if diverting output,
|
||||
// or else standard error.
|
||||
static void
|
||||
gwrite(void *v, intgo n)
|
||||
{
|
||||
if(g == nil || g->writebuf == nil) {
|
||||
runtime·write(2, v, n);
|
||||
return;
|
||||
}
|
||||
|
||||
if(g->writenbuf == 0)
|
||||
return;
|
||||
|
||||
if(n > g->writenbuf)
|
||||
n = g->writenbuf;
|
||||
runtime·memmove(g->writebuf, v, n);
|
||||
g->writebuf += n;
|
||||
g->writenbuf -= n;
|
||||
}
|
||||
|
||||
void
|
||||
runtime·dump(byte *p, int32 n)
|
||||
{
|
||||
int32 i;
|
||||
|
||||
for(i=0; i<n; i++) {
|
||||
runtime·printpointer_c((byte*)(p[i]>>4));
|
||||
runtime·printpointer_c((byte*)(p[i]&0xf));
|
||||
if((i&15) == 15)
|
||||
runtime·prints("\n");
|
||||
else
|
||||
runtime·prints(" ");
|
||||
}
|
||||
if(n & 15)
|
||||
runtime·prints("\n");
|
||||
}
|
||||
|
||||
void
|
||||
runtime·prints(int8 *s)
|
||||
{
|
||||
gwrite(s, runtime·findnull((byte*)s));
|
||||
}
|
||||
|
||||
#pragma textflag NOSPLIT
|
||||
void
|
||||
runtime·printf(int8 *s, ...)
|
||||
{
|
||||
byte *arg;
|
||||
|
||||
arg = (byte*)(&s+1);
|
||||
vprintf(s, arg);
|
||||
}
|
||||
|
||||
#pragma textflag NOSPLIT
|
||||
int32
|
||||
runtime·snprintf(byte *buf, int32 n, int8 *s, ...)
|
||||
{
|
||||
byte *arg;
|
||||
int32 m;
|
||||
|
||||
arg = (byte*)(&s+1);
|
||||
g->writebuf = buf;
|
||||
g->writenbuf = n-1;
|
||||
vprintf(s, arg);
|
||||
*g->writebuf = '\0';
|
||||
m = g->writebuf - buf;
|
||||
g->writenbuf = 0;
|
||||
g->writebuf = nil;
|
||||
return m;
|
||||
}
|
||||
|
||||
// Very simple printf. Only for debugging prints.
|
||||
// Do not add to this without checking with Rob.
|
||||
static void
|
||||
vprintf(int8 *s, byte *base)
|
||||
{
|
||||
int8 *p, *lp;
|
||||
uintptr arg, siz;
|
||||
byte *v;
|
||||
|
||||
//runtime·lock(&debuglock);
|
||||
|
||||
lp = p = s;
|
||||
arg = (uintptr)base;
|
||||
for(; *p; p++) {
|
||||
if(*p != '%')
|
||||
continue;
|
||||
if(p > lp)
|
||||
gwrite(lp, p-lp);
|
||||
p++;
|
||||
siz = 0;
|
||||
switch(*p) {
|
||||
case 't':
|
||||
case 'c':
|
||||
siz = 1;
|
||||
break;
|
||||
case 'd': // 32-bit
|
||||
case 'x':
|
||||
arg = ROUND(arg, 4);
|
||||
siz = 4;
|
||||
break;
|
||||
case 'D': // 64-bit
|
||||
case 'U':
|
||||
case 'X':
|
||||
case 'f':
|
||||
arg = ROUND(arg, sizeof(uintreg));
|
||||
siz = 8;
|
||||
break;
|
||||
case 'C':
|
||||
arg = ROUND(arg, sizeof(uintreg));
|
||||
siz = 16;
|
||||
break;
|
||||
case 'p': // pointer-sized
|
||||
case 's':
|
||||
arg = ROUND(arg, sizeof(uintptr));
|
||||
siz = sizeof(uintptr);
|
||||
break;
|
||||
case 'S': // pointer-aligned but bigger
|
||||
arg = ROUND(arg, sizeof(uintptr));
|
||||
siz = sizeof(String);
|
||||
break;
|
||||
case 'a': // pointer-aligned but bigger
|
||||
arg = ROUND(arg, sizeof(uintptr));
|
||||
siz = sizeof(Slice);
|
||||
break;
|
||||
case 'i': // pointer-aligned but bigger
|
||||
case 'e':
|
||||
arg = ROUND(arg, sizeof(uintptr));
|
||||
siz = sizeof(Eface);
|
||||
break;
|
||||
}
|
||||
v = (byte*)arg;
|
||||
switch(*p) {
|
||||
case 'a':
|
||||
runtime·printslice_c(*(Slice*)v);
|
||||
break;
|
||||
case 'c':
|
||||
runtime·printbyte_c(*(int8*)v);
|
||||
break;
|
||||
case 'd':
|
||||
runtime·printint_c(*(int32*)v);
|
||||
break;
|
||||
case 'D':
|
||||
runtime·printint_c(*(int64*)v);
|
||||
break;
|
||||
case 'e':
|
||||
runtime·printeface_c(*(Eface*)v);
|
||||
break;
|
||||
case 'f':
|
||||
runtime·printfloat_c(*(float64*)v);
|
||||
break;
|
||||
case 'C':
|
||||
runtime·printcomplex_c(*(Complex128*)v);
|
||||
break;
|
||||
case 'i':
|
||||
runtime·printiface_c(*(Iface*)v);
|
||||
break;
|
||||
case 'p':
|
||||
runtime·printpointer_c(*(void**)v);
|
||||
break;
|
||||
case 's':
|
||||
runtime·prints(*(int8**)v);
|
||||
break;
|
||||
case 'S':
|
||||
runtime·printstring_c(*(String*)v);
|
||||
break;
|
||||
case 't':
|
||||
runtime·printbool_c(*(bool*)v);
|
||||
break;
|
||||
case 'U':
|
||||
runtime·printuint_c(*(uint64*)v);
|
||||
break;
|
||||
case 'x':
|
||||
runtime·printhex_c(*(uint32*)v);
|
||||
break;
|
||||
case 'X':
|
||||
runtime·printhex_c(*(uint64*)v);
|
||||
break;
|
||||
}
|
||||
arg += siz;
|
||||
lp = p+1;
|
||||
}
|
||||
if(p > lp)
|
||||
gwrite(lp, p-lp);
|
||||
|
||||
//runtime·unlock(&debuglock);
|
||||
}
|
||||
|
||||
static void
|
||||
goprintf_m(void)
|
||||
{
|
||||
// Can assume s has terminating NUL because only
|
||||
// the Go compiler generates calls to runtime·goprintf, using
|
||||
// string constants, and all the string constants have NULs.
|
||||
vprintf(g->m->ptrarg[0], g->m->ptrarg[1]);
|
||||
g->m->ptrarg[0] = nil;
|
||||
g->m->ptrarg[1] = nil;
|
||||
}
|
||||
|
||||
#pragma textflag NOSPLIT
|
||||
void
|
||||
runtime·goprintf(String s, ...)
|
||||
{
|
||||
g->m->ptrarg[0] = s.str;
|
||||
g->m->ptrarg[1] = (byte*)(&s+1);
|
||||
runtime·onM(goprintf_m);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·printpc_c(void *p)
|
||||
{
|
||||
runtime·prints("PC=");
|
||||
runtime·printhex_c((uint64)runtime·getcallerpc(p));
|
||||
}
|
||||
|
||||
void
|
||||
runtime·printbool_c(bool v)
|
||||
{
|
||||
if(v) {
|
||||
gwrite((byte*)"true", 4);
|
||||
return;
|
||||
}
|
||||
gwrite((byte*)"false", 5);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·printbyte_c(int8 c)
|
||||
{
|
||||
gwrite(&c, 1);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·printfloat_c(float64 v)
|
||||
{
|
||||
byte buf[20];
|
||||
int32 e, s, i, n;
|
||||
float64 h;
|
||||
|
||||
if(ISNAN(v)) {
|
||||
gwrite("NaN", 3);
|
||||
return;
|
||||
}
|
||||
if(v == runtime·posinf) {
|
||||
gwrite("+Inf", 4);
|
||||
return;
|
||||
}
|
||||
if(v == runtime·neginf) {
|
||||
gwrite("-Inf", 4);
|
||||
return;
|
||||
}
|
||||
|
||||
n = 7; // digits printed
|
||||
e = 0; // exp
|
||||
s = 0; // sign
|
||||
if(v == 0) {
|
||||
if(1/v == runtime·neginf)
|
||||
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_c(Complex128 v)
|
||||
{
|
||||
gwrite("(", 1);
|
||||
runtime·printfloat_c(v.real);
|
||||
runtime·printfloat_c(v.imag);
|
||||
gwrite("i)", 2);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·printuint_c(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_c(int64 v)
|
||||
{
|
||||
if(v < 0) {
|
||||
gwrite("-", 1);
|
||||
v = -v;
|
||||
}
|
||||
runtime·printuint_c(v);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·printhex_c(uint64 v)
|
||||
{
|
||||
static int8 *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_c(void *p)
|
||||
{
|
||||
runtime·printhex_c((uintptr)p);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·printstring_c(String v)
|
||||
{
|
||||
if(v.len > runtime·maxstring) {
|
||||
gwrite("[string too long]", 17);
|
||||
return;
|
||||
}
|
||||
if(v.len > 0)
|
||||
gwrite(v.str, v.len);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·printslice_c(Slice s)
|
||||
{
|
||||
runtime·prints("[");
|
||||
runtime·printint_c(s.len);
|
||||
runtime·prints("/");
|
||||
runtime·printint_c(s.cap);
|
||||
runtime·prints("]");
|
||||
runtime·printpointer_c(s.array);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·printeface_c(Eface e)
|
||||
{
|
||||
runtime·printf("(%p,%p)", e.type, e.data);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·printiface_c(Iface i)
|
||||
{
|
||||
runtime·printf("(%p,%p)", i.tab, i.data);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·printstring_m(void)
|
||||
{
|
||||
String s;
|
||||
|
||||
s.str = g->m->ptrarg[0];
|
||||
g->m->ptrarg[0] = nil;
|
||||
s.len = g->m->scalararg[0];
|
||||
runtime·printstring_c(s);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·printuint_m(void)
|
||||
{
|
||||
runtime·printuint_c(*(uint64*)(&g->m->scalararg[0]));
|
||||
}
|
||||
|
||||
void
|
||||
runtime·printhex_m(void)
|
||||
{
|
||||
runtime·printhex_c(g->m->scalararg[0]);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·printfloat_m(void)
|
||||
{
|
||||
runtime·printfloat_c(*(float64*)(&g->m->scalararg[0]));
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// these 4 functions are complicated enough that we will share
|
||||
// the print logic with the C printf.
|
||||
var (
|
||||
printstring_m,
|
||||
printuint_m,
|
||||
printhex_m,
|
||||
printfloat_m mFunction
|
||||
)
|
||||
|
||||
func printstring(s string) {
|
||||
mp := acquirem()
|
||||
mp.scalararg[0] = uintptr(len(s))
|
||||
mp.ptrarg[0] = (*stringStruct)(unsafe.Pointer(&s)).str
|
||||
onM(&printstring_m)
|
||||
releasem(mp)
|
||||
}
|
||||
|
||||
func printuint(x uint64) {
|
||||
mp := acquirem()
|
||||
*(*uint64)(unsafe.Pointer(&mp.scalararg[0])) = x
|
||||
onM(&printuint_m)
|
||||
releasem(mp)
|
||||
}
|
||||
|
||||
func printhex(x uintptr) {
|
||||
mp := acquirem()
|
||||
mp.scalararg[0] = uintptr(x)
|
||||
onM(&printhex_m)
|
||||
releasem(mp)
|
||||
}
|
||||
|
||||
func printfloat(x float64) {
|
||||
mp := acquirem()
|
||||
*(*float64)(unsafe.Pointer(&mp.scalararg[0])) = x
|
||||
onM(&printfloat_m)
|
||||
releasem(mp)
|
||||
}
|
||||
|
||||
// all other print functions are expressible as combinations
|
||||
// of the above 4 functions.
|
||||
func printnl() {
|
||||
printstring("\n")
|
||||
}
|
||||
|
||||
func printsp() {
|
||||
printstring(" ")
|
||||
}
|
||||
|
||||
func printbool(b bool) {
|
||||
if b {
|
||||
printstring("true")
|
||||
} else {
|
||||
printstring("false")
|
||||
}
|
||||
}
|
||||
|
||||
func printpointer(p unsafe.Pointer) {
|
||||
printhex(uintptr(p))
|
||||
}
|
||||
|
||||
func printint(x int64) {
|
||||
if x < 0 {
|
||||
printstring("-")
|
||||
x = -x
|
||||
}
|
||||
printuint(uint64(x))
|
||||
}
|
||||
|
||||
func printcomplex(x complex128) {
|
||||
printstring("(")
|
||||
printfloat(real(x))
|
||||
printfloat(imag(x))
|
||||
printstring("i)")
|
||||
}
|
||||
|
||||
func printiface(i interface {
|
||||
f()
|
||||
}) {
|
||||
printstring("(")
|
||||
printhex((*[2]uintptr)(unsafe.Pointer(&i))[0])
|
||||
printstring(",")
|
||||
printhex((*[2]uintptr)(unsafe.Pointer(&i))[1])
|
||||
printstring(")")
|
||||
}
|
||||
|
||||
func printeface(e interface{}) {
|
||||
printstring("(")
|
||||
printhex((*[2]uintptr)(unsafe.Pointer(&e))[0])
|
||||
printstring(",")
|
||||
printhex((*[2]uintptr)(unsafe.Pointer(&e))[1])
|
||||
printstring(")")
|
||||
}
|
||||
|
||||
func printslice(b []byte) {
|
||||
printstring("[")
|
||||
printint(int64(len(b)))
|
||||
printstring("/")
|
||||
printint(int64(cap(b)))
|
||||
printstring("]")
|
||||
printhex((*[3]uintptr)(unsafe.Pointer(&b))[0])
|
||||
}
|
338
src/pkg/runtime/print1.go
Normal file
338
src/pkg/runtime/print1.go
Normal file
@ -0,0 +1,338 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:noescape
|
||||
func gostring(*byte) string
|
||||
|
||||
func bytes(s string) (ret []byte) {
|
||||
rp := (*slice)(unsafe.Pointer(&ret))
|
||||
sp := (*_string)(noescape(unsafe.Pointer(&s)))
|
||||
rp.array = sp.str
|
||||
rp.len = uint(sp.len)
|
||||
rp.cap = uint(sp.len)
|
||||
return
|
||||
}
|
||||
|
||||
// goprintf is the function call that is actually deferred when you write
|
||||
// defer print(...)
|
||||
// It is otherwise unused. In particular it is not used for ordinary prints.
|
||||
// Right now a dynamically allocated string that is being passed as an
|
||||
// argument is invisible to the garbage collector and might be collected
|
||||
// if that argument list is the only reference. For now we ignore that possibility.
|
||||
// To fix, we should change to defer a call to vprintf with a pointer to
|
||||
// an argument list on the stack, stored in an appropriately typed
|
||||
// struct. golang.org/issue/8614.
|
||||
//go:nosplit
|
||||
func goprintf(s string) {
|
||||
vprintf(s, add(unsafe.Pointer(&s), unsafe.Sizeof(s)))
|
||||
}
|
||||
|
||||
// printf is only called from C code. It has the same problem as goprintf
|
||||
// with strings possibly being collected from underneath.
|
||||
// However, the runtime never prints dynamically allocated
|
||||
// Go strings using printf. The strings it prints come from the symbol
|
||||
// and type tables.
|
||||
//go:nosplit
|
||||
func printf(s *byte) {
|
||||
vprintf(gostring(s), add(unsafe.Pointer(&s), unsafe.Sizeof(s)))
|
||||
}
|
||||
|
||||
// sprintf is only called from C code.
|
||||
// It has the same problem as goprintf.
|
||||
//go:nosplit
|
||||
func snprintf(dst *byte, n int32, s *byte) {
|
||||
buf := (*[1 << 30]byte)(unsafe.Pointer(dst))[0:0:n]
|
||||
|
||||
gp := getg()
|
||||
gp.writebuf = buf[0:0 : n-1] // leave room for NUL, this is called from C
|
||||
vprintf(gostring(s), add(unsafe.Pointer(&s), unsafe.Sizeof(s)))
|
||||
buf[len(gp.writebuf)] = '\x00'
|
||||
gp.writebuf = nil
|
||||
}
|
||||
|
||||
//var debuglock mutex
|
||||
|
||||
// write to goroutine-local buffer if diverting output,
|
||||
// or else standard error.
|
||||
func gwrite(b []byte) {
|
||||
if len(b) == 0 {
|
||||
return
|
||||
}
|
||||
gp := getg()
|
||||
if gp == nil || gp.writebuf == nil {
|
||||
write(2, unsafe.Pointer(&b[0]), int32(len(b)))
|
||||
return
|
||||
}
|
||||
|
||||
n := copy(gp.writebuf[len(gp.writebuf):cap(gp.writebuf)], b)
|
||||
gp.writebuf = gp.writebuf[:len(gp.writebuf)+n]
|
||||
}
|
||||
|
||||
func prints(s *byte) {
|
||||
b := (*[1 << 30]byte)(unsafe.Pointer(s))
|
||||
for i := 0; ; i++ {
|
||||
if b[i] == 0 {
|
||||
gwrite(b[:i])
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func printsp() {
|
||||
print(" ")
|
||||
}
|
||||
|
||||
func printnl() {
|
||||
print("\n")
|
||||
}
|
||||
|
||||
// Very simple printf. Only for debugging prints.
|
||||
// Do not add to this without checking with Rob.
|
||||
func vprintf(str string, arg unsafe.Pointer) {
|
||||
//lock(&debuglock);
|
||||
|
||||
s := bytes(str)
|
||||
start := 0
|
||||
i := 0
|
||||
for ; i < len(s); i++ {
|
||||
if s[i] != '%' {
|
||||
continue
|
||||
}
|
||||
if i > start {
|
||||
gwrite(s[start:i])
|
||||
}
|
||||
if i++; i >= len(s) {
|
||||
break
|
||||
}
|
||||
var siz uintptr
|
||||
switch s[i] {
|
||||
case 't', 'c':
|
||||
siz = 1
|
||||
case 'd', 'x': // 32-bit
|
||||
arg = roundup(arg, 4)
|
||||
siz = 4
|
||||
case 'D', 'U', 'X', 'f': // 64-bit
|
||||
arg = roundup(arg, unsafe.Sizeof(uintreg(0)))
|
||||
siz = 8
|
||||
case 'C':
|
||||
arg = roundup(arg, unsafe.Sizeof(uintreg(0)))
|
||||
siz = 16
|
||||
case 'p', 's': // pointer-sized
|
||||
arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
|
||||
siz = unsafe.Sizeof(uintptr(0))
|
||||
case 'S': // pointer-aligned but bigger
|
||||
arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
|
||||
siz = unsafe.Sizeof(string(""))
|
||||
case 'a': // pointer-aligned but bigger
|
||||
arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
|
||||
siz = unsafe.Sizeof([]byte{})
|
||||
case 'i', 'e': // pointer-aligned but bigger
|
||||
arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
|
||||
siz = unsafe.Sizeof(interface{}(nil))
|
||||
}
|
||||
switch s[i] {
|
||||
case 'a':
|
||||
printslice(*(*[]byte)(arg))
|
||||
case 'c':
|
||||
printbyte(*(*byte)(arg))
|
||||
case 'd':
|
||||
printint(int64(*(*int32)(arg)))
|
||||
case 'D':
|
||||
printint(int64(*(*int64)(arg)))
|
||||
case 'e':
|
||||
printeface(*(*interface{})(arg))
|
||||
case 'f':
|
||||
printfloat(*(*float64)(arg))
|
||||
case 'C':
|
||||
printcomplex(*(*complex128)(arg))
|
||||
case 'i':
|
||||
printiface(*(*fInterface)(arg))
|
||||
case 'p':
|
||||
printpointer(*(*unsafe.Pointer)(arg))
|
||||
case 's':
|
||||
prints(*(**byte)(arg))
|
||||
case 'S':
|
||||
printstring(*(*string)(arg))
|
||||
case 't':
|
||||
printbool(*(*bool)(arg))
|
||||
case 'U':
|
||||
printuint(*(*uint64)(arg))
|
||||
case 'x':
|
||||
printhex(uint64(*(*uint32)(arg)))
|
||||
case 'X':
|
||||
printhex(*(*uint64)(arg))
|
||||
}
|
||||
arg = add(arg, siz)
|
||||
start = i + 1
|
||||
}
|
||||
if start < i {
|
||||
gwrite(s[start:i])
|
||||
}
|
||||
|
||||
//unlock(&debuglock);
|
||||
}
|
||||
|
||||
func printpc(p unsafe.Pointer) {
|
||||
print("PC=")
|
||||
printhex(uint64(getcallerpc(p)))
|
||||
}
|
||||
|
||||
func printbool(v bool) {
|
||||
if v {
|
||||
print("true")
|
||||
} else {
|
||||
print("false")
|
||||
}
|
||||
}
|
||||
|
||||
func printbyte(c byte) {
|
||||
gwrite((*[1]byte)(unsafe.Pointer(&c))[:])
|
||||
}
|
||||
|
||||
func printfloat(v float64) {
|
||||
switch {
|
||||
case v != v:
|
||||
print("NaN")
|
||||
return
|
||||
case v+v == v && v > 0:
|
||||
print("+Inf")
|
||||
return
|
||||
case v+v == v && v < 0:
|
||||
print("-Inf")
|
||||
return
|
||||
}
|
||||
|
||||
const n = 7 // digits printed
|
||||
var buf [n + 7]byte
|
||||
buf[0] = '+'
|
||||
e := 0 // exp
|
||||
if v == 0 {
|
||||
if 1/v < 0 {
|
||||
buf[0] = '-'
|
||||
}
|
||||
} else {
|
||||
if v < 0 {
|
||||
v = -v
|
||||
buf[0] = '-'
|
||||
}
|
||||
|
||||
// normalize
|
||||
for v >= 10 {
|
||||
e++
|
||||
v /= 10
|
||||
}
|
||||
for v < 1 {
|
||||
e--
|
||||
v *= 10
|
||||
}
|
||||
|
||||
// round
|
||||
h := 5.0
|
||||
for i := 0; i < n; i++ {
|
||||
h /= 10
|
||||
}
|
||||
v += h
|
||||
if v >= 10 {
|
||||
e++
|
||||
v /= 10
|
||||
}
|
||||
}
|
||||
|
||||
// format +d.dddd+edd
|
||||
for i := 0; i < n; i++ {
|
||||
s := int(v)
|
||||
buf[i+2] = byte(s + '0')
|
||||
v -= float64(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] = byte(e/100) + '0'
|
||||
buf[n+5] = byte(e/10)%10 + '0'
|
||||
buf[n+6] = byte(e%10) + '0'
|
||||
gwrite(buf[:])
|
||||
}
|
||||
|
||||
func printcomplex(c complex128) {
|
||||
print("(", real(c), imag(c), "i)")
|
||||
}
|
||||
|
||||
func printuint(v uint64) {
|
||||
var buf [100]byte
|
||||
i := len(buf)
|
||||
for i--; i > 0; i-- {
|
||||
buf[i] = byte(v%10 + '0')
|
||||
if v < 10 {
|
||||
break
|
||||
}
|
||||
v /= 10
|
||||
}
|
||||
gwrite(buf[i:])
|
||||
}
|
||||
|
||||
func printint(v int64) {
|
||||
if v < 0 {
|
||||
print("-")
|
||||
v = -v
|
||||
}
|
||||
printuint(uint64(v))
|
||||
}
|
||||
|
||||
func printhex(v uint64) {
|
||||
const dig = "0123456789abcdef"
|
||||
var buf [100]byte
|
||||
i := len(buf)
|
||||
for i--; i > 0; i-- {
|
||||
buf[i] = dig[v%16]
|
||||
if v < 16 {
|
||||
break
|
||||
}
|
||||
v /= 16
|
||||
}
|
||||
i--
|
||||
buf[i] = 'x'
|
||||
i--
|
||||
buf[i] = '0'
|
||||
gwrite(buf[i:])
|
||||
}
|
||||
|
||||
func printpointer(p unsafe.Pointer) {
|
||||
printhex(uint64(uintptr(p)))
|
||||
}
|
||||
|
||||
func printstring(s string) {
|
||||
if uintptr(len(s)) > maxstring {
|
||||
gwrite(bytes("[string too long]"))
|
||||
return
|
||||
}
|
||||
gwrite(bytes(s))
|
||||
}
|
||||
|
||||
func printslice(s []byte) {
|
||||
sp := (*slice)(unsafe.Pointer(&s))
|
||||
print("[", len(s), "/", cap(s), "]")
|
||||
printpointer(unsafe.Pointer(sp.array))
|
||||
}
|
||||
|
||||
func printeface(e interface{}) {
|
||||
ep := (*eface)(unsafe.Pointer(&e))
|
||||
print("(", ep._type, ",", ep.data, ")")
|
||||
}
|
||||
|
||||
func printiface(i fInterface) {
|
||||
ip := (*iface)(unsafe.Pointer(&i))
|
||||
print("(", ip.tab, ",", ip.data, ")")
|
||||
}
|
@ -1648,8 +1648,9 @@ goexit0(G *gp)
|
||||
gp->paniconfault = 0;
|
||||
gp->defer = nil; // should be true already but just in case.
|
||||
gp->panic = nil; // non-nil for Goexit during panic. points at stack-allocated data.
|
||||
gp->writenbuf = 0;
|
||||
gp->writebuf = nil;
|
||||
gp->writebuf.array = nil;
|
||||
gp->writebuf.len = 0;
|
||||
gp->writebuf.cap = 0;
|
||||
gp->waitreason.str = nil;
|
||||
gp->waitreason.len = 0;
|
||||
gp->param = nil;
|
||||
|
@ -297,7 +297,7 @@ struct G
|
||||
M* lockedm;
|
||||
int32 sig;
|
||||
int32 writenbuf;
|
||||
byte* writebuf;
|
||||
Slice writebuf;
|
||||
uintptr sigcode0;
|
||||
uintptr sigcode1;
|
||||
uintptr sigpc;
|
||||
@ -828,7 +828,7 @@ void runtime·panicstring(int8*);
|
||||
bool runtime·canpanic(G*);
|
||||
void runtime·prints(int8*);
|
||||
void runtime·printf(int8*, ...);
|
||||
int32 runtime·snprintf(byte*, int32, int8*, ...);
|
||||
void runtime·snprintf(byte*, int32, int8*, ...);
|
||||
byte* runtime·mchr(byte*, byte, byte*);
|
||||
int32 runtime·mcmp(byte*, byte*, uintptr);
|
||||
void runtime·memmove(void*, void*, uintptr);
|
||||
@ -1063,19 +1063,19 @@ void runtime·madvise(byte*, uintptr, int32);
|
||||
void runtime·memclr(byte*, uintptr);
|
||||
void runtime·setcallerpc(void*, void*);
|
||||
void* runtime·getcallerpc(void*);
|
||||
void runtime·printbool_c(bool);
|
||||
void runtime·printbyte_c(int8);
|
||||
void runtime·printfloat_c(float64);
|
||||
void runtime·printint_c(int64);
|
||||
void runtime·printiface_c(Iface);
|
||||
void runtime·printeface_c(Eface);
|
||||
void runtime·printstring_c(String);
|
||||
void runtime·printpc_c(void*);
|
||||
void runtime·printpointer_c(void*);
|
||||
void runtime·printuint_c(uint64);
|
||||
void runtime·printhex_c(uint64);
|
||||
void runtime·printslice_c(Slice);
|
||||
void runtime·printcomplex_c(Complex128);
|
||||
void runtime·printbool(bool);
|
||||
void runtime·printbyte(int8);
|
||||
void runtime·printfloat(float64);
|
||||
void runtime·printint(int64);
|
||||
void runtime·printiface(Iface);
|
||||
void runtime·printeface(Eface);
|
||||
void runtime·printstring(String);
|
||||
void runtime·printpc(void*);
|
||||
void runtime·printpointer(void*);
|
||||
void runtime·printuint(uint64);
|
||||
void runtime·printhex(uint64);
|
||||
void runtime·printslice(Slice);
|
||||
void runtime·printcomplex(Complex128);
|
||||
|
||||
/*
|
||||
* runtime go-called
|
||||
|
@ -173,7 +173,6 @@ func gogo(buf *gobuf)
|
||||
func gosave(buf *gobuf)
|
||||
func open(name *byte, mode, perm int32) int32
|
||||
func read(fd int32, p unsafe.Pointer, n int32) int32
|
||||
func write(fd uintptr, p unsafe.Pointer, n int32) int32
|
||||
func close(fd int32) int32
|
||||
func mincore(addr unsafe.Pointer, n uintptr, dst *byte) int32
|
||||
func jmpdefer(fv *funcval, argp unsafe.Pointer)
|
||||
@ -205,6 +204,9 @@ func lock(lk *mutex)
|
||||
func unlock(lk *mutex)
|
||||
func purgecachedstats(c *mcache)
|
||||
|
||||
//go:noescape
|
||||
func write(fd uintptr, p unsafe.Pointer, n int32) int32
|
||||
|
||||
//go:noescape
|
||||
func cas(ptr *uint32, old, new uint32) bool
|
||||
|
||||
|
@ -234,7 +234,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip,
|
||||
}
|
||||
if(i != 0)
|
||||
runtime·prints(", ");
|
||||
runtime·printhex_c(((uintptr*)frame.argp)[i]);
|
||||
runtime·printhex(((uintptr*)frame.argp)[i]);
|
||||
}
|
||||
runtime·prints(")\n");
|
||||
line = runtime·funcline(f, tracepc, &file);
|
||||
|
@ -270,7 +270,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip,
|
||||
}
|
||||
if(i != 0)
|
||||
runtime·prints(", ");
|
||||
runtime·printhex_c(((uintptr*)frame.argp)[i]);
|
||||
runtime·printhex(((uintptr*)frame.argp)[i]);
|
||||
}
|
||||
runtime·prints(")\n");
|
||||
line = runtime·funcline(f, tracepc, &file);
|
||||
|
Loading…
Reference in New Issue
Block a user