Skip to content

Commit a186b77

Browse files
committed
gc: implement defer print/println/panic/panicln
Fixes #219. R=ken2, r CC=golang-dev https://golang.org/cl/194097
1 parent 22a4952 commit a186b77

File tree

7 files changed

+246
-80
lines changed

7 files changed

+246
-80
lines changed

src/cmd/gc/builtin.c.boot

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
char *runtimeimport =
22
"package runtime\n"
3-
"func \"\".mal (? int32) (? *any)\n"
3+
"func \"\".mal (? int32) *any\n"
44
"func \"\".throwindex ()\n"
55
"func \"\".throwreturn ()\n"
66
"func \"\".throwinit ()\n"
@@ -16,17 +16,18 @@ char *runtimeimport =
1616
"func \"\".printslice (? any)\n"
1717
"func \"\".printnl ()\n"
1818
"func \"\".printsp ()\n"
19-
"func \"\".catstring (? string, ? string) (? string)\n"
20-
"func \"\".cmpstring (? string, ? string) (? int)\n"
21-
"func \"\".slicestring (? string, ? int, ? int) (? string)\n"
22-
"func \"\".slicestring1 (? string, ? int) (? string)\n"
23-
"func \"\".indexstring (? string, ? int) (? uint8)\n"
24-
"func \"\".intstring (? int64) (? string)\n"
25-
"func \"\".slicebytetostring (? []uint8) (? string)\n"
26-
"func \"\".sliceinttostring (? []int) (? string)\n"
27-
"func \"\".stringiter (? string, ? int) (? int)\n"
19+
"func \"\".printf ()\n"
20+
"func \"\".catstring (? string, ? string) string\n"
21+
"func \"\".cmpstring (? string, ? string) int\n"
22+
"func \"\".slicestring (? string, ? int, ? int) string\n"
23+
"func \"\".slicestring1 (? string, ? int) string\n"
24+
"func \"\".indexstring (? string, ? int) uint8\n"
25+
"func \"\".intstring (? int64) string\n"
26+
"func \"\".slicebytetostring (? []uint8) string\n"
27+
"func \"\".sliceinttostring (? []int) string\n"
28+
"func \"\".stringiter (? string, ? int) int\n"
2829
"func \"\".stringiter2 (? string, ? int) (retk int, retv int)\n"
29-
"func \"\".slicecopy (to any, fr any, wid uint32) (? int)\n"
30+
"func \"\".slicecopy (to any, fr any, wid uint32) int\n"
3031
"func \"\".ifaceI2E (iface any) (ret any)\n"
3132
"func \"\".ifaceE2I (typ *uint8, iface any) (ret any)\n"
3233
"func \"\".ifaceT2E (typ *uint8, elem any) (ret any)\n"
@@ -58,7 +59,7 @@ char *runtimeimport =
5859
"func \"\".chansend1 (hchan chan<- any, elem any)\n"
5960
"func \"\".chansend2 (hchan chan<- any, elem any) (pres bool)\n"
6061
"func \"\".closechan (hchan any)\n"
61-
"func \"\".closedchan (hchan any) (? bool)\n"
62+
"func \"\".closedchan (hchan any) bool\n"
6263
"func \"\".newselect (size int) (sel *uint8)\n"
6364
"func \"\".selectsend (sel *uint8, hchan chan<- any, elem any) (selected bool)\n"
6465
"func \"\".selectrecv (sel *uint8, hchan <-chan any, elem *any) (selected bool)\n"
@@ -69,24 +70,24 @@ char *runtimeimport =
6970
"func \"\".sliceslice (old []any, lb int, hb int, width int) (ary []any)\n"
7071
"func \"\".slicearray (old *any, nel int, lb int, hb int, width int) (ary []any)\n"
7172
"func \"\".closure ()\n"
72-
"func \"\".int64div (? int64, ? int64) (? int64)\n"
73-
"func \"\".uint64div (? uint64, ? uint64) (? uint64)\n"
74-
"func \"\".int64mod (? int64, ? int64) (? int64)\n"
75-
"func \"\".uint64mod (? uint64, ? uint64) (? uint64)\n"
76-
"func \"\".float64toint64 (? float64) (? int64)\n"
77-
"func \"\".int64tofloat64 (? int64) (? float64)\n"
73+
"func \"\".int64div (? int64, ? int64) int64\n"
74+
"func \"\".uint64div (? uint64, ? uint64) uint64\n"
75+
"func \"\".int64mod (? int64, ? int64) int64\n"
76+
"func \"\".uint64mod (? uint64, ? uint64) uint64\n"
77+
"func \"\".float64toint64 (? float64) int64\n"
78+
"func \"\".int64tofloat64 (? int64) float64\n"
7879
"\n"
7980
"$$\n";
8081
char *unsafeimport =
8182
"package unsafe\n"
8283
"type \"\".Pointer *any\n"
83-
"func \"\".Offsetof (? any) (? int)\n"
84-
"func \"\".Sizeof (? any) (? int)\n"
85-
"func \"\".Alignof (? any) (? int)\n"
84+
"func \"\".Offsetof (? any) int\n"
85+
"func \"\".Sizeof (? any) int\n"
86+
"func \"\".Alignof (? any) int\n"
8687
"func \"\".Typeof (i interface { }) (typ interface { })\n"
8788
"func \"\".Reflect (i interface { }) (typ interface { }, addr \"\".Pointer)\n"
8889
"func \"\".Unreflect (typ interface { }, addr \"\".Pointer) (ret interface { })\n"
89-
"func \"\".New (typ interface { }) (? \"\".Pointer)\n"
90-
"func \"\".NewArray (typ interface { }, n int) (? \"\".Pointer)\n"
90+
"func \"\".New (typ interface { }) \"\".Pointer\n"
91+
"func \"\".NewArray (typ interface { }, n int) \"\".Pointer\n"
9192
"\n"
9293
"$$\n";

src/cmd/gc/runtime.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ func printeface(any)
2727
func printslice(any)
2828
func printnl()
2929
func printsp()
30+
func printf()
3031

3132
func catstring(string, string) string
3233
func cmpstring(string, string) int

src/cmd/gc/walk.c

Lines changed: 129 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
#include "go.h"
66

7-
static Node* walkprint(Node*, NodeList**);
7+
static Node* walkprint(Node*, NodeList**, int);
88
static Node* conv(Node*, Type*);
99
static Node* mapfn(char*, Type*);
1010
static Node* makenewvar(Type*, NodeList**, Node**);
@@ -355,7 +355,18 @@ walkstmt(Node **np)
355355

356356
case ODEFER:
357357
hasdefer = 1;
358-
walkexpr(&n->left, &n->ninit);
358+
switch(n->left->op) {
359+
case OPRINT:
360+
case OPRINTN:
361+
case OPANIC:
362+
case OPANICN:
363+
walkexprlist(n->left->list, &n->ninit);
364+
n->left = walkprint(n->left, &n->ninit, 1);
365+
break;
366+
default:
367+
walkexpr(&n->left, &n->ninit);
368+
break;
369+
}
359370
break;
360371

361372
case OFOR:
@@ -539,7 +550,7 @@ walkexpr(Node **np, NodeList **init)
539550
case OPANIC:
540551
case OPANICN:
541552
walkexprlist(n->list, init);
542-
n = walkprint(n, init);
553+
n = walkprint(n, init, 0);
543554
goto ret;
544555

545556
case OLITERAL:
@@ -1510,24 +1521,40 @@ ascompatte(int op, Type **nl, NodeList *lr, int fp, NodeList **init)
15101521

15111522
// generate code for print
15121523
static Node*
1513-
walkprint(Node *nn, NodeList **init)
1524+
walkprint(Node *nn, NodeList **init, int defer)
15141525
{
15151526
Node *r;
15161527
Node *n;
15171528
NodeList *l, *all;
15181529
Node *on;
15191530
Type *t;
15201531
int notfirst, et, op;
1521-
NodeList *calls;
1532+
NodeList *calls, *intypes, *args;
1533+
Fmt fmt;
15221534

1535+
on = nil;
15231536
op = nn->op;
15241537
all = nn->list;
15251538
calls = nil;
15261539
notfirst = 0;
1540+
intypes = nil;
1541+
args = nil;
1542+
1543+
memset(&fmt, 0, sizeof fmt);
1544+
if(defer) {
1545+
// defer print turns into defer printf with format string
1546+
fmtstrinit(&fmt);
1547+
intypes = list(intypes, nod(ODCLFIELD, N, typenod(types[TSTRING])));
1548+
args = list1(nod(OXXX, N, N));
1549+
}
15271550

15281551
for(l=all; l; l=l->next) {
1529-
if(notfirst)
1530-
calls = list(calls, mkcall("printsp", T, init));
1552+
if(notfirst) {
1553+
if(defer)
1554+
fmtprint(&fmt, " ");
1555+
else
1556+
calls = list(calls, mkcall("printsp", T, init));
1557+
}
15311558
notfirst = op == OPRINTN || op == OPANICN;
15321559

15331560
n = l->n;
@@ -1548,62 +1575,121 @@ walkprint(Node *nn, NodeList **init)
15481575
if(n->type == T || n->type->etype == TFORW)
15491576
continue;
15501577

1578+
t = n->type;
15511579
et = n->type->etype;
15521580
if(isinter(n->type)) {
1553-
if(isnilinter(n->type))
1554-
on = syslook("printeface", 1);
1555-
else
1556-
on = syslook("printiface", 1);
1557-
argtype(on, n->type); // any-1
1581+
if(defer) {
1582+
if(isnilinter(n->type))
1583+
fmtprint(&fmt, "%%e");
1584+
else
1585+
fmtprint(&fmt, "%%i");
1586+
} else {
1587+
if(isnilinter(n->type))
1588+
on = syslook("printeface", 1);
1589+
else
1590+
on = syslook("printiface", 1);
1591+
argtype(on, n->type); // any-1
1592+
}
15581593
} else if(isptr[et] || et == TCHAN || et == TMAP || et == TFUNC) {
1559-
on = syslook("printpointer", 1);
1560-
argtype(on, n->type); // any-1
1594+
if(defer) {
1595+
fmtprint(&fmt, "%%p");
1596+
} else {
1597+
on = syslook("printpointer", 1);
1598+
argtype(on, n->type); // any-1
1599+
}
15611600
} else if(isslice(n->type)) {
1562-
on = syslook("printslice", 1);
1563-
argtype(on, n->type); // any-1
1601+
if(defer) {
1602+
fmtprint(&fmt, "%%a");
1603+
} else {
1604+
on = syslook("printslice", 1);
1605+
argtype(on, n->type); // any-1
1606+
}
15641607
} else if(isint[et]) {
1565-
if(et == TUINT64)
1566-
on = syslook("printuint", 0);
1567-
else
1568-
on = syslook("printint", 0);
1608+
if(defer) {
1609+
if(et == TUINT64)
1610+
fmtprint(&fmt, "%%U");
1611+
else {
1612+
fmtprint(&fmt, "%%D");
1613+
t = types[TINT64];
1614+
}
1615+
} else {
1616+
if(et == TUINT64)
1617+
on = syslook("printuint", 0);
1618+
else
1619+
on = syslook("printint", 0);
1620+
}
15691621
} else if(isfloat[et]) {
1570-
on = syslook("printfloat", 0);
1622+
if(defer) {
1623+
fmtprint(&fmt, "%%f");
1624+
t = types[TFLOAT64];
1625+
} else
1626+
on = syslook("printfloat", 0);
15711627
} else if(et == TBOOL) {
1572-
on = syslook("printbool", 0);
1628+
if(defer)
1629+
fmtprint(&fmt, "%%t");
1630+
else
1631+
on = syslook("printbool", 0);
15731632
} else if(et == TSTRING) {
1574-
on = syslook("printstring", 0);
1633+
if(defer)
1634+
fmtprint(&fmt, "%%S");
1635+
else
1636+
on = syslook("printstring", 0);
15751637
} else {
15761638
badtype(OPRINT, n->type, T);
15771639
continue;
15781640
}
15791641

1580-
t = *getinarg(on->type);
1581-
if(t != nil)
1582-
t = t->type;
1583-
if(t != nil)
1584-
t = t->type;
1642+
if(!defer) {
1643+
t = *getinarg(on->type);
1644+
if(t != nil)
1645+
t = t->type;
1646+
if(t != nil)
1647+
t = t->type;
1648+
}
15851649

15861650
if(!eqtype(t, n->type)) {
15871651
n = nod(OCONV, n, N);
15881652
n->type = t;
15891653
}
1590-
r = nod(OCALL, on, N);
1591-
r->list = list1(n);
1592-
calls = list(calls, r);
1654+
1655+
if(defer) {
1656+
intypes = list(intypes, nod(ODCLFIELD, N, typenod(t)));
1657+
args = list(args, n);
1658+
} else {
1659+
r = nod(OCALL, on, N);
1660+
r->list = list1(n);
1661+
calls = list(calls, r);
1662+
}
15931663
}
15941664

1595-
if(op == OPRINTN)
1596-
calls = list(calls, mkcall("printnl", T, nil));
1597-
typechecklist(calls, Etop);
1598-
walkexprlist(calls, init);
1599-
1600-
if(op == OPANIC || op == OPANICN)
1601-
r = mkcall("panicl", T, nil);
1602-
else
1603-
r = nod(OEMPTY, N, N);
1604-
typecheck(&r, Etop);
1605-
walkexpr(&r, init);
1606-
r->ninit = calls;
1665+
if(defer) {
1666+
if(op == OPRINTN)
1667+
fmtprint(&fmt, "\n");
1668+
if(op == OPANIC || op == OPANICN)
1669+
fmtprint(&fmt, "%%!");
1670+
on = syslook("printf", 1);
1671+
on->type = functype(nil, intypes, nil);
1672+
args->n = nod(OLITERAL, N, N);
1673+
args->n->val.ctype = CTSTR;
1674+
args->n->val.u.sval = strlit(fmtstrflush(&fmt));
1675+
r = nod(OCALL, on, N);
1676+
r->list = args;
1677+
typecheck(&r, Etop);
1678+
walkexpr(&r, init);
1679+
} else {
1680+
if(op == OPRINTN)
1681+
calls = list(calls, mkcall("printnl", T, nil));
1682+
typechecklist(calls, Etop);
1683+
walkexprlist(calls, init);
1684+
1685+
if(op == OPANIC || op == OPANICN)
1686+
r = mkcall("panicl", T, nil);
1687+
else
1688+
r = nod(OEMPTY, N, N);
1689+
typecheck(&r, Etop);
1690+
walkexpr(&r, init);
1691+
r->ninit = calls;
1692+
}
16071693
return r;
16081694
}
16091695

0 commit comments

Comments
 (0)