gsubr.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890
  1. /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2006, 2008, 2009, 2010, 2011 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. #ifdef HAVE_CONFIG_H
  19. # include <config.h>
  20. #endif
  21. #include <stdio.h>
  22. #include <stdarg.h>
  23. #include "libguile/_scm.h"
  24. #include "libguile/gsubr.h"
  25. #include "libguile/foreign.h"
  26. #include "libguile/instructions.h"
  27. #include "libguile/objcodes.h"
  28. #include "libguile/srfi-4.h"
  29. #include "libguile/programs.h"
  30. #include "libguile/private-options.h"
  31. /*
  32. * gsubr.c
  33. * Provide `gsubrs' -- subrs taking a prescribed number of required, optional,
  34. * and rest arguments.
  35. */
  36. /* #define GSUBR_TEST */
  37. /* OK here goes nothing: we're going to define VM assembly trampolines for
  38. invoking subrs, along with their meta-information, and then wrap them into
  39. statically allocated objcode values. Ready? Right!
  40. */
  41. /* There's a maximum of 10 args, so the number of possible combinations is:
  42. (REQ-OPT-REST)
  43. for 0 args: 1 (000) (1 + 0)
  44. for 1 arg: 3 (100, 010, 001) (2 + 1)
  45. for 2 args: 5 (200, 110, 020, 101, 011) (3 + 2)
  46. for 3 args: 7 (300, 210, 120, 030, 201, 111, 021) (4 + 3)
  47. for N args: 2N+1
  48. and the index at which N args starts:
  49. for 0 args: 0
  50. for 1 args: 1
  51. for 2 args: 4
  52. for 3 args: 9
  53. for N args: N^2
  54. One can prove this:
  55. (1 + 3 + 5 + ... + (2N+1))
  56. = ((2N+1)+1)/2 * (N+1)
  57. = 2(N+1)/2 * (N+1)
  58. = (N+1)^2
  59. Thus the total sum is 11^2 = 121. Let's just generate all of them as
  60. read-only data.
  61. */
  62. #ifdef WORDS_BIGENDIAN
  63. #define OBJCODE_HEADER 0, 0, 0, 16, 0, 0, 0, 40
  64. #define META_HEADER 0, 0, 0, 32, 0, 0, 0, 0
  65. #else
  66. #define OBJCODE_HEADER 16, 0, 0, 0, 40, 0, 0, 0
  67. #define META_HEADER 32, 0, 0, 0, 0, 0, 0, 0
  68. #endif
  69. /* A: req; B: opt; C: rest */
  70. #define A(nreq) \
  71. OBJCODE_HEADER, \
  72. /* 0 */ scm_op_assert_nargs_ee, 0, nreq, /* assert number of args */ \
  73. /* 3 */ scm_op_object_ref, 0, /* push the foreign object wrapping the subr pointer */ \
  74. /* 5 */ scm_op_subr_call, nreq, /* and call (will return value as well) */ \
  75. /* 7 */ scm_op_nop, \
  76. /* 8 */ scm_op_nop, scm_op_nop, scm_op_nop, scm_op_nop, \
  77. /* 12 */ scm_op_nop, scm_op_nop, scm_op_nop, scm_op_nop, \
  78. /* 16 */ META (3, 7, nreq, 0, 0)
  79. #define B(nopt) \
  80. OBJCODE_HEADER, \
  81. /* 0 */ scm_op_bind_optionals, 0, nopt, /* bind optionals */ \
  82. /* 3 */ scm_op_assert_nargs_ee, 0, nopt, /* assert number of args */ \
  83. /* 6 */ scm_op_object_ref, 0, /* push the foreign object wrapping the subr pointer */ \
  84. /* 8 */ scm_op_subr_call, nopt, /* and call (will return value as well) */ \
  85. /* 10 */ scm_op_nop, scm_op_nop, \
  86. /* 12 */ scm_op_nop, scm_op_nop, scm_op_nop, scm_op_nop, \
  87. /* 16 */ META (6, 10, 0, nopt, 0)
  88. #define C() \
  89. OBJCODE_HEADER, \
  90. /* 0 */ scm_op_push_rest, 0, 0, /* cons all args into a list */ \
  91. /* 3 */ scm_op_object_ref, 0, /* push the foreign object wrapping the subr pointer */ \
  92. /* 5 */ scm_op_subr_call, 1, /* and call (will return value as well) */ \
  93. /* 7 */ scm_op_nop, \
  94. /* 8 */ scm_op_nop, scm_op_nop, scm_op_nop, scm_op_nop, \
  95. /* 12 */ scm_op_nop, scm_op_nop, scm_op_nop, scm_op_nop, \
  96. /* 16 */ META (3, 7, 0, 0, 1)
  97. #define AB(nreq, nopt) \
  98. OBJCODE_HEADER, \
  99. /* 0 */ scm_op_assert_nargs_ge, 0, nreq, /* assert number of args */ \
  100. /* 3 */ scm_op_bind_optionals, 0, nreq+nopt, /* bind optionals */ \
  101. /* 6 */ scm_op_assert_nargs_ee, 0, nreq+nopt, /* assert number of args */ \
  102. /* 9 */ scm_op_object_ref, 0, /* push the foreign object wrapping the subr pointer */ \
  103. /* 11 */ scm_op_subr_call, nreq+nopt, /* and call (will return value as well) */ \
  104. /* 13 */ scm_op_nop, scm_op_nop, scm_op_nop, \
  105. /* 16 */ META (9, 13, nreq, nopt, 0)
  106. #define AC(nreq) \
  107. OBJCODE_HEADER, \
  108. /* 0 */ scm_op_assert_nargs_ge, 0, nreq, /* assert number of args */ \
  109. /* 3 */ scm_op_push_rest, 0, nreq, /* cons rest list */ \
  110. /* 6 */ scm_op_object_ref, 0, /* push the foreign object wrapping the subr pointer */ \
  111. /* 8 */ scm_op_subr_call, nreq+1, /* and call (will return value as well) */ \
  112. /* 10 */ scm_op_nop, scm_op_nop, \
  113. /* 12 */ scm_op_nop, scm_op_nop, scm_op_nop, scm_op_nop, \
  114. /* 16 */ META (6, 10, nreq, 0, 1)
  115. #define BC(nopt) \
  116. OBJCODE_HEADER, \
  117. /* 0 */ scm_op_bind_optionals, 0, nopt, /* bind optionals */ \
  118. /* 3 */ scm_op_push_rest, 0, nopt, /* cons rest list */ \
  119. /* 6 */ scm_op_object_ref, 0, /* push the foreign object wrapping the subr pointer */ \
  120. /* 8 */ scm_op_subr_call, nopt+1, /* and call (will return value as well) */ \
  121. /* 10 */ scm_op_nop, scm_op_nop, \
  122. /* 12 */ scm_op_nop, scm_op_nop, scm_op_nop, scm_op_nop, \
  123. /* 16 */ META (6, 10, 0, nopt, 1)
  124. #define ABC(nreq, nopt) \
  125. OBJCODE_HEADER, \
  126. /* 0 */ scm_op_assert_nargs_ge, 0, nreq, /* assert number of args */ \
  127. /* 3 */ scm_op_bind_optionals, 0, nreq+nopt, /* bind optionals */ \
  128. /* 6 */ scm_op_push_rest, 0, nreq+nopt, /* cons rest list */ \
  129. /* 9 */ scm_op_object_ref, 0, /* push the foreign object wrapping the subr pointer */ \
  130. /* 11 */ scm_op_subr_call, nreq+nopt+1, /* and call (will return value as well) */ \
  131. /* 13 */ scm_op_nop, scm_op_nop, scm_op_nop, \
  132. /* 16 */ META (9, 13, nreq, nopt, 1)
  133. #define META(start, end, nreq, nopt, rest) \
  134. META_HEADER, \
  135. /* 0 */ scm_op_make_eol, /* bindings */ \
  136. /* 1 */ scm_op_make_eol, /* sources */ \
  137. /* 2 */ scm_op_make_int8, start, scm_op_make_int8, end, /* arity: from ip N to ip N */ \
  138. /* 6 */ scm_op_make_int8, nreq, /* the arity is N required args */ \
  139. /* 8 */ scm_op_make_int8, nopt, /* N optionals */ \
  140. /* 10 */ rest ? scm_op_make_true : scm_op_make_false, /* maybe a rest arg */ \
  141. /* 11 */ scm_op_list, 0, 5, /* make a list of those 5 vals */ \
  142. /* 14 */ scm_op_list, 0, 1, /* and the arities will be a list of that one list */ \
  143. /* 17 */ scm_op_load_symbol, 0, 0, 4, 'n', 'a', 'm', 'e', /* `name' */ \
  144. /* 25 */ scm_op_object_ref, 1, /* the name from the object table */ \
  145. /* 27 */ scm_op_cons, /* make a pair for the properties */ \
  146. /* 28 */ scm_op_list, 0, 4, /* pack bindings, sources, and arities into list */ \
  147. /* 31 */ scm_op_return /* and return */ \
  148. /* 32 */
  149. /*
  150. (defun generate-bytecode (n)
  151. "Generate bytecode for N arguments"
  152. (interactive "p")
  153. (insert (format "/\* %d arguments *\/\n " n))
  154. (let ((nreq n))
  155. (while (<= 0 nreq)
  156. (let ((nopt (- n nreq)))
  157. (insert
  158. (if (< 0 nreq)
  159. (if (< 0 nopt)
  160. (format "AB(%d,%d), " nreq nopt)
  161. (format "A(%d), " nreq))
  162. (if (< 0 nopt)
  163. (format "B(%d), " nopt)
  164. (format "A(0), "))))
  165. (setq nreq (1- nreq))))
  166. (insert "\n ")
  167. (setq nreq (1- n))
  168. (while (<= 0 nreq)
  169. (let ((nopt (- n nreq 1)))
  170. (insert
  171. (if (< 0 nreq)
  172. (if (< 0 nopt)
  173. (format "ABC(%d,%d), " nreq nopt)
  174. (format "AC(%d), " nreq))
  175. (if (< 0 nopt)
  176. (format "BC(%d), " nopt)
  177. (format "C(), "))))
  178. (setq nreq (1- nreq))))
  179. (insert "\n\n ")))
  180. (defun generate-bytecodes (n)
  181. "Generate bytecodes for up to N arguments"
  182. (interactive "p")
  183. (let ((i 0))
  184. (while (<= i n)
  185. (generate-bytecode i)
  186. (setq i (1+ i)))))
  187. */
  188. static const struct
  189. {
  190. scm_t_uint64 dummy; /* ensure 8-byte alignment; perhaps there's a better way */
  191. const scm_t_uint8 bytes[121 * (sizeof (struct scm_objcode) + 16
  192. + sizeof (struct scm_objcode) + 32)];
  193. } raw_bytecode = {
  194. 0,
  195. {
  196. /* C-u 1 0 M-x generate-bytecodes RET */
  197. /* 0 arguments */
  198. A(0),
  199. /* 1 arguments */
  200. A(1), B(1),
  201. C(),
  202. /* 2 arguments */
  203. A(2), AB(1,1), B(2),
  204. AC(1), BC(1),
  205. /* 3 arguments */
  206. A(3), AB(2,1), AB(1,2), B(3),
  207. AC(2), ABC(1,1), BC(2),
  208. /* 4 arguments */
  209. A(4), AB(3,1), AB(2,2), AB(1,3), B(4),
  210. AC(3), ABC(2,1), ABC(1,2), BC(3),
  211. /* 5 arguments */
  212. A(5), AB(4,1), AB(3,2), AB(2,3), AB(1,4), B(5),
  213. AC(4), ABC(3,1), ABC(2,2), ABC(1,3), BC(4),
  214. /* 6 arguments */
  215. A(6), AB(5,1), AB(4,2), AB(3,3), AB(2,4), AB(1,5), B(6),
  216. AC(5), ABC(4,1), ABC(3,2), ABC(2,3), ABC(1,4), BC(5),
  217. /* 7 arguments */
  218. A(7), AB(6,1), AB(5,2), AB(4,3), AB(3,4), AB(2,5), AB(1,6), B(7),
  219. AC(6), ABC(5,1), ABC(4,2), ABC(3,3), ABC(2,4), ABC(1,5), BC(6),
  220. /* 8 arguments */
  221. A(8), AB(7,1), AB(6,2), AB(5,3), AB(4,4), AB(3,5), AB(2,6), AB(1,7), B(8),
  222. AC(7), ABC(6,1), ABC(5,2), ABC(4,3), ABC(3,4), ABC(2,5), ABC(1,6), BC(7),
  223. /* 9 arguments */
  224. A(9), AB(8,1), AB(7,2), AB(6,3), AB(5,4), AB(4,5), AB(3,6), AB(2,7), AB(1,8), B(9),
  225. AC(8), ABC(7,1), ABC(6,2), ABC(5,3), ABC(4,4), ABC(3,5), ABC(2,6), ABC(1,7), BC(8),
  226. /* 10 arguments */
  227. A(10), AB(9,1), AB(8,2), AB(7,3), AB(6,4), AB(5,5), AB(4,6), AB(3,7), AB(2,8), AB(1,9), B(10),
  228. AC(9), ABC(8,1), ABC(7,2), ABC(6,3), ABC(5,4), ABC(4,5), ABC(3,6), ABC(2,7), ABC(1,8), BC(9)
  229. }
  230. };
  231. #undef A
  232. #undef B
  233. #undef C
  234. #undef AB
  235. #undef AC
  236. #undef BC
  237. #undef ABC
  238. #undef OBJCODE_HEADER
  239. #undef META_HEADER
  240. #undef META
  241. /*
  242. ;; (nargs * nargs) + nopt + rest * (nargs + 1)
  243. (defun generate-objcode-cells-helper (n)
  244. "Generate objcode cells for N arguments"
  245. (interactive "p")
  246. (insert (format " /\* %d arguments *\/\n" n))
  247. (let ((nreq n))
  248. (while (<= 0 nreq)
  249. (let ((nopt (- n nreq)))
  250. (insert
  251. (format " { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + %d) },\n"
  252. (* (+ 4 4 16 4 4 32)
  253. (+ (* n n) nopt))))
  254. (insert " { SCM_BOOL_F, SCM_PACK (0) },\n")
  255. (setq nreq (1- nreq))))
  256. (insert "\n")
  257. (setq nreq (1- n))
  258. (while (<= 0 nreq)
  259. (let ((nopt (- n nreq 1)))
  260. (insert
  261. (format " { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + %d) },\n"
  262. (* (+ 4 4 16 4 4 32)
  263. (+ (* n n) nopt n 1))))
  264. (insert " { SCM_BOOL_F, SCM_PACK (0) },\n")
  265. (setq nreq (1- nreq))))
  266. (insert "\n")))
  267. (defun generate-objcode-cells (n)
  268. "Generate objcode cells for up to N arguments"
  269. (interactive "p")
  270. (let ((i 0))
  271. (while (<= i n)
  272. (generate-objcode-cells-helper i)
  273. (setq i (1+ i)))))
  274. */
  275. #define STATIC_OBJCODE_TAG \
  276. SCM_PACK (SCM_MAKE_OBJCODE_TAG (SCM_OBJCODE_TYPE_STATIC, 0))
  277. static const struct
  278. {
  279. scm_t_uint64 dummy; /* alignment */
  280. scm_t_cell cells[121 * 2]; /* 11*11 double cells */
  281. } objcode_cells = {
  282. 0,
  283. /* C-u 1 0 M-x generate-objcode-cells RET */
  284. {
  285. /* 0 arguments */
  286. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 0) },
  287. { SCM_BOOL_F, SCM_PACK (0) },
  288. /* 1 arguments */
  289. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 64) },
  290. { SCM_BOOL_F, SCM_PACK (0) },
  291. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 128) },
  292. { SCM_BOOL_F, SCM_PACK (0) },
  293. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 192) },
  294. { SCM_BOOL_F, SCM_PACK (0) },
  295. /* 2 arguments */
  296. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 256) },
  297. { SCM_BOOL_F, SCM_PACK (0) },
  298. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 320) },
  299. { SCM_BOOL_F, SCM_PACK (0) },
  300. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 384) },
  301. { SCM_BOOL_F, SCM_PACK (0) },
  302. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 448) },
  303. { SCM_BOOL_F, SCM_PACK (0) },
  304. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 512) },
  305. { SCM_BOOL_F, SCM_PACK (0) },
  306. /* 3 arguments */
  307. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 576) },
  308. { SCM_BOOL_F, SCM_PACK (0) },
  309. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 640) },
  310. { SCM_BOOL_F, SCM_PACK (0) },
  311. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 704) },
  312. { SCM_BOOL_F, SCM_PACK (0) },
  313. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 768) },
  314. { SCM_BOOL_F, SCM_PACK (0) },
  315. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 832) },
  316. { SCM_BOOL_F, SCM_PACK (0) },
  317. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 896) },
  318. { SCM_BOOL_F, SCM_PACK (0) },
  319. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 960) },
  320. { SCM_BOOL_F, SCM_PACK (0) },
  321. /* 4 arguments */
  322. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1024) },
  323. { SCM_BOOL_F, SCM_PACK (0) },
  324. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1088) },
  325. { SCM_BOOL_F, SCM_PACK (0) },
  326. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1152) },
  327. { SCM_BOOL_F, SCM_PACK (0) },
  328. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1216) },
  329. { SCM_BOOL_F, SCM_PACK (0) },
  330. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1280) },
  331. { SCM_BOOL_F, SCM_PACK (0) },
  332. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1344) },
  333. { SCM_BOOL_F, SCM_PACK (0) },
  334. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1408) },
  335. { SCM_BOOL_F, SCM_PACK (0) },
  336. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1472) },
  337. { SCM_BOOL_F, SCM_PACK (0) },
  338. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1536) },
  339. { SCM_BOOL_F, SCM_PACK (0) },
  340. /* 5 arguments */
  341. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1600) },
  342. { SCM_BOOL_F, SCM_PACK (0) },
  343. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1664) },
  344. { SCM_BOOL_F, SCM_PACK (0) },
  345. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1728) },
  346. { SCM_BOOL_F, SCM_PACK (0) },
  347. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1792) },
  348. { SCM_BOOL_F, SCM_PACK (0) },
  349. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1856) },
  350. { SCM_BOOL_F, SCM_PACK (0) },
  351. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1920) },
  352. { SCM_BOOL_F, SCM_PACK (0) },
  353. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1984) },
  354. { SCM_BOOL_F, SCM_PACK (0) },
  355. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2048) },
  356. { SCM_BOOL_F, SCM_PACK (0) },
  357. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2112) },
  358. { SCM_BOOL_F, SCM_PACK (0) },
  359. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2176) },
  360. { SCM_BOOL_F, SCM_PACK (0) },
  361. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2240) },
  362. { SCM_BOOL_F, SCM_PACK (0) },
  363. /* 6 arguments */
  364. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2304) },
  365. { SCM_BOOL_F, SCM_PACK (0) },
  366. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2368) },
  367. { SCM_BOOL_F, SCM_PACK (0) },
  368. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2432) },
  369. { SCM_BOOL_F, SCM_PACK (0) },
  370. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2496) },
  371. { SCM_BOOL_F, SCM_PACK (0) },
  372. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2560) },
  373. { SCM_BOOL_F, SCM_PACK (0) },
  374. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2624) },
  375. { SCM_BOOL_F, SCM_PACK (0) },
  376. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2688) },
  377. { SCM_BOOL_F, SCM_PACK (0) },
  378. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2752) },
  379. { SCM_BOOL_F, SCM_PACK (0) },
  380. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2816) },
  381. { SCM_BOOL_F, SCM_PACK (0) },
  382. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2880) },
  383. { SCM_BOOL_F, SCM_PACK (0) },
  384. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2944) },
  385. { SCM_BOOL_F, SCM_PACK (0) },
  386. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3008) },
  387. { SCM_BOOL_F, SCM_PACK (0) },
  388. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3072) },
  389. { SCM_BOOL_F, SCM_PACK (0) },
  390. /* 7 arguments */
  391. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3136) },
  392. { SCM_BOOL_F, SCM_PACK (0) },
  393. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3200) },
  394. { SCM_BOOL_F, SCM_PACK (0) },
  395. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3264) },
  396. { SCM_BOOL_F, SCM_PACK (0) },
  397. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3328) },
  398. { SCM_BOOL_F, SCM_PACK (0) },
  399. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3392) },
  400. { SCM_BOOL_F, SCM_PACK (0) },
  401. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3456) },
  402. { SCM_BOOL_F, SCM_PACK (0) },
  403. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3520) },
  404. { SCM_BOOL_F, SCM_PACK (0) },
  405. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3584) },
  406. { SCM_BOOL_F, SCM_PACK (0) },
  407. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3648) },
  408. { SCM_BOOL_F, SCM_PACK (0) },
  409. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3712) },
  410. { SCM_BOOL_F, SCM_PACK (0) },
  411. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3776) },
  412. { SCM_BOOL_F, SCM_PACK (0) },
  413. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3840) },
  414. { SCM_BOOL_F, SCM_PACK (0) },
  415. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3904) },
  416. { SCM_BOOL_F, SCM_PACK (0) },
  417. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3968) },
  418. { SCM_BOOL_F, SCM_PACK (0) },
  419. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4032) },
  420. { SCM_BOOL_F, SCM_PACK (0) },
  421. /* 8 arguments */
  422. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4096) },
  423. { SCM_BOOL_F, SCM_PACK (0) },
  424. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4160) },
  425. { SCM_BOOL_F, SCM_PACK (0) },
  426. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4224) },
  427. { SCM_BOOL_F, SCM_PACK (0) },
  428. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4288) },
  429. { SCM_BOOL_F, SCM_PACK (0) },
  430. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4352) },
  431. { SCM_BOOL_F, SCM_PACK (0) },
  432. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4416) },
  433. { SCM_BOOL_F, SCM_PACK (0) },
  434. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4480) },
  435. { SCM_BOOL_F, SCM_PACK (0) },
  436. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4544) },
  437. { SCM_BOOL_F, SCM_PACK (0) },
  438. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4608) },
  439. { SCM_BOOL_F, SCM_PACK (0) },
  440. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4672) },
  441. { SCM_BOOL_F, SCM_PACK (0) },
  442. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4736) },
  443. { SCM_BOOL_F, SCM_PACK (0) },
  444. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4800) },
  445. { SCM_BOOL_F, SCM_PACK (0) },
  446. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4864) },
  447. { SCM_BOOL_F, SCM_PACK (0) },
  448. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4928) },
  449. { SCM_BOOL_F, SCM_PACK (0) },
  450. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4992) },
  451. { SCM_BOOL_F, SCM_PACK (0) },
  452. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5056) },
  453. { SCM_BOOL_F, SCM_PACK (0) },
  454. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5120) },
  455. { SCM_BOOL_F, SCM_PACK (0) },
  456. /* 9 arguments */
  457. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5184) },
  458. { SCM_BOOL_F, SCM_PACK (0) },
  459. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5248) },
  460. { SCM_BOOL_F, SCM_PACK (0) },
  461. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5312) },
  462. { SCM_BOOL_F, SCM_PACK (0) },
  463. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5376) },
  464. { SCM_BOOL_F, SCM_PACK (0) },
  465. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5440) },
  466. { SCM_BOOL_F, SCM_PACK (0) },
  467. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5504) },
  468. { SCM_BOOL_F, SCM_PACK (0) },
  469. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5568) },
  470. { SCM_BOOL_F, SCM_PACK (0) },
  471. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5632) },
  472. { SCM_BOOL_F, SCM_PACK (0) },
  473. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5696) },
  474. { SCM_BOOL_F, SCM_PACK (0) },
  475. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5760) },
  476. { SCM_BOOL_F, SCM_PACK (0) },
  477. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5824) },
  478. { SCM_BOOL_F, SCM_PACK (0) },
  479. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5888) },
  480. { SCM_BOOL_F, SCM_PACK (0) },
  481. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5952) },
  482. { SCM_BOOL_F, SCM_PACK (0) },
  483. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6016) },
  484. { SCM_BOOL_F, SCM_PACK (0) },
  485. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6080) },
  486. { SCM_BOOL_F, SCM_PACK (0) },
  487. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6144) },
  488. { SCM_BOOL_F, SCM_PACK (0) },
  489. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6208) },
  490. { SCM_BOOL_F, SCM_PACK (0) },
  491. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6272) },
  492. { SCM_BOOL_F, SCM_PACK (0) },
  493. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6336) },
  494. { SCM_BOOL_F, SCM_PACK (0) },
  495. /* 10 arguments */
  496. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6400) },
  497. { SCM_BOOL_F, SCM_PACK (0) },
  498. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6464) },
  499. { SCM_BOOL_F, SCM_PACK (0) },
  500. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6528) },
  501. { SCM_BOOL_F, SCM_PACK (0) },
  502. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6592) },
  503. { SCM_BOOL_F, SCM_PACK (0) },
  504. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6656) },
  505. { SCM_BOOL_F, SCM_PACK (0) },
  506. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6720) },
  507. { SCM_BOOL_F, SCM_PACK (0) },
  508. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6784) },
  509. { SCM_BOOL_F, SCM_PACK (0) },
  510. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6848) },
  511. { SCM_BOOL_F, SCM_PACK (0) },
  512. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6912) },
  513. { SCM_BOOL_F, SCM_PACK (0) },
  514. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6976) },
  515. { SCM_BOOL_F, SCM_PACK (0) },
  516. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7040) },
  517. { SCM_BOOL_F, SCM_PACK (0) },
  518. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7104) },
  519. { SCM_BOOL_F, SCM_PACK (0) },
  520. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7168) },
  521. { SCM_BOOL_F, SCM_PACK (0) },
  522. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7232) },
  523. { SCM_BOOL_F, SCM_PACK (0) },
  524. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7296) },
  525. { SCM_BOOL_F, SCM_PACK (0) },
  526. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7360) },
  527. { SCM_BOOL_F, SCM_PACK (0) },
  528. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7424) },
  529. { SCM_BOOL_F, SCM_PACK (0) },
  530. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7488) },
  531. { SCM_BOOL_F, SCM_PACK (0) },
  532. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7552) },
  533. { SCM_BOOL_F, SCM_PACK (0) },
  534. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7616) },
  535. { SCM_BOOL_F, SCM_PACK (0) },
  536. { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7680) },
  537. { SCM_BOOL_F, SCM_PACK (0) }
  538. }
  539. };
  540. /*
  541. (defun generate-objcode (n)
  542. "Generate objcode for N arguments"
  543. (interactive "p")
  544. (insert (format " /\* %d arguments *\/\n" n))
  545. (let ((i (* n n)))
  546. (while (< i (* (1+ n) (1+ n)))
  547. (insert (format " SCM_PACK (objcode_cells.cells+%d),\n" (* i 2)))
  548. (setq i (1+ i)))
  549. (insert "\n")))
  550. (defun generate-objcodes (n)
  551. "Generate objcodes for up to N arguments"
  552. (interactive "p")
  553. (let ((i 0))
  554. (while (<= i n)
  555. (generate-objcode i)
  556. (setq i (1+ i)))))
  557. */
  558. static const SCM scm_subr_objcode_trampolines[121] = {
  559. /* C-u 1 0 M-x generate-objcodes RET */
  560. /* 0 arguments */
  561. SCM_PACK (objcode_cells.cells+0),
  562. /* 1 arguments */
  563. SCM_PACK (objcode_cells.cells+2),
  564. SCM_PACK (objcode_cells.cells+4),
  565. SCM_PACK (objcode_cells.cells+6),
  566. /* 2 arguments */
  567. SCM_PACK (objcode_cells.cells+8),
  568. SCM_PACK (objcode_cells.cells+10),
  569. SCM_PACK (objcode_cells.cells+12),
  570. SCM_PACK (objcode_cells.cells+14),
  571. SCM_PACK (objcode_cells.cells+16),
  572. /* 3 arguments */
  573. SCM_PACK (objcode_cells.cells+18),
  574. SCM_PACK (objcode_cells.cells+20),
  575. SCM_PACK (objcode_cells.cells+22),
  576. SCM_PACK (objcode_cells.cells+24),
  577. SCM_PACK (objcode_cells.cells+26),
  578. SCM_PACK (objcode_cells.cells+28),
  579. SCM_PACK (objcode_cells.cells+30),
  580. /* 4 arguments */
  581. SCM_PACK (objcode_cells.cells+32),
  582. SCM_PACK (objcode_cells.cells+34),
  583. SCM_PACK (objcode_cells.cells+36),
  584. SCM_PACK (objcode_cells.cells+38),
  585. SCM_PACK (objcode_cells.cells+40),
  586. SCM_PACK (objcode_cells.cells+42),
  587. SCM_PACK (objcode_cells.cells+44),
  588. SCM_PACK (objcode_cells.cells+46),
  589. SCM_PACK (objcode_cells.cells+48),
  590. /* 5 arguments */
  591. SCM_PACK (objcode_cells.cells+50),
  592. SCM_PACK (objcode_cells.cells+52),
  593. SCM_PACK (objcode_cells.cells+54),
  594. SCM_PACK (objcode_cells.cells+56),
  595. SCM_PACK (objcode_cells.cells+58),
  596. SCM_PACK (objcode_cells.cells+60),
  597. SCM_PACK (objcode_cells.cells+62),
  598. SCM_PACK (objcode_cells.cells+64),
  599. SCM_PACK (objcode_cells.cells+66),
  600. SCM_PACK (objcode_cells.cells+68),
  601. SCM_PACK (objcode_cells.cells+70),
  602. /* 6 arguments */
  603. SCM_PACK (objcode_cells.cells+72),
  604. SCM_PACK (objcode_cells.cells+74),
  605. SCM_PACK (objcode_cells.cells+76),
  606. SCM_PACK (objcode_cells.cells+78),
  607. SCM_PACK (objcode_cells.cells+80),
  608. SCM_PACK (objcode_cells.cells+82),
  609. SCM_PACK (objcode_cells.cells+84),
  610. SCM_PACK (objcode_cells.cells+86),
  611. SCM_PACK (objcode_cells.cells+88),
  612. SCM_PACK (objcode_cells.cells+90),
  613. SCM_PACK (objcode_cells.cells+92),
  614. SCM_PACK (objcode_cells.cells+94),
  615. SCM_PACK (objcode_cells.cells+96),
  616. /* 7 arguments */
  617. SCM_PACK (objcode_cells.cells+98),
  618. SCM_PACK (objcode_cells.cells+100),
  619. SCM_PACK (objcode_cells.cells+102),
  620. SCM_PACK (objcode_cells.cells+104),
  621. SCM_PACK (objcode_cells.cells+106),
  622. SCM_PACK (objcode_cells.cells+108),
  623. SCM_PACK (objcode_cells.cells+110),
  624. SCM_PACK (objcode_cells.cells+112),
  625. SCM_PACK (objcode_cells.cells+114),
  626. SCM_PACK (objcode_cells.cells+116),
  627. SCM_PACK (objcode_cells.cells+118),
  628. SCM_PACK (objcode_cells.cells+120),
  629. SCM_PACK (objcode_cells.cells+122),
  630. SCM_PACK (objcode_cells.cells+124),
  631. SCM_PACK (objcode_cells.cells+126),
  632. /* 8 arguments */
  633. SCM_PACK (objcode_cells.cells+128),
  634. SCM_PACK (objcode_cells.cells+130),
  635. SCM_PACK (objcode_cells.cells+132),
  636. SCM_PACK (objcode_cells.cells+134),
  637. SCM_PACK (objcode_cells.cells+136),
  638. SCM_PACK (objcode_cells.cells+138),
  639. SCM_PACK (objcode_cells.cells+140),
  640. SCM_PACK (objcode_cells.cells+142),
  641. SCM_PACK (objcode_cells.cells+144),
  642. SCM_PACK (objcode_cells.cells+146),
  643. SCM_PACK (objcode_cells.cells+148),
  644. SCM_PACK (objcode_cells.cells+150),
  645. SCM_PACK (objcode_cells.cells+152),
  646. SCM_PACK (objcode_cells.cells+154),
  647. SCM_PACK (objcode_cells.cells+156),
  648. SCM_PACK (objcode_cells.cells+158),
  649. SCM_PACK (objcode_cells.cells+160),
  650. /* 9 arguments */
  651. SCM_PACK (objcode_cells.cells+162),
  652. SCM_PACK (objcode_cells.cells+164),
  653. SCM_PACK (objcode_cells.cells+166),
  654. SCM_PACK (objcode_cells.cells+168),
  655. SCM_PACK (objcode_cells.cells+170),
  656. SCM_PACK (objcode_cells.cells+172),
  657. SCM_PACK (objcode_cells.cells+174),
  658. SCM_PACK (objcode_cells.cells+176),
  659. SCM_PACK (objcode_cells.cells+178),
  660. SCM_PACK (objcode_cells.cells+180),
  661. SCM_PACK (objcode_cells.cells+182),
  662. SCM_PACK (objcode_cells.cells+184),
  663. SCM_PACK (objcode_cells.cells+186),
  664. SCM_PACK (objcode_cells.cells+188),
  665. SCM_PACK (objcode_cells.cells+190),
  666. SCM_PACK (objcode_cells.cells+192),
  667. SCM_PACK (objcode_cells.cells+194),
  668. SCM_PACK (objcode_cells.cells+196),
  669. SCM_PACK (objcode_cells.cells+198),
  670. /* 10 arguments */
  671. SCM_PACK (objcode_cells.cells+200),
  672. SCM_PACK (objcode_cells.cells+202),
  673. SCM_PACK (objcode_cells.cells+204),
  674. SCM_PACK (objcode_cells.cells+206),
  675. SCM_PACK (objcode_cells.cells+208),
  676. SCM_PACK (objcode_cells.cells+210),
  677. SCM_PACK (objcode_cells.cells+212),
  678. SCM_PACK (objcode_cells.cells+214),
  679. SCM_PACK (objcode_cells.cells+216),
  680. SCM_PACK (objcode_cells.cells+218),
  681. SCM_PACK (objcode_cells.cells+220),
  682. SCM_PACK (objcode_cells.cells+222),
  683. SCM_PACK (objcode_cells.cells+224),
  684. SCM_PACK (objcode_cells.cells+226),
  685. SCM_PACK (objcode_cells.cells+228),
  686. SCM_PACK (objcode_cells.cells+230),
  687. SCM_PACK (objcode_cells.cells+232),
  688. SCM_PACK (objcode_cells.cells+234),
  689. SCM_PACK (objcode_cells.cells+236),
  690. SCM_PACK (objcode_cells.cells+238),
  691. SCM_PACK (objcode_cells.cells+240)
  692. };
  693. /* (nargs * nargs) + nopt + rest * (nargs + 1) */
  694. #define SCM_SUBR_OBJCODE_TRAMPOLINE(nreq,nopt,rest) \
  695. scm_subr_objcode_trampolines[(nreq + nopt + rest) * (nreq + nopt + rest) \
  696. + nopt + rest * (nreq + nopt + rest + 1)]
  697. SCM
  698. scm_subr_objcode_trampoline (unsigned int nreq, unsigned int nopt,
  699. unsigned int rest)
  700. {
  701. if (SCM_UNLIKELY (rest > 1 || nreq + nopt + rest > 10))
  702. scm_out_of_range ("make-subr", scm_from_uint (nreq + nopt + rest));
  703. return SCM_SUBR_OBJCODE_TRAMPOLINE (nreq, nopt, rest);
  704. }
  705. static SCM
  706. create_gsubr (int define, const char *name,
  707. unsigned int nreq, unsigned int nopt, unsigned int rest,
  708. SCM (*fcn) (), SCM *generic_loc)
  709. {
  710. SCM ret;
  711. SCM sname;
  712. SCM table;
  713. scm_t_bits flags;
  714. /* make objtable */
  715. sname = scm_from_utf8_symbol (name);
  716. table = scm_c_make_vector (generic_loc ? 3 : 2, SCM_UNDEFINED);
  717. SCM_SIMPLE_VECTOR_SET (table, 0, scm_from_pointer (fcn, NULL));
  718. SCM_SIMPLE_VECTOR_SET (table, 1, sname);
  719. if (generic_loc)
  720. SCM_SIMPLE_VECTOR_SET (table, 2,
  721. scm_from_pointer (generic_loc, NULL));
  722. /* make program */
  723. ret = scm_make_program (scm_subr_objcode_trampoline (nreq, nopt, rest),
  724. table, SCM_BOOL_F);
  725. /* set flags */
  726. flags = SCM_F_PROGRAM_IS_PRIMITIVE;
  727. flags |= generic_loc ? SCM_F_PROGRAM_IS_PRIMITIVE_GENERIC : 0;
  728. SCM_SET_CELL_WORD_0 (ret, SCM_CELL_WORD_0 (ret) | flags);
  729. /* define, if needed */
  730. if (define)
  731. scm_define (sname, ret);
  732. /* et voila. */
  733. return ret;
  734. }
  735. SCM
  736. scm_c_make_gsubr (const char *name, int req, int opt, int rst, SCM (*fcn)())
  737. {
  738. return create_gsubr (0, name, req, opt, rst, fcn, NULL);
  739. }
  740. SCM
  741. scm_c_define_gsubr (const char *name, int req, int opt, int rst, SCM (*fcn)())
  742. {
  743. return create_gsubr (1, name, req, opt, rst, fcn, NULL);
  744. }
  745. SCM
  746. scm_c_make_gsubr_with_generic (const char *name,
  747. int req,
  748. int opt,
  749. int rst,
  750. SCM (*fcn)(),
  751. SCM *gf)
  752. {
  753. return create_gsubr (0, name, req, opt, rst, fcn, gf);
  754. }
  755. SCM
  756. scm_c_define_gsubr_with_generic (const char *name,
  757. int req,
  758. int opt,
  759. int rst,
  760. SCM (*fcn)(),
  761. SCM *gf)
  762. {
  763. return create_gsubr (1, name, req, opt, rst, fcn, gf);
  764. }
  765. #ifdef GSUBR_TEST
  766. /* A silly example, taking 2 required args, 1 optional, and
  767. a scm_list of rest args
  768. */
  769. SCM
  770. gsubr_21l(SCM req1, SCM req2, SCM opt, SCM rst)
  771. {
  772. scm_puts_unlocked ("gsubr-2-1-l:\n req1: ", scm_cur_outp);
  773. scm_display(req1, scm_cur_outp);
  774. scm_puts_unlocked ("\n req2: ", scm_cur_outp);
  775. scm_display(req2, scm_cur_outp);
  776. scm_puts_unlocked ("\n opt: ", scm_cur_outp);
  777. scm_display(opt, scm_cur_outp);
  778. scm_puts_unlocked ("\n rest: ", scm_cur_outp);
  779. scm_display(rst, scm_cur_outp);
  780. scm_newline(scm_cur_outp);
  781. return SCM_UNSPECIFIED;
  782. }
  783. #endif
  784. void
  785. scm_init_gsubr()
  786. {
  787. #ifdef GSUBR_TEST
  788. scm_c_define_gsubr ("gsubr-2-1-l", 2, 1, 1, gsubr_21l); /* example */
  789. #endif
  790. #include "libguile/gsubr.x"
  791. }
  792. /*
  793. Local Variables:
  794. c-file-style: "gnu"
  795. End:
  796. */