eval.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176
  1. /* Definitions for the 'eval' function.
  2. This file is part of khipu.
  3. khipu is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Lesser General Public License as published by
  5. the Free Software Foundation; either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program. If not, see <https://www.gnu.org/licenses/>. */
  13. #include <cstdio>
  14. #include "khipu.hpp"
  15. KP_DECLS_BEGIN
  16. static result<uint32_t>
  17. process_keys (interpreter *interp, object kwtab, uint32_t nreq,
  18. uint32_t nkw, uint32_t nopt, uint32_t bp, uint32_t nargs, bool va)
  19. {
  20. uint32_t extra = nopt + nkw;
  21. uint32_t total = nreq + extra;
  22. if (nargs < nreq)
  23. return (interp->raise_nargs (nreq, total, nargs));
  24. tmp_allocator ta { interp };
  25. object *argv = (object *)ta.alloc (extra * sizeof (*argv));
  26. uint32_t ix, ax = 0;
  27. object uv, saved_data[4];
  28. local_varobj<array> saved;
  29. saved.local_init (saved_data, KP_NELEM (saved_data));
  30. saved.data[0] = *(interp->stkend - 1);
  31. saved.data[1] = *(interp->stkend - 2);
  32. saved.data[2] = *(interp->stkend - 4);
  33. saved.data[3] = *(interp->stkend - 5);
  34. interp->aux = saved.as_obj ();
  35. for (ix = 0; ix < extra; ++ix)
  36. argv[ix] = UNBOUND;
  37. uint32_t n = len_a (kwtab) / 2;
  38. for (ix = nreq; ix < nargs; ++ix)
  39. {
  40. uv = interp->stack[bp + ix];
  41. if (keyword_p (uv))
  42. break;
  43. else if (ax >= nopt)
  44. goto done;
  45. argv[ax++] = uv;
  46. }
  47. if (ix >= nargs)
  48. goto done;
  49. do
  50. {
  51. if (++ix >= nargs)
  52. return (interp->raise ("arg-error",
  53. KP_SPRINTF (interp,
  54. "keyword %Q requires an argument",
  55. uv)));
  56. uint32_t pos = hash_S (interp, uv) & (n - 1);
  57. while (true)
  58. {
  59. object *keyp = &xaref(kwtab, pos * 2);
  60. if (*keyp == fixint (0))
  61. return (interp->raise ("arg-error",
  62. KP_SPRINTF (interp,
  63. "invalid keyword %Q", uv)));
  64. else if (*keyp == uv)
  65. {
  66. pos = as_int (*++keyp);
  67. break;
  68. }
  69. pos = (pos + 1) & (n - 1);
  70. }
  71. if (argv[pos] == UNBOUND)
  72. argv[pos] = interp->stack[bp + ix];
  73. if (++ix >= nargs)
  74. break;
  75. uv = interp->stack[bp + ix];
  76. }
  77. while (keyword_p (uv));
  78. done:
  79. uint32_t nrest = nargs - ix;
  80. if (!va && nrest > 0)
  81. return (interp->raise ("arg-error",
  82. KP_SPRINTF (interp,
  83. "wrong number of positional arguments "
  84. "for %Q (expected %Q, got %Q)",
  85. interp->caller (),
  86. fixint (nreq + nopt), fixint (nargs))));
  87. nargs = total + nrest;
  88. move_objs (interp->stack + bp + total, interp->stack + bp + ix, nrest);
  89. copy_objs (interp->stack + bp + nreq, argv, extra);
  90. interp->stkend = interp->stack + bp + nargs;
  91. KP_VTRY (interp->growstk (interpreter::frame_size));
  92. *interp->stkend++ = saved.data[3];
  93. *interp->stkend++ = saved.data[2];
  94. *interp->stkend++ = fixint (nargs);
  95. *interp->stkend++ = saved.data[1];
  96. *interp->stkend++ = saved.data[0];
  97. interp->aux = UNBOUND;
  98. interp->cur_frame = interp->stklen ();
  99. return (nargs);
  100. }
  101. // Index a sequence with N arguments on the stack.
  102. static result<object>
  103. call_indexer (interpreter *interp, indexer_t fp, object seq, int n)
  104. {
  105. return (fp (interp, seq, *(interp->stkend - n),
  106. n > 1 ? interp->stktop () : UNBOUND));
  107. }
  108. static inline result<bool>
  109. call_sequence (interpreter *interp, object seq, int n)
  110. {
  111. indexer_t fp = index_seq (seq);
  112. if (!fp)
  113. return (false);
  114. else if (n == 0)
  115. return (interp->raise ("arg-error", "missing index for sequence"));
  116. else if (n > 2)
  117. {
  118. local_varobj<string> sn;
  119. sn.local_init ("#:index", 7);
  120. return (interp->raise_nargs (sn.as_obj (), 1, 2, n));
  121. }
  122. *(interp->stkend - 1) = KP_TRY (call_indexer (interp, fp, seq, n));
  123. return (true);
  124. }
  125. static uint32_t
  126. fetch32 (const uint8_t*& ptr)
  127. {
  128. uint32_t ret = get32 (ptr);
  129. ptr += sizeof (ret);
  130. return (ret);
  131. }
  132. static inline uint32_t
  133. ip_ival (const uint8_t*& ip)
  134. {
  135. return (!bcode_long_p (*(ip - 1)) ? *ip++ : fetch32 (ip));
  136. }
  137. static result<int>
  138. push_seq (interpreter *interp, object seq, int n)
  139. {
  140. int ret = 0;
  141. if (xcons_p (seq))
  142. {
  143. cons::iterator it { interp, seq };
  144. for (; it.valid (); ++it, ++ret)
  145. KP_VTRY (interp->push (*it));
  146. if (!xcons_p (it.node ()))
  147. return (interp->raise ("arg-error",
  148. "list argument must be a proper list"));
  149. }
  150. else if (array_p (seq))
  151. {
  152. uint32_t len = len_a (seq);
  153. KP_VTRY (interp->growstk (len));
  154. for (; ret < (int)len; ++ret)
  155. *interp->stkend++ = xaref (seq, ret);
  156. }
  157. else if (table_p (seq))
  158. for (table::iterator it (interp, seq); it.valid (); ++it, ++ret)
  159. KP_VTRY (interp->push (it.key ()));
  160. else if (tuple_p (seq))
  161. for (tuple::iterator it (interp, seq); it.valid (); ++it, ++ret)
  162. KP_VTRY (interp->push (*it));
  163. else if (fct_p (*(interp->stkend - n + 1)))
  164. return (interp->raise ("type-error",
  165. KP_SPRINTF (interp, "cannot interpret object of "
  166. "type %Q as a sequence",
  167. type (seq))));
  168. else
  169. {
  170. KP_VTRY (interp->push (seq),
  171. interp->push (fixint (0)),
  172. intern (interp, "g-apply", 7));
  173. valref meth (interp, symval (interp->retval));
  174. object *lp = interp->stkend - n - 1;
  175. if (*meth == UNBOUND)
  176. return (interp->raise ("type-error",
  177. KP_SPRINTF (interp, "cannot apply object of "
  178. "type %Q", type (*lp))));
  179. move_objs (lp + 1, lp, n);
  180. *lp = *meth;
  181. ret = 2;
  182. }
  183. return (ret);
  184. }
  185. static result<bool>
  186. captenv (interpreter *interp, uint32_t bp, function *fp)
  187. {
  188. const array *ap = as_array (fp->env);
  189. object env = KP_TRY (alloc_array (interp, ap->len + 1));
  190. for (uint32_t i = 0; i < ap->len; ++i)
  191. xaref(env, i) = interp->stack[bp + as_int (ap->data[i])];
  192. if (!native_fct_p (interp->stack[--bp]))
  193. xaref(env, ap->len) = fct_env (interp->stack[bp]);
  194. fp->env = env;
  195. return (true);
  196. }
  197. static inline result<bool>
  198. push_symval (interpreter *interp, object sym)
  199. {
  200. interp->retval = sym;
  201. if (as_symbol(sym)->flagged_p (symbol::ctv_flag) ||
  202. (interp->aux = symval (interp->retval)) == UNBOUND)
  203. return (interp->raise ("unbound-error",
  204. KP_SPRINTF (interp,
  205. "symbol %Q is unbound",
  206. interp->retval)));
  207. *interp->stkend++ = interp->aux;
  208. return (true);
  209. }
  210. static inline result<bool>
  211. set_symval (interpreter *interp, object sym)
  212. {
  213. symbol *sp = as_symbol (sym);
  214. if (sp->flagged_p (FLAGS_CONST))
  215. return (interp->raise ("const-error",
  216. KP_SPRINTF (interp,
  217. "cannot assign to constant %Q",
  218. sp->as_obj ())));
  219. else if (kp_likely (!sp->tl_idx || interp->n_tlsyms <= sp->tl_idx))
  220. {
  221. sp->value = interp->stktop ();
  222. deref (gc_wbarrier (interp, sym, sp->value));
  223. }
  224. else
  225. interp->tl_syms[sp->tl_idx - 1] = interp->stktop ();
  226. return (true);
  227. }
  228. static inline object&
  229. closure_var (interpreter *interp, uint32_t bp, uint32_t n, uint32_t idx)
  230. {
  231. array *ap = as_array (fct_env (interp->stack[bp - 1]));
  232. for (uint32_t i = 0; i < n; ++i)
  233. ap = as_array (ap->data[ap->len - 1]);
  234. return (ap->data[idx]);
  235. }
  236. // Additional data used in function calls.
  237. struct call_data
  238. {
  239. uint32_t ip_offset;
  240. uint32_t topf;
  241. };
  242. struct cont_data
  243. {
  244. coroutine *crp;
  245. object value;
  246. };
  247. static result<object> __attribute__((hot))
  248. run_bytecode (interpreter *interp, uint32_t nargs,
  249. cont_data *cont = nullptr, const call_data *cdp = nullptr)
  250. {
  251. uint32_t top_frame = interp->cur_frame;
  252. uint32_t n = 0, bp, ix;
  253. int32_t sx = 0;
  254. const uint8_t *ip;
  255. object fn;
  256. object* stack = interp->stack, *fvals;
  257. object*& stkend = interp->stkend;
  258. object& retval = interp->retval;
  259. cons *cnp;
  260. #if defined (__GNUC__) && !defined (KP_NO_THREADED_GOTO)
  261. # define GOTO_LABELS
  262. const void* const LABELS[] =
  263. {
  264. # define P_(opc) [OP_##opc] = &&OP_LBL_##opc
  265. P_(NOP), P_(DUP), P_(POP), P_(RET), P_(IS), P_(NOT), P_(CONS),
  266. P_(CAR), P_(CDR), P_(CADR), P_(APPLY), P_(TAPPLY), P_(LOADT),
  267. P_(LOADNIL), P_(LOAD0), P_(LOAD1), P_(LOADA0), P_(LOADA1), P_(LOADC00),
  268. P_(LOADC01), P_(MKCONT), P_(CLOSURE), P_(VFRAME), P_(TRYEND),
  269. P_(LDCALLER), P_(CLREXC), P_(SYMNAME), P_(SYMPKG), P_(COROVAL),
  270. P_(TYPEP), P_(TYPEP2), P_(RAISE), P_(LOADI8), P_(LOADI32), P_(LOADCHR8),
  271. P_(LOADCHR32), P_(VARGC), P_(VARGCL), P_(JMP), P_(JMPL), P_(BRT),
  272. P_(BRTL), P_(BRN), P_(BRNL), P_(BRNEQ), P_(BRNEQL), P_(TCALL), P_(TCALLL),
  273. P_(CALL), P_(CALLL), P_(RECUR), P_(RECURL), P_(TRECUR), P_(TRECURL),
  274. P_(SETC0), P_(SETC0L), P_(SETC), P_(SETCL), P_(SETA), P_(SETAL),
  275. P_(SETG), P_(SETGL), P_(SETFGS), P_(SETFGSL), P_(LOADC0), P_(LOADC0L),
  276. P_(LOADC), P_(LOADCL), P_(LOADA), P_(LOADAL), P_(LOADG), P_(LOADGL),
  277. P_(LOADV), P_(LOADVL), P_(LOADX), P_(LOADXL), P_(LOADFGS), P_(LOADFGSL),
  278. P_(BIND), P_(BINDL), P_(TRYBEGIN), P_(TRYBEGINL), P_(SETAPOP),
  279. P_(SETAPOPL), P_(IRTJMP), P_(IRTJMPL), P_(OPTARGS), P_(OPTARGSL),
  280. P_(BRBOUND), P_(BRBOUNDL), P_(KWARGS), P_(KWARGSL), P_(JMPT), P_(JMPTL),
  281. P_(JMPN), P_(JMPNL), P_(BOX), P_(BOXL), P_(LOADB), P_(LOADBL), P_(SETB),
  282. P_(SETBL), P_(SKIP), P_(SKIPL), P_(UNBIND), P_(UNBINDL)
  283. };
  284. # undef P_
  285. #else
  286. uint32_t op;
  287. #endif
  288. #define U_PUSH(val) *stkend++ = val
  289. #define r_stkend(off) *(stkend - (off))
  290. if (cdp)
  291. { // Restored from a caught exception.
  292. top_frame = cdp->topf;
  293. nargs = as_int (stack[interp->cur_frame - 3]);
  294. bp = interp->cur_frame - interpreter::frame_size - nargs;
  295. fn = stack[bp - 1];
  296. ip = as_bvector(fct_bcode (fn))->data + cdp->ip_offset;
  297. }
  298. else if (cont)
  299. { // Resume execution from coroutine.
  300. interp->cur_frame = cont->crp->frame;
  301. nargs = as_int (stack[interp->cur_frame - 3]);
  302. bp = interp->cur_frame - interpreter::frame_size - nargs;
  303. fn = stack[bp - 1];
  304. ip = as_bvector(fct_bcode (fn))->data + cont->crp->ip_offset;
  305. U_PUSH (cont->value);
  306. }
  307. else
  308. { // Regular function call.
  309. top:
  310. fn = r_stkend (nargs + 1);
  311. ip = as_bvector(fct_bcode (fn))->data;
  312. bp = interp->stklen () - nargs;
  313. KP_VTRY (interp->push_frame (as_fct(fn)->env, nargs, 0),
  314. as_fct(fn)->test_nargs (interp, nargs),
  315. interp->growstk (as_fct(fn)->max_sp));
  316. stack = interp->stack;
  317. }
  318. fvals = as_array(fct_vals (stack[bp - 1]))->data;
  319. #ifdef GOTO_LABELS
  320. # define OP_(code) OP_LBL_##code
  321. # define NEXT_OP goto *LABELS[*ip++]
  322. NEXT_OP;
  323. #else
  324. # define OP_(code) case OP_##code
  325. # define NEXT_OP goto next_op
  326. next_op:
  327. op = *ip++;
  328. dispatch:
  329. switch (op)
  330. #endif
  331. {
  332. OP_(NOP):
  333. NEXT_OP;
  334. OP_(VARGC):
  335. OP_(VARGCL):
  336. ix = ip_ival (ip);
  337. sx = (int32_t)nargs - (int32_t)ix;
  338. if (sx > 0)
  339. {
  340. stack[bp + ix] = KP_TRY (list_fct (interp, &stack[bp + ix], sx));
  341. if (sx > 1)
  342. {
  343. stack[bp + ix + 1] = stack[bp + nargs + 0];
  344. stack[bp + ix + 2] = stack[bp + nargs + 1];
  345. stack[bp + ix + 3] = fixint (ix + 1);
  346. stack[bp + ix + 5] = fixint (0);
  347. stkend = stack + bp + ix + 6;
  348. interp->cur_frame = interp->stklen ();
  349. }
  350. }
  351. else
  352. {
  353. U_PUSH (fixint (0));
  354. r_stkend(3) = fixint (ix + 1);
  355. r_stkend(4) = r_stkend (5);
  356. r_stkend(5) = r_stkend (6);
  357. r_stkend(6) = NIL;
  358. interp->cur_frame = interp->stklen ();
  359. }
  360. nargs = ix + 1;
  361. NEXT_OP;
  362. OP_(BRBOUND):
  363. OP_(BRBOUNDL):
  364. U_PUSH (stack[bp + ip_ival (ip)] != UNBOUND ? symbol::t : NIL);
  365. NEXT_OP;
  366. OP_(DUP):
  367. retval = r_stkend(1);
  368. U_PUSH (retval);
  369. NEXT_OP;
  370. OP_(POP):
  371. interp->popn ();
  372. NEXT_OP;
  373. OP_(TRECUR):
  374. OP_(TRECURL):
  375. KP_VTRY (interp->handle_evs ());
  376. n = ip_ival (ip);
  377. bp = interp->cur_frame - interpreter::frame_size - nargs;
  378. interp->cur_frame = as_int (stack[interp->cur_frame - 4]);
  379. move_objs (&stack[bp - 1], stkend - n - 1, n + 1);
  380. stkend = stack + bp + n;
  381. nargs = n;
  382. goto top;
  383. OP_(TCALL):
  384. OP_(TCALLL):
  385. KP_VTRY (interp->handle_evs ());
  386. n = ip_ival (ip);
  387. do_tcall:
  388. fn = r_stkend (n + 1);
  389. if (fct_p (fn))
  390. {
  391. if (native_fct_p (fn))
  392. {
  393. KP_VTRY (as_native_fct(fn)->call (interp, n));
  394. stack = interp->stack;
  395. U_PUSH (retval);
  396. NEXT_OP;
  397. }
  398. bp = interp->cur_frame - interpreter::frame_size - nargs;
  399. interp->cur_frame = as_int (stack[interp->cur_frame - 4]);
  400. move_objs (&stack[bp - 1], stkend - n - 1, n + 1);
  401. stkend = stack + bp + n;
  402. nargs = n;
  403. goto top;
  404. }
  405. else
  406. {
  407. bool rv = KP_TRY (call_sequence (interp, fn, n));
  408. if (rv)
  409. {
  410. stack = interp->stack, stkend -= n;
  411. r_stkend(1) = retval;
  412. NEXT_OP;
  413. }
  414. }
  415. return (interp->raise ("type-error",
  416. KP_SPRINTF (interp,
  417. "object of type %Q is not callable",
  418. type (fn))));
  419. OP_(RECUR):
  420. OP_(RECURL):
  421. nargs = ip_ival (ip);
  422. stack[interp->cur_frame - 2] = fixint (ip -
  423. as_bvector(fct_bcode (stack[bp - 1]))->data);
  424. goto top;
  425. OP_(CALL):
  426. OP_(CALLL):
  427. n = ip_ival (ip);
  428. do_call:
  429. fn = r_stkend (n + 1);
  430. if (fct_p (fn))
  431. {
  432. if (native_fct_p (fn))
  433. {
  434. KP_VTRY (as_native_fct(fn)->call (interp, n));
  435. stack = interp->stack;
  436. U_PUSH (retval);
  437. NEXT_OP;
  438. }
  439. stack[interp->cur_frame - 2] = fixint (ip -
  440. as_bvector(fct_bcode (stack[bp - 1]))->data);
  441. nargs = n;
  442. goto top;
  443. }
  444. else
  445. {
  446. bool rv = KP_TRY (call_sequence (interp, fn, n));
  447. if (rv)
  448. {
  449. stack = interp->stack, stkend -= n;
  450. r_stkend(1) = retval;
  451. NEXT_OP;
  452. }
  453. }
  454. return (interp->raise ("type-error",
  455. KP_SPRINTF (interp,
  456. "object of type %Q is not callable",
  457. type (fn))));
  458. OP_(IRTJMP):
  459. KP_VTRY (interp->handle_evs ());
  460. OP_(JMP):
  461. ip += (int16_t)get16 (ip);
  462. NEXT_OP;
  463. OP_(IRTJMPL):
  464. KP_VTRY (interp->handle_evs ());
  465. OP_(JMPL):
  466. ip += (int32_t)get32 (ip);
  467. NEXT_OP;
  468. OP_(BRN):
  469. interp->pop ();
  470. ip += retval == NIL ? (int16_t)get16 (ip) : sizeof (int16_t);
  471. NEXT_OP;
  472. OP_(BRNL):
  473. interp->pop ();
  474. ip += retval == NIL ? (int32_t)get32 (ip) : sizeof (int32_t);
  475. NEXT_OP;
  476. OP_(BRT):
  477. interp->pop ();
  478. ip += retval != NIL ? (int16_t)get16 (ip) : sizeof (int16_t);
  479. NEXT_OP;
  480. OP_(BRTL):
  481. interp->pop ();
  482. ip += retval != NIL ? (int32_t)get32 (ip) : sizeof (int32_t);
  483. NEXT_OP;
  484. OP_(BRNEQ):
  485. ip += r_stkend (2) != r_stkend (1) ?
  486. (int16_t)get16 (ip) : sizeof (int16_t);
  487. interp->popn (2);
  488. NEXT_OP;
  489. OP_(BRNEQL):
  490. ip += r_stkend (2) != r_stkend (1) ?
  491. (int32_t)get32 (ip) : sizeof (int32_t);
  492. interp->popn (2);
  493. NEXT_OP;
  494. OP_(JMPT):
  495. OP_(JMPTL):
  496. sx = *(ip - 1) - OP_JMPT;
  497. if (r_stkend (1) != NIL)
  498. ip += sx ? (int32_t)get32 (ip) : (int16_t)get16 (ip);
  499. else
  500. {
  501. interp->popn ();
  502. ip += sizeof (int16_t) << sx;
  503. }
  504. NEXT_OP;
  505. OP_(JMPN):
  506. OP_(JMPNL):
  507. sx = *(ip - 1) - OP_JMPN;
  508. if (r_stkend (1) == NIL)
  509. ip += sx ? (int32_t)get32 (ip) : (int16_t)get16 (ip);
  510. else
  511. {
  512. interp->popn ();
  513. ip += sizeof (int16_t) << sx;
  514. }
  515. NEXT_OP;
  516. OP_(RET):
  517. retval = r_stkend (1);
  518. stkend = stack + interp->cur_frame;
  519. interp->cur_frame = as_int (stack[interp->cur_frame - 4]);
  520. if (interp->cur_frame == top_frame)
  521. return (retval);
  522. stkend -= interpreter::frame_size + nargs;
  523. nargs = as_int (stack[interp->cur_frame - 3]);
  524. bp = interp->cur_frame - interpreter::frame_size - nargs;
  525. fn = stack[bp - 1];
  526. fvals = as_array(fct_vals (fn))->data;
  527. ip = as_bvector(fct_bcode (fn))->data +
  528. as_int (stack[interp->cur_frame - 2]);
  529. r_stkend(1) = retval;
  530. NEXT_OP;
  531. OP_(IS):
  532. r_stkend(2) = r_stkend (2) == r_stkend (1) ? symbol::t : NIL;
  533. interp->popn ();
  534. NEXT_OP;
  535. OP_(NOT):
  536. r_stkend(1) = r_stkend (1) == NIL ? symbol::t : NIL;
  537. NEXT_OP;
  538. OP_(CONS):
  539. r_stkend(2) = KP_TRY (cons::make (interp, r_stkend (2), r_stkend (1)));
  540. interp->popn ();
  541. NEXT_OP;
  542. OP_(CAR):
  543. if (!(cnp = as<cons> (r_stkend (1))))
  544. return (interp->raise ("type-error", "car: value is not a cons"));
  545. r_stkend(1) = cnp->car;
  546. NEXT_OP;
  547. OP_(CDR):
  548. if (!(cnp = as<cons> (r_stkend (1))))
  549. return (interp->raise ("type-error", "cdr: value is not a cons"));
  550. r_stkend(1) = cnp->cdr;
  551. NEXT_OP;
  552. OP_(CADR):
  553. if (!(cnp = as<cons> (r_stkend (1))) ||
  554. !(cnp = as<cons> (cnp->cdr)))
  555. return (interp->raise ("type-error", "cadr: value is not a cons"));
  556. r_stkend(1) = cnp->car;
  557. NEXT_OP;
  558. OP_(SYMNAME):
  559. OP_(SYMPKG):
  560. {
  561. symbol *sp = as<symbol> (r_stkend (1));
  562. if (kp_unlikely (!sp))
  563. {
  564. char err[] = "name\0pkg";
  565. char buf[100];
  566. sprintf (buf, "sym%s: argument must be a symbol",
  567. err + (*(ip - 1) - OP_SYMNAME) * 5);
  568. return (interp->raise ("type-error", buf));
  569. }
  570. r_stkend(1) = (&sp->name)[*(ip - 1) - OP_SYMNAME];
  571. NEXT_OP;
  572. }
  573. OP_(COROVAL):
  574. {
  575. auto crp = as<coroutine> (r_stkend (1));
  576. if (kp_unlikely (!crp))
  577. return (interp->raise ("type-error",
  578. "coro-val: argument must be a coroutine"));
  579. r_stkend(1) = crp->value;
  580. NEXT_OP;
  581. }
  582. OP_(TYPEP2):
  583. ix = itype (r_stkend (1));
  584. sx = *ip++;
  585. if (sx == (int32_t)ix ||
  586. itype (builtin_member (r_stkend (1))) == sx)
  587. {
  588. ++ip; // Skip the second typecode.
  589. r_stkend(1) = symbol::t;
  590. NEXT_OP;
  591. }
  592. // FALLTHROUGH.
  593. OP_(TYPEP):
  594. ix = itype (r_stkend (1));
  595. sx = *ip++;
  596. r_stkend(1) = sx == (int32_t)ix ||
  597. itype (builtin_member (r_stkend (1))) == sx ?
  598. symbol::t : NIL;
  599. NEXT_OP;
  600. OP_(TAPPLY):
  601. OP_(APPLY):
  602. sx = *(ip - 1) == OP_APPLY;
  603. n = ip_ival (ip);
  604. n += -2 + KP_TRY (push_seq (interp, interp->pop (), n));
  605. stack = interp->stack; // Could get moved by the above operation.
  606. if (sx)
  607. goto do_call;
  608. else
  609. goto do_tcall;
  610. OP_(LOADT):
  611. U_PUSH (symbol::t);
  612. NEXT_OP;
  613. OP_(LOADNIL):
  614. U_PUSH (NIL);
  615. NEXT_OP;
  616. OP_(LOAD0):
  617. U_PUSH (fixint (0));
  618. NEXT_OP;
  619. OP_(LOAD1):
  620. U_PUSH (fixint (1));
  621. NEXT_OP;
  622. OP_(LOADI8):
  623. U_PUSH (fixint ((int8_t)*ip++));
  624. NEXT_OP;
  625. OP_(LOADI32):
  626. U_PUSH (fixint (fetch32 (ip)));
  627. NEXT_OP;
  628. OP_(LOADCHR8):
  629. U_PUSH (charobj (*ip++));
  630. NEXT_OP;
  631. OP_(LOADCHR32):
  632. U_PUSH (charobj (fetch32 (ip)));
  633. NEXT_OP;
  634. OP_(LOADV):
  635. U_PUSH (fvals[*ip++]);
  636. NEXT_OP;
  637. OP_(LOADVL):
  638. U_PUSH (fvals[fetch32 (ip)]);
  639. NEXT_OP;
  640. OP_(LOADG):
  641. KP_VTRY (push_symval (interp, fvals[*ip++]));
  642. NEXT_OP;
  643. OP_(LOADGL):
  644. KP_VTRY (push_symval (interp, fvals[fetch32 (ip)]));
  645. NEXT_OP;
  646. OP_(LOADFGS):
  647. KP_VTRY (push_symval (interp, symbol::fast_global_syms[*ip++]));
  648. NEXT_OP;
  649. OP_(LOADFGSL):
  650. KP_VTRY (push_symval (interp, symbol::fast_global_syms[fetch32 (ip)]));
  651. NEXT_OP;
  652. OP_(SETG):
  653. OP_(SETGL):
  654. KP_VTRY (set_symval (interp, fvals[ip_ival (ip)]));
  655. NEXT_OP;
  656. OP_(SETFGS):
  657. OP_(SETFGSL):
  658. KP_VTRY (set_symval (interp, symbol::fast_global_syms[ip_ival (ip)]));
  659. NEXT_OP;
  660. OP_(LOADA0):
  661. U_PUSH (stack[bp]);
  662. NEXT_OP;
  663. OP_(LOADA1):
  664. U_PUSH (stack[bp + 1]);
  665. NEXT_OP;
  666. OP_(LOADA):
  667. U_PUSH (stack[bp + *ip++]);
  668. NEXT_OP;
  669. OP_(LOADAL):
  670. U_PUSH (stack[bp + fetch32 (ip)]);
  671. NEXT_OP;
  672. OP_(SETA):
  673. OP_(SETAL):
  674. stack[bp + ip_ival (ip)] = r_stkend (1);
  675. NEXT_OP;
  676. OP_(SETAPOP):
  677. OP_(SETAPOPL):
  678. stack[bp + ip_ival (ip)] = r_stkend (1);
  679. --stkend;
  680. NEXT_OP;
  681. OP_(LOADC):
  682. OP_(LOADCL):
  683. sx = ip_ival (ip);
  684. U_PUSH (xcar (closure_var (interp, bp, sx, ip_ival (ip))));
  685. NEXT_OP;
  686. OP_(LOADC0):
  687. OP_(LOADC0L):
  688. U_PUSH (xcar (xaref (as_fct(stack[bp - 1])->env, ip_ival (ip))));
  689. NEXT_OP;
  690. OP_(LOADC00):
  691. U_PUSH (xcar (xaref (as_fct(stack[bp - 1])->env, 0)));
  692. NEXT_OP;
  693. OP_(LOADC01):
  694. U_PUSH (xcar (xaref (as_fct(stack[bp - 1])->env, 1)));
  695. NEXT_OP;
  696. OP_(SETC):
  697. OP_(SETCL):
  698. sx = ip_ival (ip);
  699. KP_VTRY (nputcar (interp, closure_var (interp, bp, sx, ip_ival (ip)),
  700. r_stkend (1)));
  701. NEXT_OP;
  702. OP_(SETC0):
  703. OP_(SETC0L):
  704. KP_VTRY (nputcar (interp, xaref (as_fct(stack[bp - 1])->env,
  705. ip_ival (ip)),
  706. r_stkend (1)));
  707. NEXT_OP;
  708. OP_(CLREXC):
  709. interp->last_err = NIL;
  710. NEXT_OP;
  711. OP_(TRYBEGIN):
  712. OP_(TRYBEGINL):
  713. if (kp_likely (*(ip - 1) == OP_TRYBEGIN))
  714. sx = get16 (ip) - sizeof (int16_t), ip += sizeof (int16_t);
  715. else
  716. sx = fetch32 (ip) - sizeof (int32_t);
  717. sx += ip - as_bvector(fct_bcode (stack[bp - 1]))->data;
  718. U_PUSH (fixint (interp->exc_offset));
  719. U_PUSH (fixint (sx));
  720. interp->exc_offset = interp->stklen () - 2;
  721. NEXT_OP;
  722. OP_(TRYEND):
  723. interp->pop ();
  724. interp->exc_offset = as_int (r_stkend (2));
  725. interp->popn (2);
  726. U_PUSH (retval);
  727. NEXT_OP;
  728. OP_(LOADX):
  729. OP_(LOADXL):
  730. interp->aux = fvals[ip_ival (ip)];
  731. if ((retval = symval (interp, interp->aux)) == UNBOUND)
  732. return (interp->raise ("unbound-error",
  733. KP_SPRINTF (interp,
  734. "symbol %Q is unbound",
  735. interp->aux)));
  736. U_PUSH (retval);
  737. NEXT_OP;
  738. OP_(OPTARGS):
  739. OP_(OPTARGSL):
  740. if (kp_likely (!bcode_long_p (*(ip - 1))))
  741. ix = *ip++, n = (int8_t)*ip++;
  742. else
  743. ix = fetch32 (ip), n = fetch32 (ip);
  744. if ((int32_t)n <= 0)
  745. n = -(int32_t)n;
  746. if (n > nargs)
  747. {
  748. n -= nargs;
  749. stkend += n;
  750. r_stkend(1) = r_stkend (n + 1);
  751. r_stkend(2) = r_stkend (n + 2);
  752. r_stkend(3) = fixint (nargs + n);
  753. r_stkend(4) = r_stkend (n + 4);
  754. r_stkend(5) = r_stkend (n + 5);
  755. interp->cur_frame = interp->stklen ();
  756. for (ix = 0; ix < n; ++ix)
  757. stack[bp + nargs + ix] = UNBOUND;
  758. nargs += n;
  759. }
  760. NEXT_OP;
  761. OP_(LDCALLER):
  762. U_PUSH (stack[bp - 1]);
  763. NEXT_OP;
  764. OP_(KWARGS):
  765. OP_(KWARGSL):
  766. if (kp_likely (*(ip - 1) == OP_KWARGS))
  767. {
  768. ix = (int8_t)*ip++;
  769. n = (int8_t)*ip++;
  770. sx = (int8_t)*ip++;
  771. }
  772. else
  773. {
  774. ix = fetch32 (ip);
  775. n = fetch32 (ip);
  776. sx = fetch32 (ip);
  777. }
  778. nargs = KP_TRY (process_keys (interp, *fvals, ix, n, abs (sx) - ix - n,
  779. bp, nargs, sx < 0));
  780. NEXT_OP;
  781. OP_(MKCONT):
  782. {
  783. interp->pop ();
  784. coroutine *crp;
  785. if (cont && cont->crp->frame == interp->cur_frame)
  786. { // Update coroutine.
  787. crp = cont->crp;
  788. crp->argv = interp->stkobj;
  789. crp->exc_off = interp->exc_offset;
  790. }
  791. else
  792. {
  793. KP_VTRY (coroutine::make (interp, bp));
  794. crp = as_coro (interp->alval);
  795. }
  796. sx = *ip++;
  797. crp->ip_offset = sx + (ip -
  798. as_bvector (fct_bcode(stack[bp - 1]))->data);
  799. crp->value = retval;
  800. crp->sp_diff = interp->stklen () - interp->cur_frame;
  801. U_PUSH (crp->as_obj ());
  802. NEXT_OP;
  803. }
  804. OP_(BOX):
  805. OP_(BOXL):
  806. sx = ip_ival (ip);
  807. if (!xcons_p (stack[bp + sx]) ||
  808. xcdr (stack[bp + sx]) != NIL | EXTRA_BIT)
  809. { stack[bp + sx] = KP_TRY (cons::make (interp, stack[bp + sx],
  810. NIL | EXTRA_BIT)); }
  811. NEXT_OP;
  812. OP_(LOADB):
  813. OP_(LOADBL):
  814. U_PUSH (xcar (stack[bp + ip_ival (ip)]));
  815. NEXT_OP;
  816. OP_(SETB):
  817. OP_(SETBL):
  818. KP_VTRY (nputcar (interp, stack[bp + ip_ival (ip)], r_stkend (1)));
  819. NEXT_OP;
  820. OP_(VFRAME):
  821. U_PUSH (stack[interp->cur_frame - 1]);
  822. U_PUSH (fixint (0));
  823. stack[interp->cur_frame - 1] =
  824. fixint (interp->stklen () - interp->cur_frame - 1);
  825. NEXT_OP;
  826. OP_(BIND):
  827. OP_(BINDL):
  828. U_PUSH (fvals[ip_ival (ip)]);
  829. r_stkend(2) = KP_TRY (interp->dbind (r_stkend (1), r_stkend (2)));
  830. stack[interp->cur_frame +
  831. as_int (stack[interp->cur_frame - 1])] += fixint (1);
  832. NEXT_OP;
  833. OP_(UNBIND):
  834. KP_VTRY (interp->unbind ((uint32_t)(int8_t)*ip++,
  835. cont ? cont->crp : nullptr));
  836. NEXT_OP;
  837. OP_(UNBINDL):
  838. KP_VTRY (interp->unbind (fetch32 (ip), cont ? cont->crp : nullptr));
  839. NEXT_OP;
  840. OP_(SKIP):
  841. OP_(SKIPL):
  842. retval = r_stkend (1);
  843. stkend -= ip_ival (ip);
  844. r_stkend(1) = retval;
  845. NEXT_OP;
  846. OP_(RAISE):
  847. sx = *ip;
  848. if (sx == 0)
  849. {
  850. if (nil_p (interp->last_err))
  851. return (interp->raise ("runtime error", "no exception to reraise"));
  852. return (interp->raise (interp->last_err));
  853. }
  854. else
  855. {
  856. object exc = r_stkend (sx);
  857. cnp = as<cons> (sx == 1 ? NIL : r_stkend (1));
  858. if (!cnp)
  859. return (interp->raise ("arg-error",
  860. "raise: traceback argument must be a list"));
  861. interp->last_tb = cnp->as_obj ();
  862. return (interp->raise (exc));
  863. }
  864. OP_(CLOSURE):
  865. {
  866. KP_VTRY (alloc_fct (interp));
  867. function *fp = as_fct (interp->alval);
  868. as_fct(r_stkend (1))->copy_into (fp);
  869. r_stkend(1) = fp->as_obj ();
  870. KP_VTRY (captenv (interp, bp, fp));
  871. NEXT_OP;
  872. }
  873. #ifndef GOTO_LABELS
  874. default:
  875. goto dispatch;
  876. #endif
  877. }
  878. #ifdef GOTO_LABELS
  879. return (UNBOUND); // NOTREACHED
  880. #else
  881. goto dispatch;
  882. #endif
  883. #undef GOTO_LABELS
  884. #undef U_PUSH
  885. #undef r_stkend
  886. }
  887. static result<object>
  888. apply_n (interpreter *interp, uint32_t nargs, cont_data *conp = nullptr)
  889. {
  890. call_data cd, *cdp = nullptr;
  891. cd.topf = interp->cur_frame;
  892. while (true)
  893. {
  894. auto ret = run_bytecode (interp, nargs, conp, cdp);
  895. if (!ret.error_p ())
  896. return (*ret);
  897. bool exh = KP_TRY (interp->exc_handle ());
  898. if (!exh)
  899. /* No catch frame to handle this exception. Now it's the
  900. * top level's responsibility. */
  901. return (exception ());
  902. cd.ip_offset = as_int (interp->aux);
  903. cdp = &cd;
  904. }
  905. }
  906. result<object> call_coroutine (interpreter *interp,
  907. coroutine *crp, object value)
  908. {
  909. cont_data cd;
  910. cd.crp = crp;
  911. cd.value = value;
  912. return (apply_n (interp, 0, &cd));
  913. }
  914. result<object> call_n (interpreter *interp, uint32_t nargs)
  915. {
  916. object fn = *(interp->stkend - nargs - 1);
  917. if (native_fct_p (fn))
  918. return (as_native_fct(fn)->call (interp, nargs));
  919. call_guard g (interp, nargs + 1);
  920. if (indexer_t seq = index_seq (fn))
  921. KP_VTRY (call_indexer (interp, seq, fn, nargs));
  922. else if (!fct_p (fn))
  923. return (interp->raise ("arg-error",
  924. KP_SPRINTF (interp,
  925. "object of type %Q is not callable",
  926. type (fn))));
  927. else
  928. KP_VTRY (apply_n (interp, nargs));
  929. return (interp->retval);
  930. }
  931. // (apply fn arg1 [...args])
  932. result<object> apply_fct (interpreter *interp, object *argv, int argc)
  933. {
  934. uint32_t sp = interp->stklen ();
  935. KP_VTRY (interp->growstk (argc - 1));
  936. for (int i = 0; i < argc - 1; ++i)
  937. *interp->stkend++ = argv[i];
  938. KP_VTRY (push_seq (interp, argv[argc - 1], argc));
  939. return (call_n (interp, interp->stklen () - sp - 1));
  940. }
  941. result<object> eval (interpreter *interp, object expr)
  942. {
  943. valref tmp (interp, expr);
  944. // Avoid compiling the expression for trivial cases.
  945. switch (itype (expr))
  946. {
  947. case typecode::SYMBOL:
  948. if (as_symbol(expr)->flagged_p (symbol::ctv_flag | symbol::alias_flag))
  949. break;
  950. interp->retval = symval (expr);
  951. if (interp->retval == UNBOUND)
  952. return (interp->raise ("unbound-error",
  953. KP_SPRINTF (interp,
  954. "symbol %Q is unbound", expr)));
  955. return (interp->retval);
  956. case typecode::CONS:
  957. if (expr == NIL)
  958. kp_return (expr);
  959. else if (xcar (expr) == symbol::quote &&
  960. cons_p (xcdr (expr)) && xcddr (expr) == NIL)
  961. kp_return (xcadr (expr));
  962. break;
  963. case typecode::ARRAY:
  964. case typecode::TABLE:
  965. case typecode::TUPLE:
  966. // These need special handling to resolve local symbols.
  967. break;
  968. case typecode::STR:
  969. // Handle string interpolation.
  970. *tmp = expr = KP_TRY (expand_str (interp, expr));
  971. if (str_p (expr))
  972. kp_return (expr);
  973. break;
  974. default:
  975. kp_return (expr);
  976. }
  977. valref e2 = KP_TRY (macroexp (interp, expr));
  978. KP_PUSH_ALL (interp, compile_expr (interp, *e2));
  979. return (call_n (interp, 0));
  980. }
  981. KP_DECLS_END