123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- /* $Header$ */
- #include <alloc.h>
- #include <assert.h>
- #include "position.h"
- #include "scope.h"
- #include "idf.h"
- #include "symbol.h"
- #include "type.h"
- #include "message.h"
- #include "langdep.h"
- #include "expr.h"
- int stack_offset; /* for up and down commands */
- extern long pointer_size;
- extern t_addr *get_EM_regs();
- extern char *memcpy();
- /* Get the address of the object indicated by sym.
- Return 0 on failure,
- address on success.
- *psize will contain size of object.
- */
- t_addr
- get_addr(sym, psize)
- register p_symbol sym;
- long *psize;
- {
- p_type tp = sym->sy_type;
- long size = tp->ty_size;
- t_addr *EM_regs;
- int i;
- p_scope sc, symsc;
- *psize = size;
- switch(sym->sy_class) {
- case VAR:
- /* exists if child exists; nm_value contains addres */
- return (t_addr) sym->sy_name.nm_value;
- case VARPAR:
- case LOCVAR:
- /* first find the stack frame in which it resides */
- symsc = base_scope(sym->sy_scope);
- /* now symsc contains the scope where the storage for sym is
- allocated. Now find it on the stack of child.
- */
- i = stack_offset;
- for (;;) {
- sc = 0;
- if (! (EM_regs = get_EM_regs(i++))) {
- return 0;
- }
- if (! EM_regs[1]) {
- error("%s not available", sym->sy_idf->id_text);
- return 0;
- }
- sc = base_scope(get_scope_from_addr(EM_regs[2]));
- if (! sc || sc->sc_start > EM_regs[2]) {
- error("%s not available", sym->sy_idf->id_text);
- sc = 0;
- return 0;
- }
- if (sc == symsc) break; /* found it */
- }
- if (sym->sy_class == LOCVAR) {
- /* Either local variable or value parameter */
- return EM_regs[sym->sy_name.nm_value < 0 ? 0 : 1] +
- (t_addr) sym->sy_name.nm_value;
- }
- /* If we get here, we have a var parameter. Get the parameters
- of the current procedure invocation.
- */
- {
- p_type proctype = sc->sc_definedby->sy_type;
- t_addr a;
- char *AB;
- size = proctype->ty_nbparams;
- if (has_static_link(sc)) size += pointer_size;
- AB = malloc((unsigned) size);
- if (! AB) {
- error("could not allocate enough memory");
- break;
- }
- if (! get_bytes(size, EM_regs[1], AB)) {
- break;
- }
- if ((size = tp->ty_size) == 0) {
- size = compute_size(tp, AB);
- *psize = size;
- }
- a = (t_addr) get_int(AB+sym->sy_name.nm_value, pointer_size, T_UNSIGNED);
- free(AB);
- return a;
- }
- default:
- error("%s is not a variable", sym->sy_idf->id_text);
- break;
- }
- return 0;
- }
- /* Get the value of the symbol indicated by sym.
- Return 0 on failure,
- 1 on success.
- On success, 'buf' contains the value, and 'size' contains the size.
- For 'buf', storage is allocated by malloc; this storage must
- be freed by caller (I don't like this any more than you do, but caller
- does not know sizes).
- */
- int
- get_value(sym, buf, psize)
- register p_symbol sym;
- char **buf;
- long *psize;
- {
- p_type tp = sym->sy_type;
- int retval = 0;
- t_addr a;
- long size = tp->ty_size;
- *buf = 0;
- switch(sym->sy_class) {
- case CONST:
- *buf = malloc((unsigned) size);
- if (! *buf) {
- error("could not allocate enough memory");
- break;
- }
- switch(tp->ty_class) {
- case T_REAL:
- put_real(*buf, size, sym->sy_const.co_rval);
- break;
- case T_INTEGER:
- case T_SUBRANGE:
- case T_UNSIGNED:
- case T_ENUM:
- put_int(*buf, size, sym->sy_const.co_ival);
- break;
- case T_SET:
- memcpy(*buf, sym->sy_const.co_setval, (int) size);
- break;
- case T_STRING:
- memcpy(*buf, sym->sy_const.co_sval, (int) size);
- break;
- default:
- fatal("strange constant");
- }
- retval = 1;
- break;
- case VAR:
- case VARPAR:
- case LOCVAR:
- a = get_addr(sym, psize);
- if (a) {
- size = *psize;
- *buf = malloc((unsigned) size);
- if (! *buf) {
- error("could not allocate enough memory");
- break;
- }
- if (get_bytes(size, a, *buf)) {
- retval = 1;
- }
- }
- break;
- }
- if (retval == 0) {
- if (*buf) free(*buf);
- *buf = 0;
- *psize = 0;
- }
- else *psize = size;
- return retval;
- }
|