Commit 721c8735 authored by Keith Randall's avatar Keith Randall

runtime: move built-in print routines to go.

Fixes #8297

LGTM=bradfitz
R=golang-codereviews, bradfitz, khr, dave, dvyukov
CC=golang-codereviews
https://golang.org/cl/119240043
parent 53304558
...@@ -66,7 +66,7 @@ runtime·memprint(uintptr s, void *a) ...@@ -66,7 +66,7 @@ runtime·memprint(uintptr s, void *a)
v = *(uint64*)a; v = *(uint64*)a;
break; break;
} }
runtime·printint(v); runtime·printint_c(v);
} }
void void
...@@ -332,7 +332,7 @@ void ...@@ -332,7 +332,7 @@ void
runtime·strprint(uintptr s, void *a) runtime·strprint(uintptr s, void *a)
{ {
USED(s); USED(s);
runtime·printstring(*(String*)a); runtime·printstring_c(*(String*)a);
} }
void void
...@@ -359,7 +359,7 @@ void ...@@ -359,7 +359,7 @@ void
runtime·interprint(uintptr s, void *a) runtime·interprint(uintptr s, void *a)
{ {
USED(s); USED(s);
runtime·printiface(*(Iface*)a); runtime·printiface_c(*(Iface*)a);
} }
void void
...@@ -393,7 +393,7 @@ void ...@@ -393,7 +393,7 @@ void
runtime·nilinterprint(uintptr s, void *a) runtime·nilinterprint(uintptr s, void *a)
{ {
USED(s); USED(s);
runtime·printeface(*(Eface*)a); runtime·printeface_c(*(Eface*)a);
} }
void void
......
...@@ -258,3 +258,27 @@ func BenchmarkAllocation(b *testing.B) { ...@@ -258,3 +258,27 @@ func BenchmarkAllocation(b *testing.B) {
<-result <-result
} }
} }
func TestPrintGC(t *testing.T) {
if testing.Short() {
t.Skip("Skipping in short mode")
}
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2))
done := make(chan bool)
go func() {
for {
select {
case <-done:
return
default:
runtime.GC()
}
}
}()
for i := 0; i < 1e4; i++ {
func() {
defer print("")
}()
}
close(done)
}
...@@ -10,14 +10,6 @@ package runtime ...@@ -10,14 +10,6 @@ package runtime
#include "malloc.h" #include "malloc.h"
#include "../../cmd/ld/textflag.h" #include "../../cmd/ld/textflag.h"
func printiface(i Iface) {
runtime·printf("(%p,%p)", i.tab, i.data);
}
func printeface(e Eface) {
runtime·printf("(%p,%p)", e.type, e.data);
}
static Itab* hash[1009]; static Itab* hash[1009];
static Lock ifacelock; static Lock ifacelock;
......
...@@ -150,7 +150,7 @@ macherror(int32 r, int8 *fn) ...@@ -150,7 +150,7 @@ macherror(int32 r, int8 *fn)
runtime·prints("mach error "); runtime·prints("mach error ");
runtime·prints(fn); runtime·prints(fn);
runtime·prints(": "); runtime·prints(": ");
runtime·printint(r); runtime·printint_c(r);
runtime·prints("\n"); runtime·prints("\n");
runtime·throw("mach error"); runtime·throw("mach error");
} }
...@@ -218,7 +218,7 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize) ...@@ -218,7 +218,7 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize)
runtime·prints("send:\t"); runtime·prints("send:\t");
for(i=0; i<h->msgh_size/sizeof(p[0]); i++){ for(i=0; i<h->msgh_size/sizeof(p[0]); i++){
runtime·prints(" "); runtime·prints(" ");
runtime·printpointer((void*)p[i]); runtime·printpointer_c((void*)p[i]);
if(i%8 == 7) if(i%8 == 7)
runtime·prints("\n\t"); runtime·prints("\n\t");
} }
...@@ -231,7 +231,7 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize) ...@@ -231,7 +231,7 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize)
if(ret != 0){ if(ret != 0){
if(DebugMach){ if(DebugMach){
runtime·prints("mach_msg error "); runtime·prints("mach_msg error ");
runtime·printint(ret); runtime·printint_c(ret);
runtime·prints("\n"); runtime·prints("\n");
} }
return ret; return ret;
...@@ -242,7 +242,7 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize) ...@@ -242,7 +242,7 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize)
runtime·prints("recv:\t"); runtime·prints("recv:\t");
for(i=0; i<h->msgh_size/sizeof(p[0]); i++){ for(i=0; i<h->msgh_size/sizeof(p[0]); i++){
runtime·prints(" "); runtime·prints(" ");
runtime·printpointer((void*)p[i]); runtime·printpointer_c((void*)p[i]);
if(i%8 == 7) if(i%8 == 7)
runtime·prints("\n\t"); runtime·prints("\n\t");
} }
...@@ -253,9 +253,9 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize) ...@@ -253,9 +253,9 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize)
if(h->msgh_id != id+Reply){ if(h->msgh_id != id+Reply){
if(DebugMach){ if(DebugMach){
runtime·prints("mach_msg reply id mismatch "); runtime·prints("mach_msg reply id mismatch ");
runtime·printint(h->msgh_id); runtime·printint_c(h->msgh_id);
runtime·prints(" != "); runtime·prints(" != ");
runtime·printint(id+Reply); runtime·printint_c(id+Reply);
runtime·prints("\n"); runtime·prints("\n");
} }
return -303; // MIG_REPLY_MISMATCH return -303; // MIG_REPLY_MISMATCH
...@@ -272,7 +272,7 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize) ...@@ -272,7 +272,7 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize)
&& !(h->msgh_bits & MACH_MSGH_BITS_COMPLEX)){ && !(h->msgh_bits & MACH_MSGH_BITS_COMPLEX)){
if(DebugMach){ if(DebugMach){
runtime·prints("mig result "); runtime·prints("mig result ");
runtime·printint(c->code); runtime·printint_c(c->code);
runtime·prints("\n"); runtime·prints("\n");
} }
return c->code; return c->code;
...@@ -281,9 +281,9 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize) ...@@ -281,9 +281,9 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize)
if(h->msgh_size != rxsize){ if(h->msgh_size != rxsize){
if(DebugMach){ if(DebugMach){
runtime·prints("mach_msg reply size mismatch "); runtime·prints("mach_msg reply size mismatch ");
runtime·printint(h->msgh_size); runtime·printint_c(h->msgh_size);
runtime·prints(" != "); runtime·prints(" != ");
runtime·printint(rxsize); runtime·printint_c(rxsize);
runtime·prints("\n"); runtime·prints("\n");
} }
return -307; // MIG_ARRAY_TOO_LARGE return -307; // MIG_ARRAY_TOO_LARGE
......
...@@ -63,11 +63,11 @@ runtime·futexsleep(uint32 *addr, uint32 val, int64 ns) ...@@ -63,11 +63,11 @@ runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
return; return;
runtime·prints("umtx_wait addr="); runtime·prints("umtx_wait addr=");
runtime·printpointer(addr); runtime·printpointer_c(addr);
runtime·prints(" val="); runtime·prints(" val=");
runtime·printint(val); runtime·printint_c(val);
runtime·prints(" ret="); runtime·prints(" ret=");
runtime·printint(ret); runtime·printint_c(ret);
runtime·prints("\n"); runtime·prints("\n");
*(int32*)0x1005 = 0x1005; *(int32*)0x1005 = 0x1005;
} }
......
...@@ -64,11 +64,11 @@ runtime·futexsleep(uint32 *addr, uint32 val, int64 ns) ...@@ -64,11 +64,11 @@ runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
fail: fail:
runtime·prints("umtx_wait addr="); runtime·prints("umtx_wait addr=");
runtime·printpointer(addr); runtime·printpointer_c(addr);
runtime·prints(" val="); runtime·prints(" val=");
runtime·printint(val); runtime·printint_c(val);
runtime·prints(" ret="); runtime·prints(" ret=");
runtime·printint(ret); runtime·printint_c(ret);
runtime·prints("\n"); runtime·prints("\n");
*(int32*)0x1005 = 0x1005; *(int32*)0x1005 = 0x1005;
} }
......
...@@ -36,8 +36,8 @@ runtime·dump(byte *p, int32 n) ...@@ -36,8 +36,8 @@ runtime·dump(byte *p, int32 n)
int32 i; int32 i;
for(i=0; i<n; i++) { for(i=0; i<n; i++) {
runtime·printpointer((byte*)(p[i]>>4)); runtime·printpointer_c((byte*)(p[i]>>4));
runtime·printpointer((byte*)(p[i]&0xf)); runtime·printpointer_c((byte*)(p[i]&0xf));
if((i&15) == 15) if((i&15) == 15)
runtime·prints("\n"); runtime·prints("\n");
else else
...@@ -144,49 +144,49 @@ vprintf(int8 *s, byte *base) ...@@ -144,49 +144,49 @@ vprintf(int8 *s, byte *base)
v = (byte*)arg; v = (byte*)arg;
switch(*p) { switch(*p) {
case 'a': case 'a':
runtime·printslice(*(Slice*)v); runtime·printslice_c(*(Slice*)v);
break; break;
case 'c': case 'c':
runtime·printbyte(*(int8*)v); runtime·printbyte_c(*(int8*)v);
break; break;
case 'd': case 'd':
runtime·printint(*(int32*)v); runtime·printint_c(*(int32*)v);
break; break;
case 'D': case 'D':
runtime·printint(*(int64*)v); runtime·printint_c(*(int64*)v);
break; break;
case 'e': case 'e':
runtime·printeface(*(Eface*)v); runtime·printeface_c(*(Eface*)v);
break; break;
case 'f': case 'f':
runtime·printfloat(*(float64*)v); runtime·printfloat_c(*(float64*)v);
break; break;
case 'C': case 'C':
runtime·printcomplex(*(Complex128*)v); runtime·printcomplex_c(*(Complex128*)v);
break; break;
case 'i': case 'i':
runtime·printiface(*(Iface*)v); runtime·printiface_c(*(Iface*)v);
break; break;
case 'p': case 'p':
runtime·printpointer(*(void**)v); runtime·printpointer_c(*(void**)v);
break; break;
case 's': case 's':
runtime·prints(*(int8**)v); runtime·prints(*(int8**)v);
break; break;
case 'S': case 'S':
runtime·printstring(*(String*)v); runtime·printstring_c(*(String*)v);
break; break;
case 't': case 't':
runtime·printbool(*(bool*)v); runtime·printbool_c(*(bool*)v);
break; break;
case 'U': case 'U':
runtime·printuint(*(uint64*)v); runtime·printuint_c(*(uint64*)v);
break; break;
case 'x': case 'x':
runtime·printhex(*(uint32*)v); runtime·printhex_c(*(uint32*)v);
break; break;
case 'X': case 'X':
runtime·printhex(*(uint64*)v); runtime·printhex_c(*(uint64*)v);
break; break;
} }
arg += siz; arg += siz;
...@@ -198,25 +198,35 @@ vprintf(int8 *s, byte *base) ...@@ -198,25 +198,35 @@ vprintf(int8 *s, byte *base)
//runtime·unlock(&debuglock); //runtime·unlock(&debuglock);
} }
#pragma textflag NOSPLIT static void
void goprintf_m(void)
runtime·goprintf(String s, ...)
{ {
// Can assume s has terminating NUL because only // Can assume s has terminating NUL because only
// the Go compiler generates calls to runtime·goprintf, using // the Go compiler generates calls to runtime·goprintf, using
// string constants, and all the string constants have NULs. // string constants, and all the string constants have NULs.
vprintf((int8*)s.str, (byte*)(&s+1)); 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 void
runtime·printpc(void *p) runtime·printpc_c(void *p)
{ {
runtime·prints("PC="); runtime·prints("PC=");
runtime·printhex((uint64)runtime·getcallerpc(p)); runtime·printhex_c((uint64)runtime·getcallerpc(p));
} }
void void
runtime·printbool(bool v) runtime·printbool_c(bool v)
{ {
if(v) { if(v) {
gwrite((byte*)"true", 4); gwrite((byte*)"true", 4);
...@@ -226,13 +236,13 @@ runtime·printbool(bool v) ...@@ -226,13 +236,13 @@ runtime·printbool(bool v)
} }
void void
runtime·printbyte(int8 c) runtime·printbyte_c(int8 c)
{ {
gwrite(&c, 1); gwrite(&c, 1);
} }
void void
runtime·printfloat(float64 v) runtime·printfloat_c(float64 v)
{ {
byte buf[20]; byte buf[20];
int32 e, s, i, n; int32 e, s, i, n;
...@@ -313,16 +323,16 @@ runtime·printfloat(float64 v) ...@@ -313,16 +323,16 @@ runtime·printfloat(float64 v)
} }
void void
runtime·printcomplex(Complex128 v) runtime·printcomplex_c(Complex128 v)
{ {
gwrite("(", 1); gwrite("(", 1);
runtime·printfloat(v.real); runtime·printfloat_c(v.real);
runtime·printfloat(v.imag); runtime·printfloat_c(v.imag);
gwrite("i)", 2); gwrite("i)", 2);
} }
void void
runtime·printuint(uint64 v) runtime·printuint_c(uint64 v)
{ {
byte buf[100]; byte buf[100];
int32 i; int32 i;
...@@ -337,17 +347,17 @@ runtime·printuint(uint64 v) ...@@ -337,17 +347,17 @@ runtime·printuint(uint64 v)
} }
void void
runtime·printint(int64 v) runtime·printint_c(int64 v)
{ {
if(v < 0) { if(v < 0) {
gwrite("-", 1); gwrite("-", 1);
v = -v; v = -v;
} }
runtime·printuint(v); runtime·printuint_c(v);
} }
void void
runtime·printhex(uint64 v) runtime·printhex_c(uint64 v)
{ {
static int8 *dig = "0123456789abcdef"; static int8 *dig = "0123456789abcdef";
byte buf[100]; byte buf[100];
...@@ -364,13 +374,13 @@ runtime·printhex(uint64 v) ...@@ -364,13 +374,13 @@ runtime·printhex(uint64 v)
} }
void void
runtime·printpointer(void *p) runtime·printpointer_c(void *p)
{ {
runtime·printhex((uintptr)p); runtime·printhex_c((uintptr)p);
} }
void void
runtime·printstring(String v) runtime·printstring_c(String v)
{ {
if(v.len > runtime·maxstring) { if(v.len > runtime·maxstring) {
gwrite("[string too long]", 17); gwrite("[string too long]", 17);
...@@ -381,13 +391,53 @@ runtime·printstring(String v) ...@@ -381,13 +391,53 @@ runtime·printstring(String v)
} }
void void
runtime·printsp(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)
{ {
gwrite(" ", 1); runtime·printhex_c(g->m->scalararg[0]);
} }
void void
runtime·printnl(void) runtime·printfloat_m(void)
{ {
gwrite("\n", 1); runtime·printfloat_c(*(float64*)(&g->m->scalararg[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 byte
var printuint_m byte
var printhex_m byte
var printfloat_m byte
func printstring(s string) {
mp := acquirem()
mp.scalararg[0] = uint(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] = uint(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])
}
...@@ -1061,23 +1061,23 @@ void runtime·madvise(byte*, uintptr, int32); ...@@ -1061,23 +1061,23 @@ void runtime·madvise(byte*, uintptr, int32);
void runtime·memclr(byte*, uintptr); void runtime·memclr(byte*, uintptr);
void runtime·setcallerpc(void*, void*); void runtime·setcallerpc(void*, void*);
void* runtime·getcallerpc(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);
/* /*
* runtime go-called * runtime go-called
*/ */
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);
void runtime·newstackcall(FuncVal*, byte*, uint32); void runtime·newstackcall(FuncVal*, byte*, uint32);
void reflect·call(FuncVal*, byte*, uint32, uint32); void reflect·call(FuncVal*, byte*, uint32, uint32);
void runtime·panic(Eface); void runtime·panic(Eface);
......
// 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.
#include "runtime.h"
#include "arch_GOARCH.h"
void
runtime·printslice_m(G *gp)
{
void *array;
uintptr len, cap;
array = g->m->ptrarg[0];
g->m->ptrarg[0] = nil;
len = g->m->scalararg[0];
cap = g->m->scalararg[1];
runtime·prints("[");
runtime·printint(len);
runtime·prints("/");
runtime·printint(cap);
runtime·prints("]");
runtime·printpointer(array);
runtime·gogo(&gp->sched);
}
...@@ -141,14 +141,3 @@ func slicestringcopy(to []byte, fm string) int { ...@@ -141,14 +141,3 @@ func slicestringcopy(to []byte, fm string) int {
memmove(unsafe.Pointer(&to[0]), unsafe.Pointer((*stringStruct)(unsafe.Pointer(&fm)).str), uintptr(n)) memmove(unsafe.Pointer(&to[0]), unsafe.Pointer((*stringStruct)(unsafe.Pointer(&fm)).str), uintptr(n))
return n return n
} }
var printslice_m byte
func printslice(a sliceStruct) {
mp := acquirem()
mp.ptrarg[0] = a.array
mp.scalararg[0] = uint(a.len)
mp.scalararg[1] = uint(a.cap)
mcall(&printslice_m)
releasem(mp)
}
...@@ -229,7 +229,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, ...@@ -229,7 +229,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip,
} }
if(i != 0) if(i != 0)
runtime·prints(", "); runtime·prints(", ");
runtime·printhex(((uintptr*)frame.argp)[i]); runtime·printhex_c(((uintptr*)frame.argp)[i]);
} }
runtime·prints(")\n"); runtime·prints(")\n");
line = runtime·funcline(f, tracepc, &file); line = runtime·funcline(f, tracepc, &file);
......
...@@ -270,7 +270,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, ...@@ -270,7 +270,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip,
} }
if(i != 0) if(i != 0)
runtime·prints(", "); runtime·prints(", ");
runtime·printhex(((uintptr*)frame.argp)[i]); runtime·printhex_c(((uintptr*)frame.argp)[i]);
} }
runtime·prints(")\n"); runtime·prints(")\n");
line = runtime·funcline(f, tracepc, &file); line = runtime·funcline(f, tracepc, &file);
......
// cmpout
// 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.
// Test internal print routines that are generated
// by the print builtin. This test is not exhaustive,
// we're just checking that the formatting is correct.
package main
func main() {
println((interface{})(nil)) // printeface
println((interface { // printiface
f()
})(nil))
println((map[int]int)(nil)) // printpointer
println(([]int)(nil)) // printslice
println(int64(-7)) // printint
println(uint64(7)) // printuint
println(8.0) // printfloat
println(complex(9.0, 10.0)) // printcomplex
println(true) // printbool
println(false) // printbool
println("hello") // printstring
println("one", "two") // printsp
// test goprintf
defer println((interface{})(nil))
defer println((interface{f()})(nil))
defer println((map[int]int)(nil))
defer println(([]int)(nil))
defer println(int64(-11))
defer println(uint64(12))
defer println(13.0)
defer println(complex(14.0, 15.0))
defer println(true)
defer println(false)
defer println("hello")
defer println("one", "two")
}
(0x0,0x0)
(0x0,0x0)
0x0
[0/0]0x0
-7
7
+8.000000e+000
(+9.000000e+000+1.000000e+001i)
true
false
hello
one two
one two
hello
false
true
(+1.400000e+001+1.500000e+001i)
+1.300000e+001
12
-11
[0/0]0x0
0x0
(0x0,0x0)
(0x0,0x0)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment