vm-engine.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /* Copyright (C) 2001, 2009 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. /* This file is included in vm.c multiple times */
  19. #if (VM_ENGINE == SCM_VM_REGULAR_ENGINE)
  20. #define VM_USE_HOOKS 0 /* Various hooks */
  21. #define VM_USE_CLOCK 0 /* Bogoclock */
  22. #define VM_CHECK_OBJECT 1 /* Check object table */
  23. #define VM_CHECK_FREE_VARIABLES 1 /* Check free variable access */
  24. #define VM_PUSH_DEBUG_FRAMES 0 /* Push frames onto the evaluator debug stack */
  25. #elif (VM_ENGINE == SCM_VM_DEBUG_ENGINE)
  26. #define VM_USE_HOOKS 1
  27. #define VM_USE_CLOCK 1
  28. #define VM_CHECK_OBJECT 1
  29. #define VM_CHECK_FREE_VARIABLES 1
  30. #define VM_PUSH_DEBUG_FRAMES 1
  31. #else
  32. #error unknown debug engine VM_ENGINE
  33. #endif
  34. #include "vm-engine.h"
  35. static SCM
  36. VM_NAME (struct scm_vm *vp, SCM program, SCM *argv, int nargs)
  37. {
  38. /* VM registers */
  39. register scm_byte_t *ip IP_REG; /* instruction pointer */
  40. register SCM *sp SP_REG; /* stack pointer */
  41. register SCM *fp FP_REG; /* frame pointer */
  42. /* Cache variables */
  43. struct scm_objcode *bp = NULL; /* program base pointer */
  44. SCM *free_vars = NULL; /* free variables */
  45. size_t free_vars_count = 0; /* length of FREE_VARS */
  46. SCM *objects = NULL; /* constant objects */
  47. size_t object_count = 0; /* length of OBJECTS */
  48. SCM *stack_base = vp->stack_base; /* stack base address */
  49. SCM *stack_limit = vp->stack_limit; /* stack limit address */
  50. /* Internal variables */
  51. int nvalues = 0;
  52. long start_time = scm_c_get_internal_run_time ();
  53. SCM finish_args; /* used both for returns: both in error
  54. and normal situations */
  55. #if VM_USE_HOOKS
  56. SCM hook_args = SCM_EOL;
  57. #endif
  58. #ifdef HAVE_LABELS_AS_VALUES
  59. static void **jump_table = NULL;
  60. #endif
  61. #if VM_PUSH_DEBUG_FRAMES
  62. scm_t_debug_frame debug;
  63. scm_t_debug_info debug_vect_body;
  64. debug.status = SCM_VOIDFRAME;
  65. #endif
  66. #ifdef HAVE_LABELS_AS_VALUES
  67. if (SCM_UNLIKELY (!jump_table))
  68. {
  69. int i;
  70. jump_table = malloc (SCM_VM_NUM_INSTRUCTIONS * sizeof(void*));
  71. for (i = 0; i < SCM_VM_NUM_INSTRUCTIONS; i++)
  72. jump_table[i] = &&vm_error_bad_instruction;
  73. #define VM_INSTRUCTION_TO_LABEL 1
  74. #include <libguile/vm-expand.h>
  75. #include <libguile/vm-i-system.i>
  76. #include <libguile/vm-i-scheme.i>
  77. #include <libguile/vm-i-loader.i>
  78. #undef VM_INSTRUCTION_TO_LABEL
  79. }
  80. #endif
  81. /* Initialization */
  82. {
  83. SCM prog = program;
  84. /* Boot program */
  85. program = vm_make_boot_program (nargs);
  86. #if VM_PUSH_DEBUG_FRAMES
  87. debug.prev = scm_i_last_debug_frame ();
  88. debug.status = SCM_APPLYFRAME;
  89. debug.vect = &debug_vect_body;
  90. debug.vect[0].a.proc = program; /* the boot program */
  91. debug.vect[0].a.args = SCM_EOL;
  92. scm_i_set_last_debug_frame (&debug);
  93. #endif
  94. /* Initial frame */
  95. CACHE_REGISTER ();
  96. CACHE_PROGRAM ();
  97. PUSH (program);
  98. NEW_FRAME ();
  99. /* Initial arguments */
  100. PUSH (prog);
  101. if (SCM_UNLIKELY (sp + nargs >= stack_limit))
  102. goto vm_error_too_many_args;
  103. while (nargs--)
  104. PUSH (*argv++);
  105. }
  106. /* Let's go! */
  107. BOOT_HOOK ();
  108. NEXT;
  109. #ifndef HAVE_LABELS_AS_VALUES
  110. vm_start:
  111. switch ((*ip++) & SCM_VM_INSTRUCTION_MASK) {
  112. #endif
  113. #include "vm-expand.h"
  114. #include "vm-i-system.c"
  115. #include "vm-i-scheme.c"
  116. #include "vm-i-loader.c"
  117. #ifndef HAVE_LABELS_AS_VALUES
  118. default:
  119. goto vm_error_bad_instruction;
  120. }
  121. #endif
  122. vm_done:
  123. SYNC_ALL ();
  124. #if VM_PUSH_DEBUG_FRAMES
  125. scm_i_set_last_debug_frame (debug.prev);
  126. #endif
  127. return finish_args;
  128. /* Errors */
  129. {
  130. SCM err_msg;
  131. vm_error_bad_instruction:
  132. err_msg = scm_from_locale_string ("VM: Bad instruction: ~A");
  133. finish_args = scm_list_1 (scm_from_uchar (ip[-1]));
  134. goto vm_error;
  135. vm_error_unbound:
  136. err_msg = scm_from_locale_string ("VM: Unbound variable: ~A");
  137. goto vm_error;
  138. vm_error_wrong_type_arg:
  139. err_msg = scm_from_locale_string ("VM: Wrong type argument");
  140. finish_args = SCM_EOL;
  141. goto vm_error;
  142. vm_error_too_many_args:
  143. err_msg = scm_from_locale_string ("VM: Too many arguments");
  144. finish_args = scm_list_1 (scm_from_int (nargs));
  145. goto vm_error;
  146. vm_error_wrong_num_args:
  147. /* nargs and program are valid */
  148. SYNC_ALL ();
  149. scm_wrong_num_args (program);
  150. /* shouldn't get here */
  151. goto vm_error;
  152. vm_error_wrong_type_apply:
  153. err_msg = scm_from_locale_string ("VM: Wrong type to apply: ~S "
  154. "[IP offset: ~a]");
  155. finish_args = scm_list_2 (program,
  156. SCM_I_MAKINUM (ip - bp->base));
  157. goto vm_error;
  158. vm_error_stack_overflow:
  159. err_msg = scm_from_locale_string ("VM: Stack overflow");
  160. finish_args = SCM_EOL;
  161. goto vm_error;
  162. vm_error_stack_underflow:
  163. err_msg = scm_from_locale_string ("VM: Stack underflow");
  164. finish_args = SCM_EOL;
  165. goto vm_error;
  166. vm_error_improper_list:
  167. err_msg = scm_from_locale_string ("VM: Attempt to unroll an improper list: tail is ~A");
  168. goto vm_error;
  169. vm_error_not_a_pair:
  170. SYNC_ALL ();
  171. scm_wrong_type_arg_msg (FUNC_NAME, 1, finish_args, "pair");
  172. /* shouldn't get here */
  173. goto vm_error;
  174. vm_error_not_a_bytevector:
  175. SYNC_ALL ();
  176. scm_wrong_type_arg_msg (FUNC_NAME, 1, finish_args, "bytevector");
  177. /* shouldn't get here */
  178. goto vm_error;
  179. vm_error_no_values:
  180. err_msg = scm_from_locale_string ("VM: 0-valued return");
  181. finish_args = SCM_EOL;
  182. goto vm_error;
  183. vm_error_not_enough_values:
  184. err_msg = scm_from_locale_string ("VM: Not enough values for mv-bind");
  185. finish_args = SCM_EOL;
  186. goto vm_error;
  187. vm_error_bad_wide_string_length:
  188. err_msg = scm_from_locale_string ("VM: Bad wide string length: ~S");
  189. goto vm_error;
  190. #if VM_CHECK_IP
  191. vm_error_invalid_address:
  192. err_msg = scm_from_locale_string ("VM: Invalid program address");
  193. finish_args = SCM_EOL;
  194. goto vm_error;
  195. #endif
  196. #if VM_CHECK_OBJECT
  197. vm_error_object:
  198. err_msg = scm_from_locale_string ("VM: Invalid object table access");
  199. finish_args = SCM_EOL;
  200. goto vm_error;
  201. #endif
  202. #if VM_CHECK_FREE_VARIABLES
  203. vm_error_free_variable:
  204. err_msg = scm_from_locale_string ("VM: Invalid free variable access");
  205. finish_args = SCM_EOL;
  206. goto vm_error;
  207. #endif
  208. vm_error:
  209. SYNC_ALL ();
  210. scm_ithrow (sym_vm_error, scm_list_3 (sym_vm_run, err_msg, finish_args),
  211. 1);
  212. }
  213. abort (); /* never reached */
  214. }
  215. #undef VM_USE_HOOKS
  216. #undef VM_USE_CLOCK
  217. #undef VM_CHECK_OBJECT
  218. #undef VM_CHECK_FREE_VARIABLE
  219. #undef VM_PUSH_DEBUG_FRAMES
  220. /*
  221. Local Variables:
  222. c-file-style: "gnu"
  223. End:
  224. */