📄 trace.c
字号:
#include "c.h"
static void appendstr ARGS((char *));
static void tracecall ARGS((Symbol, Symbol));
static void tracefinis ARGS((Symbol));
static void tracereturn ARGS((Symbol, Symbol, Tree));
static void tracevalue ARGS((Tree, int));
static char *fmt, *fp, *fmtend; /* format string, current & limit pointer */
static Tree args; /* printf arguments */
static Symbol frameno; /* local holding frame number */
/* appendstr - append str to the evolving format string, expanding it if necessary */
static void appendstr(char *str)
{
do
if (fp == fmtend)
if (fp) {
char *s = allocate(2*(fmtend - fmt), FUNC);
strncpy(s, fmt, fmtend - fmt);
fp = s + (fmtend - fmt);
fmtend = s + 2*(fmtend - fmt);
fmt = s;
} else {
fp = fmt = allocate(80, FUNC);
fmtend = fmt + 80;
}
while ((*fp++ = *str++) != 0);
fp--;
}
/* tracecall - generate code to trace entry to f */
static void tracecall(Symbol printer,Symbol f)
{
int i;
Symbol counter = genident(STATIC, inttype, GLOBAL);
defglobal(counter, BSS);
(*IR->space)(counter->type->size);
frameno = genident(AUTO, inttype, level);
addlocal(frameno);
appendstr(f->name); appendstr("#");
tracevalue(asgn(frameno, incr(INCR, idtree(counter), consttree(1, inttype))), 0);
appendstr("(");
for (i = 0; f->u.f.callee[i]; i++) {
if (i)
appendstr(",");
appendstr(f->u.f.callee[i]->name); appendstr("=");
tracevalue(idtree(f->u.f.callee[i]), 0);
}
if (variadic(f->type))
appendstr(",...");
appendstr(StrTab[54]);// <) called\n>
tracefinis(printer);
}
/* tracefinis - complete & generate the trace call to print */
static void tracefinis(Symbol printer)
{
Tree *ap;
Symbol p;
*fp = 0;
p = mkstr(string(fmt));
for (ap = &args; *ap; ap = &(*ap)->kids[1])
;
*ap = tree(ARG+P, ptr(chartype), pointer(idtree(p->u.c.loc)), 0);
walk(calltree(pointer(idtree(printer)), freturn(printer->type), args, NULL), 0, 0);
args = 0;
fp = fmtend = 0;
}
/* traceinit - initialize for tracing */
void traceInit(char *print)
{
static Symbol printer;
if (!printer) {
printer = mksymbol(EXTERN, print && *print ? print : "printf",
ftype(inttype, ptr(qual(CONST, chartype))));
printer->defined = 0;
attach((Apply)tracecall, printer, &events.entry);
attach((Apply)tracereturn, printer, &events.returns);
}
}
/* tracereturn - generate code to trace return e */
static void tracereturn(Symbol printer,Symbol f,Tree e)
{
appendstr(f->name); appendstr("#");
tracevalue(idtree(frameno), 0);
appendstr(" returned");
if (freturn(f->type) != voidtype && e) {
appendstr(" ");
tracevalue(e, 0);
}
appendstr("\n");
tracefinis(printer);
}
/* tracevalue - append format and argument to print the value of e */
static void tracevalue(Tree e,int lev)
{
Type ty = unqual(e->type);
switch (ty->op) {
case CHAR:
appendstr("'\\x%02x'");
break;
case SHORT:
if (ty == unsignedshort)
appendstr("0x%x");
else /* fall thru */
case INT:
appendstr("%d");
break;
case UNSIGNED:
appendstr("0x%x");
break;
case FLOAT: case DOUBLE:
appendstr("%g");
break;
case POINTER:
if (unqual(ty->type) == chartype) {
static Symbol null;
if (null == NULL)
null = mkstr("(null)");
tracevalue(cast(e, unsignedtype), lev + 1);
appendstr(" \"%.30s\"");
e = condtree(e, e, pointer(idtree(null->u.c.loc)));
} else {
appendstr("("); appendstr(typestring(ty, "")); appendstr(")0x%x");
}
break;
case STRUCT: {
Field q;
appendstr("("); appendstr(typestring(ty, "")); appendstr("){");
for (q = ty->u.sym->u.s.flist; q; q = q->link) {
appendstr(q->name); appendstr("=");
tracevalue(field(addrof(e), q->name), lev + 1);
if (q->link)
appendstr(",");
}
appendstr("}");
return;
}
case UNION:
appendstr("("); appendstr(typestring(ty, "")); appendstr("){...}");
return;
case ARRAY:
if (lev && ty->type->size > 0) {
int i;
e = pointer(e);
appendstr("{");
for (i = 0; i < ty->size/ty->type->size; i++) {
Tree p = (*optree['+'])(ADD, e, consttree(i, inttype));
if (isptr(p->type) && isarray(p->type->type))
p = retype(p, p->type->type);
else
p = rvalue(p);
if (i)
appendstr(",");
tracevalue(p, lev + 1);
}
appendstr("}");
} else
appendstr(typestring(ty, ""));
return;
default:
assert(0);
}
if (ty == floattype)
e = cast(e, doubletype);
else if ((isint(ty) || isenum(ty)) && ty->size != inttype->size)
e = cast(e, promote(ty));
args = tree(ARG + widen(e->type), e->type, e, args);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -