frames.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /* Copyright (C) 2001, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
  2. *
  3. * This library is free software; you can redistribute it and/or
  4. * modify it under the terms of the GNU Lesser General Public License
  5. * as published by the Free Software Foundation; either version 3 of
  6. * the License, or (at your option) any later version.
  7. *
  8. * This library is distributed in the hope that it will be useful, but
  9. * WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * Lesser General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Lesser General Public
  14. * License along with this library; if not, write to the Free Software
  15. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  16. * 02110-1301 USA
  17. */
  18. #if HAVE_CONFIG_H
  19. # include <config.h>
  20. #endif
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include "_scm.h"
  24. #include "frames.h"
  25. #include <verify.h>
  26. /* Make sure assumptions on the layout of `struct scm_vm_frame' hold. */
  27. verify (sizeof (SCM) == sizeof (SCM *));
  28. verify (sizeof (struct scm_vm_frame) == 5 * sizeof (SCM));
  29. verify (offsetof (struct scm_vm_frame, dynamic_link) == 0);
  30. #define RELOC(frame, val) \
  31. (((SCM *) (val)) + SCM_VM_FRAME_OFFSET (frame))
  32. SCM
  33. scm_c_make_frame (SCM stack_holder, SCM *fp, SCM *sp,
  34. scm_t_uint8 *ip, scm_t_ptrdiff offset)
  35. {
  36. struct scm_frame *p = scm_gc_malloc (sizeof (struct scm_frame),
  37. "vmframe");
  38. p->stack_holder = stack_holder;
  39. p->fp = fp;
  40. p->sp = sp;
  41. p->ip = ip;
  42. p->offset = offset;
  43. return scm_cell (scm_tc7_frame, (scm_t_bits)p);
  44. }
  45. void
  46. scm_i_frame_print (SCM frame, SCM port, scm_print_state *pstate)
  47. {
  48. scm_puts_unlocked ("#<frame ", port);
  49. scm_uintprint (SCM_UNPACK (frame), 16, port);
  50. scm_putc_unlocked (' ', port);
  51. scm_write (scm_frame_procedure (frame), port);
  52. /* don't write args, they can get us into trouble. */
  53. scm_puts_unlocked (">", port);
  54. }
  55. /* Scheme interface */
  56. SCM_DEFINE (scm_frame_p, "frame?", 1, 0, 0,
  57. (SCM obj),
  58. "")
  59. #define FUNC_NAME s_scm_frame_p
  60. {
  61. return scm_from_bool (SCM_VM_FRAME_P (obj));
  62. }
  63. #undef FUNC_NAME
  64. SCM_DEFINE (scm_frame_procedure, "frame-procedure", 1, 0, 0,
  65. (SCM frame),
  66. "")
  67. #define FUNC_NAME s_scm_frame_procedure
  68. {
  69. SCM_VALIDATE_VM_FRAME (1, frame);
  70. return SCM_FRAME_PROGRAM (SCM_VM_FRAME_FP (frame));
  71. }
  72. #undef FUNC_NAME
  73. SCM_DEFINE (scm_frame_arguments, "frame-arguments", 1, 0, 0,
  74. (SCM frame),
  75. "")
  76. #define FUNC_NAME s_scm_frame_arguments
  77. {
  78. static SCM var = SCM_BOOL_F;
  79. SCM_VALIDATE_VM_FRAME (1, frame);
  80. if (scm_is_false (var))
  81. var = scm_c_module_lookup (scm_c_resolve_module ("system vm frame"),
  82. "frame-arguments");
  83. return scm_call_1 (SCM_VARIABLE_REF (var), frame);
  84. }
  85. #undef FUNC_NAME
  86. SCM_DEFINE (scm_frame_source, "frame-source", 1, 0, 0,
  87. (SCM frame),
  88. "")
  89. #define FUNC_NAME s_scm_frame_source
  90. {
  91. SCM_VALIDATE_VM_FRAME (1, frame);
  92. return scm_program_source (scm_frame_procedure (frame),
  93. scm_frame_instruction_pointer (frame),
  94. SCM_UNDEFINED);
  95. }
  96. #undef FUNC_NAME
  97. /* The number of locals would be a simple thing to compute, if it weren't for
  98. the presence of not-yet-active frames on the stack. So we have a cheap
  99. heuristic to detect not-yet-active frames, and skip over them. Perhaps we
  100. should represent them more usefully.
  101. */
  102. SCM_DEFINE (scm_frame_num_locals, "frame-num-locals", 1, 0, 0,
  103. (SCM frame),
  104. "")
  105. #define FUNC_NAME s_scm_frame_num_locals
  106. {
  107. SCM *sp, *p;
  108. unsigned int n = 0;
  109. SCM_VALIDATE_VM_FRAME (1, frame);
  110. sp = SCM_VM_FRAME_SP (frame);
  111. p = SCM_FRAME_STACK_ADDRESS (SCM_VM_FRAME_FP (frame));
  112. while (p <= sp)
  113. {
  114. if (SCM_UNPACK (p[0]) == 0)
  115. /* skip over not-yet-active frame */
  116. p += 3;
  117. else
  118. {
  119. p++;
  120. n++;
  121. }
  122. }
  123. return scm_from_uint (n);
  124. }
  125. #undef FUNC_NAME
  126. /* Need same not-yet-active frame logic here as in frame-num-locals */
  127. SCM_DEFINE (scm_frame_local_ref, "frame-local-ref", 2, 0, 0,
  128. (SCM frame, SCM index),
  129. "")
  130. #define FUNC_NAME s_scm_frame_local_ref
  131. {
  132. SCM *sp, *p;
  133. unsigned int n = 0;
  134. unsigned int i;
  135. SCM_VALIDATE_VM_FRAME (1, frame);
  136. SCM_VALIDATE_UINT_COPY (2, index, i);
  137. sp = SCM_VM_FRAME_SP (frame);
  138. p = SCM_FRAME_STACK_ADDRESS (SCM_VM_FRAME_FP (frame));
  139. while (p <= sp)
  140. {
  141. if (SCM_UNPACK (p[0]) == 0)
  142. /* skip over not-yet-active frame */
  143. p += 3;
  144. else if (n == i)
  145. return *p;
  146. else
  147. {
  148. p++;
  149. n++;
  150. }
  151. }
  152. SCM_OUT_OF_RANGE (SCM_ARG2, index);
  153. }
  154. #undef FUNC_NAME
  155. /* Need same not-yet-active frame logic here as in frame-num-locals */
  156. SCM_DEFINE (scm_frame_local_set_x, "frame-local-set!", 3, 0, 0,
  157. (SCM frame, SCM index, SCM val),
  158. "")
  159. #define FUNC_NAME s_scm_frame_local_set_x
  160. {
  161. SCM *sp, *p;
  162. unsigned int n = 0;
  163. unsigned int i;
  164. SCM_VALIDATE_VM_FRAME (1, frame);
  165. SCM_VALIDATE_UINT_COPY (2, index, i);
  166. sp = SCM_VM_FRAME_SP (frame);
  167. p = SCM_FRAME_STACK_ADDRESS (SCM_VM_FRAME_FP (frame));
  168. while (p <= sp)
  169. {
  170. if (SCM_UNPACK (p[0]) == 0)
  171. /* skip over not-yet-active frame */
  172. p += 3;
  173. else if (n == i)
  174. {
  175. *p = val;
  176. return SCM_UNSPECIFIED;
  177. }
  178. else
  179. {
  180. p++;
  181. n++;
  182. }
  183. }
  184. SCM_OUT_OF_RANGE (SCM_ARG2, index);
  185. }
  186. #undef FUNC_NAME
  187. SCM_DEFINE (scm_frame_address, "frame-address", 1, 0, 0,
  188. (SCM frame),
  189. "Return the frame pointer for @var{frame}.")
  190. #define FUNC_NAME s_scm_frame_address
  191. {
  192. SCM_VALIDATE_VM_FRAME (1, frame);
  193. return scm_from_unsigned_integer ((scm_t_bits) SCM_VM_FRAME_FP (frame));
  194. }
  195. #undef FUNC_NAME
  196. SCM_DEFINE (scm_frame_stack_pointer, "frame-stack-pointer", 1, 0, 0,
  197. (SCM frame),
  198. "")
  199. #define FUNC_NAME s_scm_frame_stack_pointer
  200. {
  201. SCM_VALIDATE_VM_FRAME (1, frame);
  202. return scm_from_unsigned_integer ((scm_t_bits) SCM_VM_FRAME_SP (frame));
  203. }
  204. #undef FUNC_NAME
  205. SCM_DEFINE (scm_frame_instruction_pointer, "frame-instruction-pointer", 1, 0, 0,
  206. (SCM frame),
  207. "")
  208. #define FUNC_NAME s_scm_frame_instruction_pointer
  209. {
  210. const struct scm_objcode *c_objcode;
  211. SCM_VALIDATE_VM_FRAME (1, frame);
  212. c_objcode = SCM_PROGRAM_DATA (scm_frame_procedure (frame));
  213. return scm_from_unsigned_integer ((SCM_VM_FRAME_IP (frame)
  214. - SCM_C_OBJCODE_BASE (c_objcode)));
  215. }
  216. #undef FUNC_NAME
  217. SCM_DEFINE (scm_frame_return_address, "frame-return-address", 1, 0, 0,
  218. (SCM frame),
  219. "")
  220. #define FUNC_NAME s_scm_frame_return_address
  221. {
  222. SCM_VALIDATE_VM_FRAME (1, frame);
  223. return scm_from_unsigned_integer ((scm_t_bits)
  224. (SCM_FRAME_RETURN_ADDRESS
  225. (SCM_VM_FRAME_FP (frame))));
  226. }
  227. #undef FUNC_NAME
  228. SCM_DEFINE (scm_frame_mv_return_address, "frame-mv-return-address", 1, 0, 0,
  229. (SCM frame),
  230. "")
  231. #define FUNC_NAME s_scm_frame_mv_return_address
  232. {
  233. SCM_VALIDATE_VM_FRAME (1, frame);
  234. return scm_from_unsigned_integer ((scm_t_bits)
  235. (SCM_FRAME_MV_RETURN_ADDRESS
  236. (SCM_VM_FRAME_FP (frame))));
  237. }
  238. #undef FUNC_NAME
  239. SCM_DEFINE (scm_frame_dynamic_link, "frame-dynamic-link", 1, 0, 0,
  240. (SCM frame),
  241. "")
  242. #define FUNC_NAME s_scm_frame_dynamic_link
  243. {
  244. SCM_VALIDATE_VM_FRAME (1, frame);
  245. /* fixme: munge fp if holder is a continuation */
  246. return scm_from_ulong
  247. ((unsigned long)
  248. RELOC (frame,
  249. SCM_FRAME_DYNAMIC_LINK (SCM_VM_FRAME_FP (frame))));
  250. }
  251. #undef FUNC_NAME
  252. SCM_DEFINE (scm_frame_previous, "frame-previous", 1, 0, 0,
  253. (SCM frame),
  254. "")
  255. #define FUNC_NAME s_scm_frame_previous
  256. {
  257. SCM *this_fp, *new_fp, *new_sp;
  258. SCM_VALIDATE_VM_FRAME (1, frame);
  259. again:
  260. this_fp = SCM_VM_FRAME_FP (frame);
  261. new_fp = SCM_FRAME_DYNAMIC_LINK (this_fp);
  262. if (new_fp)
  263. { new_fp = RELOC (frame, new_fp);
  264. new_sp = SCM_FRAME_LOWER_ADDRESS (this_fp) - 1;
  265. frame = scm_c_make_frame (SCM_VM_FRAME_STACK_HOLDER (frame),
  266. new_fp, new_sp,
  267. SCM_FRAME_RETURN_ADDRESS (this_fp),
  268. SCM_VM_FRAME_OFFSET (frame));
  269. if (SCM_PROGRAM_IS_BOOT (scm_frame_procedure (frame)))
  270. goto again;
  271. else
  272. return frame;
  273. }
  274. else
  275. return SCM_BOOL_F;
  276. }
  277. #undef FUNC_NAME
  278. void
  279. scm_init_frames (void)
  280. {
  281. #ifndef SCM_MAGIC_SNARFER
  282. #include "libguile/frames.x"
  283. #endif
  284. }
  285. /*
  286. Local Variables:
  287. c-file-style: "gnu"
  288. End:
  289. */