bytecode.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /* Declarations for bytecode operations.
  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. #ifndef __KP_BYTECODE__
  14. #define __KP_BYTECODE__ 1
  15. #include "defs.hpp"
  16. KP_DECLS_BEGIN
  17. enum
  18. {
  19. OP_NOP,
  20. OP_DUP,
  21. OP_POP,
  22. OP_RET,
  23. OP_IS,
  24. OP_NOT,
  25. OP_CONS,
  26. OP_CAR,
  27. OP_CDR,
  28. OP_CADR,
  29. OP_APPLY,
  30. OP_TAPPLY,
  31. OP_LOADT,
  32. OP_LOADNIL,
  33. OP_LOAD0,
  34. OP_LOAD1,
  35. OP_LOADA0,
  36. OP_LOADA1,
  37. OP_LOADC00,
  38. OP_LOADC01,
  39. OP_MKCONT,
  40. OP_CLOSURE,
  41. OP_VFRAME,
  42. OP_TRYEND,
  43. OP_LDCALLER,
  44. OP_CLREXC,
  45. OP_SYMNAME,
  46. OP_SYMPKG,
  47. OP_COROVAL,
  48. OP_TYPEP,
  49. OP_TYPEP2,
  50. OP_RAISE,
  51. // Opcodes with long forms.
  52. OP_LOADI8,
  53. OP_LOADI32,
  54. OP_LOADCHR8,
  55. OP_LOADCHR32,
  56. OP_VARGC,
  57. OP_VARGCL,
  58. OP_JMP,
  59. OP_JMPL,
  60. OP_BRT,
  61. OP_BRTL,
  62. OP_BRN,
  63. OP_BRNL,
  64. OP_BRNEQ,
  65. OP_BRNEQL,
  66. OP_TCALL,
  67. OP_TCALLL,
  68. OP_CALL,
  69. OP_CALLL,
  70. OP_RECUR,
  71. OP_RECURL,
  72. OP_TRECUR,
  73. OP_TRECURL,
  74. OP_SETC0,
  75. OP_SETC0L,
  76. OP_SETC,
  77. OP_SETCL,
  78. OP_SETA,
  79. OP_SETAL,
  80. OP_SETG,
  81. OP_SETGL,
  82. OP_SETFGS,
  83. OP_SETFGSL,
  84. OP_LOADC0,
  85. OP_LOADC0L,
  86. OP_LOADC,
  87. OP_LOADCL,
  88. OP_LOADA,
  89. OP_LOADAL,
  90. OP_LOADG,
  91. OP_LOADGL,
  92. OP_LOADV,
  93. OP_LOADVL,
  94. OP_LOADX,
  95. OP_LOADXL,
  96. OP_LOADFGS,
  97. OP_LOADFGSL,
  98. OP_BIND,
  99. OP_BINDL,
  100. OP_TRYBEGIN,
  101. OP_TRYBEGINL,
  102. OP_SETAPOP,
  103. OP_SETAPOPL,
  104. OP_IRTJMP,
  105. OP_IRTJMPL,
  106. OP_OPTARGS,
  107. OP_OPTARGSL,
  108. OP_BRBOUND,
  109. OP_BRBOUNDL,
  110. OP_KWARGS,
  111. OP_KWARGSL,
  112. OP_JMPT,
  113. OP_JMPTL,
  114. OP_JMPN,
  115. OP_JMPNL,
  116. OP_BOX,
  117. OP_BOXL,
  118. OP_LOADB,
  119. OP_LOADBL,
  120. OP_SETB,
  121. OP_SETBL,
  122. OP_SKIP,
  123. OP_SKIPL,
  124. OP_UNBIND,
  125. OP_UNBINDL
  126. };
  127. struct bcode_instr
  128. {
  129. uint16_t name_off;
  130. uint16_t flg_ex;
  131. static const int BC_FLG_FBIT = 2;
  132. static const int BC_OPS_MASK = (1 << BC_FLG_FBIT) - 1;
  133. #define F_(n) (1 << (BC_FLG_FBIT + n))
  134. static const int BC_CALL_FORM = F_(0);
  135. static const int BC_LOAD_FORM = F_(1);
  136. static const int BC_BRANCH_FORM = F_(2);
  137. static const int BC_LONG_FORM = F_(3);
  138. static const int BC_PURE_FORM = F_(4);
  139. #undef F_
  140. int opcode () const;
  141. const char* name () const;
  142. int nops () const
  143. {
  144. return (this->flg_ex & BC_OPS_MASK);
  145. }
  146. bool branch_p () const
  147. {
  148. return ((this->flg_ex & BC_BRANCH_FORM) != 0);
  149. }
  150. bool long_p () const
  151. {
  152. return ((this->flg_ex & BC_LONG_FORM) != 0);
  153. }
  154. bool loadf_p () const
  155. {
  156. return ((this->flg_ex & BC_LOAD_FORM) != 0);
  157. }
  158. bool callf_p () const
  159. {
  160. return ((this->flg_ex & BC_CALL_FORM) != 0);
  161. }
  162. bool pure_p () const
  163. {
  164. return ((this->flg_ex & BC_PURE_FORM) != 0);
  165. }
  166. int argsize () const
  167. {
  168. return (this->long_p () ? sizeof (int32_t) :
  169. (this->branch_p () ? sizeof (int16_t) : 1));
  170. }
  171. uint32_t getuarg (const void *ptr) const
  172. {
  173. switch (this->argsize ())
  174. {
  175. case sizeof (uint32_t):
  176. return ((uint32_t)get32 (ptr));
  177. case sizeof (uint16_t):
  178. return ((uint16_t)get16 (ptr));
  179. default:
  180. return (*(uint8_t *)ptr);
  181. }
  182. }
  183. int getsarg (const void *ptr) const
  184. {
  185. switch (this->argsize ())
  186. {
  187. case sizeof (int32_t):
  188. return ((int32_t)get32 (ptr));
  189. case sizeof (int16_t):
  190. return ((int16_t)get16 (ptr));
  191. default:
  192. return (*(int8_t *)ptr);
  193. }
  194. }
  195. };
  196. KP_EXPORT const bcode_instr* bcode_get (int opc) __attribute__ ((pure));
  197. inline const char* bcode_name (int opc)
  198. {
  199. return (bcode_get(opc)->name ());
  200. }
  201. inline int
  202. bcode_nops (int opc)
  203. {
  204. return (bcode_get(opc)->nops ());
  205. }
  206. inline bool
  207. bcode_branch_p (int opc)
  208. {
  209. return (bcode_get(opc)->branch_p ());
  210. }
  211. inline bool
  212. bcode_long_p (int opc)
  213. {
  214. return (bcode_get(opc)->long_p ());
  215. }
  216. KP_DECLS_END
  217. #endif