programs.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /* Copyright (C) 2001, 2009, 2010, 2011, 2012, 2013, 2014 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 <string.h>
  22. #include "_scm.h"
  23. #include "modules.h"
  24. #include "programs.h"
  25. #include "procprop.h" /* scm_sym_name */
  26. #include "vm.h"
  27. static SCM write_program = SCM_BOOL_F;
  28. SCM_DEFINE (scm_program_code, "program-code", 1, 0, 0,
  29. (SCM program),
  30. "")
  31. #define FUNC_NAME s_scm_program_code
  32. {
  33. SCM_VALIDATE_PROGRAM (1, program);
  34. return scm_from_uintptr_t ((scm_t_uintptr) SCM_PROGRAM_CODE (program));
  35. }
  36. #undef FUNC_NAME
  37. SCM
  38. scm_i_program_name (SCM program)
  39. {
  40. static SCM program_name = SCM_BOOL_F;
  41. if (SCM_PRIMITIVE_P (program))
  42. return SCM_SUBR_NAME (program);
  43. if (scm_is_false (program_name) && scm_module_system_booted_p)
  44. program_name =
  45. scm_c_private_variable ("system vm program", "program-name");
  46. return scm_call_1 (scm_variable_ref (program_name), program);
  47. }
  48. SCM
  49. scm_i_program_documentation (SCM program)
  50. {
  51. static SCM program_documentation = SCM_BOOL_F;
  52. if (SCM_PRIMITIVE_P (program))
  53. return SCM_BOOL_F;
  54. if (scm_is_false (program_documentation) && scm_module_system_booted_p)
  55. program_documentation =
  56. scm_c_private_variable ("system vm program", "program-documentation");
  57. return scm_call_1 (scm_variable_ref (program_documentation), program);
  58. }
  59. SCM
  60. scm_i_program_properties (SCM program)
  61. {
  62. static SCM program_properties = SCM_BOOL_F;
  63. if (SCM_PRIMITIVE_P (program))
  64. {
  65. SCM name = scm_i_program_name (program);
  66. if (scm_is_false (name))
  67. return SCM_EOL;
  68. return scm_acons (scm_sym_name, name, SCM_EOL);
  69. }
  70. if (scm_is_false (program_properties) && scm_module_system_booted_p)
  71. program_properties =
  72. scm_c_private_variable ("system vm program", "program-properties");
  73. return scm_call_1 (scm_variable_ref (program_properties), program);
  74. }
  75. void
  76. scm_i_program_print (SCM program, SCM port, scm_print_state *pstate)
  77. {
  78. static int print_error = 0;
  79. if (scm_is_false (write_program) && scm_module_system_booted_p)
  80. write_program = scm_c_private_variable ("system vm program",
  81. "write-program");
  82. if (SCM_PROGRAM_IS_CONTINUATION (program))
  83. {
  84. /* twingliness */
  85. scm_puts_unlocked ("#<continuation ", port);
  86. scm_uintprint (SCM_UNPACK (program), 16, port);
  87. scm_putc_unlocked ('>', port);
  88. }
  89. else if (SCM_PROGRAM_IS_PARTIAL_CONTINUATION (program))
  90. {
  91. /* twingliness */
  92. scm_puts_unlocked ("#<partial-continuation ", port);
  93. scm_uintprint (SCM_UNPACK (program), 16, port);
  94. scm_putc_unlocked ('>', port);
  95. }
  96. else if (scm_is_false (write_program) || print_error)
  97. {
  98. scm_puts_unlocked ("#<program ", port);
  99. scm_uintprint (SCM_UNPACK (program), 16, port);
  100. scm_putc_unlocked (' ', port);
  101. scm_uintprint ((scm_t_uintptr) SCM_PROGRAM_CODE (program), 16, port);
  102. scm_putc_unlocked ('>', port);
  103. }
  104. else
  105. {
  106. print_error = 1;
  107. scm_call_2 (SCM_VARIABLE_REF (write_program), program, port);
  108. print_error = 0;
  109. }
  110. }
  111. /*
  112. * Scheme interface
  113. */
  114. SCM_DEFINE (scm_program_p, "program?", 1, 0, 0,
  115. (SCM obj),
  116. "")
  117. #define FUNC_NAME s_scm_program_p
  118. {
  119. return scm_from_bool (SCM_PROGRAM_P (obj));
  120. }
  121. #undef FUNC_NAME
  122. SCM_DEFINE (scm_primitive_code_p, "primitive-code?", 1, 0, 0,
  123. (SCM code),
  124. "")
  125. #define FUNC_NAME s_scm_primitive_code_p
  126. {
  127. const scm_t_uint32 * ptr = (const scm_t_uint32 *) scm_to_uintptr_t (code);
  128. return scm_from_bool (scm_i_primitive_code_p (ptr));
  129. }
  130. #undef FUNC_NAME
  131. SCM_DEFINE (scm_primitive_call_ip, "primitive-call-ip", 1, 0, 0,
  132. (SCM prim),
  133. "")
  134. #define FUNC_NAME s_scm_primitive_call_ip
  135. {
  136. SCM_MAKE_VALIDATE (1, prim, PRIMITIVE_P);
  137. return scm_from_uintptr_t (scm_i_primitive_call_ip (prim));
  138. }
  139. #undef FUNC_NAME
  140. SCM
  141. scm_find_source_for_addr (SCM ip)
  142. {
  143. static SCM source_for_addr = SCM_BOOL_F;
  144. if (scm_is_false (source_for_addr)) {
  145. if (!scm_module_system_booted_p)
  146. return SCM_BOOL_F;
  147. source_for_addr =
  148. scm_c_private_variable ("system vm program", "source-for-addr");
  149. }
  150. return scm_call_1 (scm_variable_ref (source_for_addr), ip);
  151. }
  152. SCM
  153. scm_program_address_range (SCM program)
  154. {
  155. static SCM program_address_range = SCM_BOOL_F;
  156. if (scm_is_false (program_address_range) && scm_module_system_booted_p)
  157. program_address_range =
  158. scm_c_private_variable ("system vm program", "program-address-range");
  159. return scm_call_1 (scm_variable_ref (program_address_range), program);
  160. }
  161. SCM_DEFINE (scm_program_num_free_variables, "program-num-free-variables", 1, 0, 0,
  162. (SCM program),
  163. "")
  164. #define FUNC_NAME s_scm_program_num_free_variables
  165. {
  166. SCM_VALIDATE_PROGRAM (1, program);
  167. return scm_from_ulong (SCM_PROGRAM_NUM_FREE_VARIABLES (program));
  168. }
  169. #undef FUNC_NAME
  170. SCM_DEFINE (scm_program_free_variable_ref, "program-free-variable-ref", 2, 0, 0,
  171. (SCM program, SCM i),
  172. "")
  173. #define FUNC_NAME s_scm_program_free_variable_ref
  174. {
  175. unsigned long idx;
  176. SCM_VALIDATE_PROGRAM (1, program);
  177. SCM_VALIDATE_ULONG_COPY (2, i, idx);
  178. if (idx >= SCM_PROGRAM_NUM_FREE_VARIABLES (program))
  179. SCM_OUT_OF_RANGE (2, i);
  180. return SCM_PROGRAM_FREE_VARIABLE_REF (program, idx);
  181. }
  182. #undef FUNC_NAME
  183. SCM_DEFINE (scm_program_free_variable_set_x, "program-free-variable-set!", 3, 0, 0,
  184. (SCM program, SCM i, SCM x),
  185. "")
  186. #define FUNC_NAME s_scm_program_free_variable_set_x
  187. {
  188. unsigned long idx;
  189. SCM_VALIDATE_PROGRAM (1, program);
  190. SCM_VALIDATE_ULONG_COPY (2, i, idx);
  191. if (idx >= SCM_PROGRAM_NUM_FREE_VARIABLES (program))
  192. SCM_OUT_OF_RANGE (2, i);
  193. SCM_PROGRAM_FREE_VARIABLE_SET (program, idx, x);
  194. return SCM_UNSPECIFIED;
  195. }
  196. #undef FUNC_NAME
  197. int
  198. scm_i_program_arity (SCM program, int *req, int *opt, int *rest)
  199. {
  200. static SCM program_minimum_arity = SCM_BOOL_F;
  201. SCM l;
  202. if (SCM_PRIMITIVE_P (program))
  203. return scm_i_primitive_arity (program, req, opt, rest);
  204. if (SCM_PROGRAM_IS_FOREIGN (program))
  205. return scm_i_foreign_arity (program, req, opt, rest);
  206. if (SCM_PROGRAM_IS_CONTINUATION (program)
  207. || SCM_PROGRAM_IS_PARTIAL_CONTINUATION (program))
  208. {
  209. *req = *opt = 0;
  210. *rest = 1;
  211. return 1;
  212. }
  213. if (scm_is_false (program_minimum_arity) && scm_module_system_booted_p)
  214. program_minimum_arity =
  215. scm_c_private_variable ("system vm program", "program-minimum-arity");
  216. l = scm_call_1 (scm_variable_ref (program_minimum_arity), program);
  217. if (scm_is_false (l))
  218. return 0;
  219. *req = scm_to_int (scm_car (l));
  220. *opt = scm_to_int (scm_cadr (l));
  221. *rest = scm_is_true (scm_caddr (l));
  222. return 1;
  223. }
  224. void
  225. scm_bootstrap_programs (void)
  226. {
  227. scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
  228. "scm_init_programs",
  229. (scm_t_extension_init_func)scm_init_programs, NULL);
  230. }
  231. void
  232. scm_init_programs (void)
  233. {
  234. #ifndef SCM_MAGIC_SNARFER
  235. #include "libguile/programs.x"
  236. #endif
  237. }
  238. /*
  239. Local Variables:
  240. c-file-style: "gnu"
  241. End:
  242. */