2011-03-30 12:46:40 +00:00
|
|
|
#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->l == 0) {
|
|
|
|
list->l = l;
|
|
|
|
r->l = l;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
for(f = list->l; f->next; f = f->next)
|
|
|
|
;
|
|
|
|
f->next = l;
|
|
|
|
r->l = list->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->ival != r->ival)
|
|
|
|
return 0;
|
|
|
|
break;
|
|
|
|
case TFLOAT:
|
|
|
|
if(l->fval != r->fval)
|
|
|
|
return 0;
|
|
|
|
break;
|
|
|
|
case TSTRING:
|
|
|
|
if(scmp(l->string, r->string) == 0)
|
|
|
|
return 0;
|
|
|
|
break;
|
|
|
|
case TLIST:
|
|
|
|
if(listcmp(l->l, r->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->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->l = l;
|
|
|
|
|
|
|
|
for(tl = &res->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, vlong v)
|
|
|
|
{
|
|
|
|
List *l, *tl;
|
|
|
|
|
|
|
|
tl = al(TLIST);
|
|
|
|
|
|
|
|
l = al(TSTRING);
|
|
|
|
tl->l = l;
|
|
|
|
l->fmt = 's';
|
|
|
|
l->string = strnode(s);
|
|
|
|
l->next = al(TINT);
|
|
|
|
l = l->next;
|
2014-02-09 21:43:09 +00:00
|
|
|
l->fmt = 'A';
|
2011-03-30 12:46:40 +00:00
|
|
|
l->ival = v;
|
|
|
|
|
|
|
|
return tl;
|
|
|
|
}
|
|
|
|
|
|
|
|
static List*
|
|
|
|
listlocals(Map *map, Symbol *fn, uvlong fp)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
uvlong val;
|
|
|
|
Symbol s;
|
|
|
|
List **tail, *l2;
|
|
|
|
|
|
|
|
l2 = 0;
|
|
|
|
tail = &l2;
|
|
|
|
s = *fn;
|
|
|
|
|
|
|
|
for(i = 0; localsym(&s, i); i++) {
|
|
|
|
if(s.class != CAUTO)
|
|
|
|
continue;
|
|
|
|
if(s.name[0] == '.')
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if(geta(map, fp-s.value, &val) > 0) {
|
|
|
|
*tail = listvar(s.name, val);
|
|
|
|
tail = &(*tail)->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return l2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static List*
|
|
|
|
listparams(Map *map, Symbol *fn, uvlong fp)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
Symbol s;
|
|
|
|
uvlong v;
|
|
|
|
List **tail, *l2;
|
|
|
|
|
|
|
|
l2 = 0;
|
|
|
|
tail = &l2;
|
|
|
|
fp += mach->szaddr; /* skip saved pc */
|
|
|
|
s = *fn;
|
|
|
|
for(i = 0; localsym(&s, i); i++) {
|
|
|
|
if (s.class != CPARAM)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if(geta(map, fp+s.value, &v) > 0) {
|
|
|
|
*tail = listvar(s.name, v);
|
|
|
|
tail = &(*tail)->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return l2;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
trlist(Map *map, uvlong pc, uvlong sp, Symbol *sym)
|
|
|
|
{
|
|
|
|
List *q, *l;
|
|
|
|
|
|
|
|
static List **tail;
|
|
|
|
|
|
|
|
if (tracelist == 0) { /* first time */
|
|
|
|
tracelist = al(TLIST);
|
|
|
|
tail = &tracelist;
|
|
|
|
}
|
|
|
|
|
|
|
|
q = al(TLIST);
|
|
|
|
*tail = q;
|
|
|
|
tail = &q->next;
|
|
|
|
|
|
|
|
l = al(TINT); /* Function address */
|
|
|
|
q->l = l;
|
|
|
|
l->ival = sym->value;
|
2014-02-09 21:43:09 +00:00
|
|
|
l->fmt = 'A';
|
2011-03-30 12:46:40 +00:00
|
|
|
|
|
|
|
l->next = al(TINT); /* called from address */
|
|
|
|
l = l->next;
|
|
|
|
l->ival = pc;
|
|
|
|
l->fmt = 'Y';
|
|
|
|
|
|
|
|
l->next = al(TLIST); /* make list of params */
|
|
|
|
l = l->next;
|
|
|
|
l->l = listparams(map, sym, sp);
|
|
|
|
|
|
|
|
l->next = al(TLIST); /* make list of locals */
|
|
|
|
l = l->next;
|
|
|
|
l->l = listlocals(map, sym, sp);
|
|
|
|
}
|