Blob
1 #include <u.h>2 #include <libc.h>3 #include <bio.h>4 #include <ctype.h>5 #include <mach.h>6 #define Extern extern7 #include "acid.h"9 static List **tail;11 List*12 construct(Node *l)13 {14 List *lh, **save;16 save = tail;17 lh = 0;18 tail = &lh;19 build(l);20 tail = save;22 return lh;23 }25 int26 listlen(List *l)27 {28 int len;30 len = 0;31 while(l) {32 len++;33 l = l->next;34 }35 return len;36 }38 void39 build(Node *n)40 {41 List *l;42 Node res;44 if(n == 0)45 return;47 switch(n->op) {48 case OLIST:49 build(n->left);50 build(n->right);51 return;52 default:53 expr(n, &res);54 l = al(res.type);55 l->store = res.store;56 *tail = l;57 tail = &l->next;58 }59 }61 List*62 addlist(List *l, List *r)63 {64 List *f;66 if(l == 0)67 return r;69 for(f = l; f->next; f = f->next)70 ;71 f->next = r;73 return l;74 }76 void77 append(Node *r, Node *list, Node *val)78 {79 List *l, *f;81 l = al(val->type);82 l->store = val->store;83 l->next = 0;85 r->op = OCONST;86 r->type = TLIST;88 if(list->store.u.l == 0) {89 list->store.u.l = l;90 r->store.u.l = l;91 return;92 }93 for(f = list->store.u.l; f->next; f = f->next)94 ;95 f->next = l;96 r->store.u.l = list->store.u.l;97 }99 int100 listcmp(List *l, List *r)101 {102 if(l == r)103 return 1;105 while(l) {106 if(r == 0)107 return 0;108 if(l->type != r->type)109 return 0;110 switch(l->type) {111 case TINT:112 if(l->store.u.ival != r->store.u.ival)113 return 0;114 break;115 case TFLOAT:116 if(l->store.u.fval != r->store.u.fval)117 return 0;118 break;119 case TSTRING:120 if(scmp(l->store.u.string, r->store.u.string) == 0)121 return 0;122 break;123 case TLIST:124 if(listcmp(l->store.u.l, r->store.u.l) == 0)125 return 0;126 break;127 }128 l = l->next;129 r = r->next;130 }131 if(l != r)132 return 0;133 return 1;134 }136 void137 nthelem(List *l, int n, Node *res)138 {139 if(n < 0)140 error("negative index in []");142 while(l && n--)143 l = l->next;145 res->op = OCONST;146 if(l == 0) {147 res->type = TLIST;148 res->store.u.l = 0;149 return;150 }151 res->type = l->type;152 res->store = l->store;153 }155 void156 delete(List *l, int n, Node *res)157 {158 List **tl;160 if(n < 0)161 error("negative index in delete");163 res->op = OCONST;164 res->type = TLIST;165 res->store.u.l = l;167 for(tl = &res->store.u.l; l && n--; l = l->next)168 tl = &l->next;170 if(l == 0)171 error("element beyond end of list");172 *tl = l->next;173 }175 List*176 listvar(char *s, long v)177 {178 List *l, *tl;180 tl = al(TLIST);182 l = al(TSTRING);183 tl->store.u.l = l;184 l->store.fmt = 's';185 l->store.u.string = strnode(s);186 l->next = al(TINT);187 l = l->next;188 l->store.fmt = 'X';189 l->store.u.ival = v;191 return tl;192 }194 static List*195 listregisters(Map *map, Regs *regs)196 {197 List **tail, *l2, *l;198 Regdesc *rp;199 ulong v;201 l2 = 0;202 tail = &l2;203 for(rp=mach->reglist; rp->name; rp++){204 if(rget(regs, rp->name, &v) < 0)205 continue;206 l = al(TSTRING);207 l->store.fmt = 's';208 l->store.u.string = strnode(rp->name);209 *tail = l;210 tail = &l->next;211 l = al(TINT);212 l->store.fmt = 'X';213 l->store.u.ival = v;214 *tail = l;215 tail = &l->next;216 }217 return l2;218 }220 static List*221 listlocals(Map *map, Regs *regs, Symbol *fn, int class)222 {223 int i;224 u32int val;225 Symbol s;226 List **tail, *l2;228 l2 = 0;229 tail = &l2;230 if(fn == nil)231 return l2;232 for(i = 0; indexlsym(fn, i, &s)>=0; i++) {233 if(s.class != class)234 continue;235 if(class == CAUTO && (s.name==0 || s.name[0] == '.'))236 continue;237 if(lget4(map, regs, s.loc, &val) < 0)238 continue;239 *tail = listvar(s.name, val);240 tail = &(*tail)->next;241 }242 return l2;243 }245 static List*246 listparams(Map *map, Regs *regs, Symbol *fn)247 {248 return listlocals(map, regs, fn, CPARAM);249 }251 static List*252 listautos(Map *map, Regs *regs, Symbol *fn)253 {254 return listlocals(map, regs, fn, CAUTO);255 }257 int258 trlist(Map *map, Regs *regs, ulong pc, ulong callerpc, Symbol *sym, int depth)259 {260 List *q, *l;261 static List **tail;263 if (tracelist == 0) /* first time */264 tail = &tracelist;266 q = al(TLIST);267 *tail = q;268 tail = &q->next;270 l = al(TINT); /* Function address */271 q->store.u.l = l;272 l->store.u.ival = sym ? sym->loc.addr : pc;273 l->store.fmt = 'X';275 l->next = al(TINT); /* actual pc address */276 l = l->next;277 l->store.u.ival = pc;278 l->store.fmt = 'X';280 l->next = al(TINT); /* called from address */281 l = l->next;282 l->store.u.ival = callerpc;283 l->store.fmt = 'X';285 l->next = al(TLIST); /* make list of params */286 l = l->next;287 if(sym)288 l->store.u.l = listparams(map, regs, sym);290 l->next = al(TLIST); /* make list of locals */291 l = l->next;292 if(sym)293 l->store.u.l = listautos(map, regs, sym);295 l->next = al(TLIST); /* make list of registers */296 l = l->next;297 l->store.u.l = listregisters(map, regs);299 return depth<40;300 }