blob: 2c26426e244b2c62019ea73e1d7af031e390e514 [file] [log] [blame]
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ctype.h>
#include <mach.h>
#define Extern extern
#include "acid.h"
static List **tail;
List*
construct(Node *l)
{
List *lh, **save;
save = tail;
lh = 0;
tail = &lh;
build(l);
tail = save;
return lh;
}
int
listlen(List *l)
{
int len;
len = 0;
while(l) {
len++;
l = l->next;
}
return len;
}
void
build(Node *n)
{
List *l;
Node res;
if(n == 0)
return;
switch(n->op) {
case OLIST:
build(n->left);
build(n->right);
return;
default:
expr(n, &res);
l = al(res.type);
l->store = res.store;
*tail = l;
tail = &l->next;
}
}
List*
addlist(List *l, List *r)
{
List *f;
if(l == 0)
return r;
for(f = l; f->next; f = f->next)
;
f->next = r;
return l;
}
void
append(Node *r, Node *list, Node *val)
{
List *l, *f;
l = al(val->type);
l->store = val->store;
l->next = 0;
r->op = OCONST;
r->type = TLIST;
if(list->store.u.l == 0) {
list->store.u.l = l;
r->store.u.l = l;
return;
}
for(f = list->store.u.l; f->next; f = f->next)
;
f->next = l;
r->store.u.l = list->store.u.l;
}
int
listcmp(List *l, List *r)
{
if(l == r)
return 1;
while(l) {
if(r == 0)
return 0;
if(l->type != r->type)
return 0;
switch(l->type) {
case TINT:
if(l->store.u.ival != r->store.u.ival)
return 0;
break;
case TFLOAT:
if(l->store.u.fval != r->store.u.fval)
return 0;
break;
case TSTRING:
if(scmp(l->store.u.string, r->store.u.string) == 0)
return 0;
break;
case TLIST:
if(listcmp(l->store.u.l, r->store.u.l) == 0)
return 0;
break;
}
l = l->next;
r = r->next;
}
if(l != r)
return 0;
return 1;
}
void
nthelem(List *l, int n, Node *res)
{
if(n < 0)
error("negative index in []");
while(l && n--)
l = l->next;
res->op = OCONST;
if(l == 0) {
res->type = TLIST;
res->store.u.l = 0;
return;
}
res->type = l->type;
res->store = l->store;
}
void
delete(List *l, int n, Node *res)
{
List **tl;
if(n < 0)
error("negative index in delete");
res->op = OCONST;
res->type = TLIST;
res->store.u.l = l;
for(tl = &res->store.u.l; l && n--; l = l->next)
tl = &l->next;
if(l == 0)
error("element beyond end of list");
*tl = l->next;
}
List*
listvar(char *s, long v)
{
List *l, *tl;
tl = al(TLIST);
l = al(TSTRING);
tl->store.u.l = l;
l->store.fmt = 's';
l->store.u.string = strnode(s);
l->next = al(TINT);
l = l->next;
l->store.fmt = 'X';
l->store.u.ival = v;
return tl;
}
static List*
listregisters(Map *map, Regs *regs)
{
List **tail, *l2, *l;
Regdesc *rp;
u64int v;
l2 = 0;
tail = &l2;
for(rp=mach->reglist; rp->name; rp++){
if(rget(regs, rp->name, &v) < 0)
continue;
l = al(TSTRING);
l->store.fmt = 's';
l->store.u.string = strnode(rp->name);
*tail = l;
tail = &l->next;
l = al(TINT);
l->store.fmt = 'X';
l->store.u.ival = v;
*tail = l;
tail = &l->next;
}
return l2;
}
static List*
listlocals(Map *map, Regs *regs, Symbol *fn, int class)
{
int i;
u32int val;
Symbol s;
List **tail, *l2;
l2 = 0;
tail = &l2;
if(fn == nil)
return l2;
for(i = 0; indexlsym(fn, i, &s)>=0; i++) {
if(s.class != class)
continue;
if(class == CAUTO && (s.name==0 || s.name[0] == '.'))
continue;
if(lget4(map, regs, s.loc, &val) < 0)
continue;
*tail = listvar(s.name, val);
tail = &(*tail)->next;
}
return l2;
}
static List*
listparams(Map *map, Regs *regs, Symbol *fn)
{
return listlocals(map, regs, fn, CPARAM);
}
static List*
listautos(Map *map, Regs *regs, Symbol *fn)
{
return listlocals(map, regs, fn, CAUTO);
}
int
trlist(Map *map, Regs *regs, u64int pc, u64int callerpc, Symbol *sym, int depth)
{
List *q, *l;
static List **tail;
if (tracelist == 0) /* first time */
tail = &tracelist;
q = al(TLIST);
*tail = q;
tail = &q->next;
l = al(TINT); /* Function address */
q->store.u.l = l;
l->store.u.ival = sym ? sym->loc.addr : pc;
l->store.fmt = 'X';
l->next = al(TINT); /* actual pc address */
l = l->next;
l->store.u.ival = pc;
l->store.fmt = 'X';
l->next = al(TINT); /* called from address */
l = l->next;
l->store.u.ival = callerpc;
l->store.fmt = 'X';
l->next = al(TLIST); /* make list of params */
l = l->next;
if(sym)
l->store.u.l = listparams(map, regs, sym);
l->next = al(TLIST); /* make list of locals */
l = l->next;
if(sym)
l->store.u.l = listautos(map, regs, sym);
l->next = al(TLIST); /* make list of registers */
l = l->next;
l->store.u.l = listregisters(map, regs);
return depth<40;
}