value.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /* $Header$ */
  2. #include <alloc.h>
  3. #include <assert.h>
  4. #include "position.h"
  5. #include "scope.h"
  6. #include "idf.h"
  7. #include "symbol.h"
  8. #include "type.h"
  9. #include "message.h"
  10. #include "langdep.h"
  11. #include "expr.h"
  12. int stack_offset; /* for up and down commands */
  13. extern long pointer_size;
  14. extern t_addr *get_EM_regs();
  15. extern char *memcpy();
  16. /* Get the address of the object indicated by sym.
  17. Return 0 on failure,
  18. address on success.
  19. *psize will contain size of object.
  20. */
  21. t_addr
  22. get_addr(sym, psize)
  23. register p_symbol sym;
  24. long *psize;
  25. {
  26. p_type tp = sym->sy_type;
  27. long size = tp->ty_size;
  28. t_addr *EM_regs;
  29. int i;
  30. p_scope sc, symsc;
  31. *psize = size;
  32. switch(sym->sy_class) {
  33. case VAR:
  34. /* exists if child exists; nm_value contains addres */
  35. return (t_addr) sym->sy_name.nm_value;
  36. case VARPAR:
  37. case LOCVAR:
  38. /* first find the stack frame in which it resides */
  39. symsc = base_scope(sym->sy_scope);
  40. /* now symsc contains the scope where the storage for sym is
  41. allocated. Now find it on the stack of child.
  42. */
  43. i = stack_offset;
  44. for (;;) {
  45. sc = 0;
  46. if (! (EM_regs = get_EM_regs(i++))) {
  47. return 0;
  48. }
  49. if (! EM_regs[1]) {
  50. error("%s not available", sym->sy_idf->id_text);
  51. return 0;
  52. }
  53. sc = base_scope(get_scope_from_addr(EM_regs[2]));
  54. if (! sc || sc->sc_start > EM_regs[2]) {
  55. error("%s not available", sym->sy_idf->id_text);
  56. sc = 0;
  57. return 0;
  58. }
  59. if (sc == symsc) break; /* found it */
  60. }
  61. if (sym->sy_class == LOCVAR) {
  62. /* Either local variable or value parameter */
  63. return EM_regs[sym->sy_name.nm_value < 0 ? 0 : 1] +
  64. (t_addr) sym->sy_name.nm_value;
  65. }
  66. /* If we get here, we have a var parameter. Get the parameters
  67. of the current procedure invocation.
  68. */
  69. {
  70. p_type proctype = sc->sc_definedby->sy_type;
  71. t_addr a;
  72. char *AB;
  73. size = proctype->ty_nbparams;
  74. if (has_static_link(sc)) size += pointer_size;
  75. AB = malloc((unsigned) size);
  76. if (! AB) {
  77. error("could not allocate enough memory");
  78. break;
  79. }
  80. if (! get_bytes(size, EM_regs[1], AB)) {
  81. break;
  82. }
  83. if ((size = tp->ty_size) == 0) {
  84. size = compute_size(tp, AB);
  85. *psize = size;
  86. }
  87. a = (t_addr) get_int(AB+sym->sy_name.nm_value, pointer_size, T_UNSIGNED);
  88. free(AB);
  89. return a;
  90. }
  91. default:
  92. error("%s is not a variable", sym->sy_idf->id_text);
  93. break;
  94. }
  95. return 0;
  96. }
  97. /* Get the value of the symbol indicated by sym.
  98. Return 0 on failure,
  99. 1 on success.
  100. On success, 'buf' contains the value, and 'size' contains the size.
  101. For 'buf', storage is allocated by malloc; this storage must
  102. be freed by caller (I don't like this any more than you do, but caller
  103. does not know sizes).
  104. */
  105. int
  106. get_value(sym, buf, psize)
  107. register p_symbol sym;
  108. char **buf;
  109. long *psize;
  110. {
  111. p_type tp = sym->sy_type;
  112. int retval = 0;
  113. t_addr a;
  114. long size = tp->ty_size;
  115. *buf = 0;
  116. switch(sym->sy_class) {
  117. case CONST:
  118. *buf = malloc((unsigned) size);
  119. if (! *buf) {
  120. error("could not allocate enough memory");
  121. break;
  122. }
  123. switch(tp->ty_class) {
  124. case T_REAL:
  125. put_real(*buf, size, sym->sy_const.co_rval);
  126. break;
  127. case T_INTEGER:
  128. case T_SUBRANGE:
  129. case T_UNSIGNED:
  130. case T_ENUM:
  131. put_int(*buf, size, sym->sy_const.co_ival);
  132. break;
  133. case T_SET:
  134. memcpy(*buf, sym->sy_const.co_setval, (int) size);
  135. break;
  136. case T_STRING:
  137. memcpy(*buf, sym->sy_const.co_sval, (int) size);
  138. break;
  139. default:
  140. fatal("strange constant");
  141. }
  142. retval = 1;
  143. break;
  144. case VAR:
  145. case VARPAR:
  146. case LOCVAR:
  147. a = get_addr(sym, psize);
  148. if (a) {
  149. size = *psize;
  150. *buf = malloc((unsigned) size);
  151. if (! *buf) {
  152. error("could not allocate enough memory");
  153. break;
  154. }
  155. if (get_bytes(size, a, *buf)) {
  156. retval = 1;
  157. }
  158. }
  159. break;
  160. }
  161. if (retval == 0) {
  162. if (*buf) free(*buf);
  163. *buf = 0;
  164. *psize = 0;
  165. }
  166. else *psize = size;
  167. return retval;
  168. }