include/ktap_bc.h - ktap

Data types defined

Functions defined

Macros defined

Source code

  1. /*
  2. * Bytecode instruction format.
  3. *
  4. * Copyright (C) 2012-2014 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
  5. * Copyright (C) 2005-2014 Mike Pall.
  6. */

  7. #ifndef __KTAP_BC_H__
  8. #define __KTAP_BC_H__

  9. #include "../include/ktap_arch.h"

  10. /*TODO*/
  11. #define KP_STATIC_ASSERT(cond)
  12. #define kp_assert(cond)

  13. /* Types for handling bytecodes. */
  14. typedef uint32_t BCIns/* Bytecode instruction. */
  15. typedef uint32_t BCPos/* Bytecode position. */
  16. typedef uint32_t BCReg/* Bytecode register. */
  17. typedef int32_t BCLine/* Bytecode line number. */

  18. /*
  19. * Bytecode instruction format, 32 bit wide, fields of 8 or 16 bit:
  20. *
  21. * +----+----+----+----+
  22. * | B  | C  | A  | OP | Format ABC
  23. * +----+----+----+----+
  24. * |    D    | A  | OP | Format AD
  25. * +--------------------
  26. * MSB               LSB
  27. *
  28. * In-memory instructions are always stored in host byte order.
  29. */

  30. /* Operand ranges and related constants. */
  31. #define BCMAX_A        0xff
  32. #define BCMAX_B        0xff
  33. #define BCMAX_C        0xff
  34. #define BCMAX_D        0xffff
  35. #define BCBIAS_J    0x8000
  36. #define NO_REG        BCMAX_A
  37. #define NO_JMP        (~(BCPos)0)

  38. /* Macros to get instruction fields. */
  39. #define bc_op(i)    ((BCOp)((i)&0xff))
  40. #define bc_a(i)        ((BCReg)(((i)>>8)&0xff))
  41. #define bc_b(i)        ((BCReg)((i)>>24))
  42. #define bc_c(i)        ((BCReg)(((i)>>16)&0xff))
  43. #define bc_d(i)        ((BCReg)((i)>>16))
  44. #define bc_j(i)        ((ptrdiff_t)bc_d(i)-BCBIAS_J)

  45. /* Macros to set instruction fields. */
  46. #define setbc_byte(p, x, ofs) \
  47.     ((uint8_t *)(p))[KP_ENDIAN_SELECT(ofs, 3 - ofs)] = (uint8_t)(x)
  48. #define setbc_op(p, x)    setbc_byte(p, (x), 0)
  49. #define setbc_a(p, x)    setbc_byte(p, (x), 1)
  50. #define setbc_b(p, x)    setbc_byte(p, (x), 3)
  51. #define setbc_c(p, x)    setbc_byte(p, (x), 2)
  52. #define setbc_d(p, x) \
  53.     ((uint16_t *)(p))[KP_ENDIAN_SELECT(1, 0)] = (uint16_t)(x)
  54. #define setbc_j(p, x)    setbc_d(p, (BCPos)((int32_t)(x)+BCBIAS_J))

  55. /* Macros to compose instructions. */
  56. #define BCINS_ABC(o, a, b, c) \
  57.     (((BCIns)(o))|((BCIns)(a)<<8)|((BCIns)(b)<<24)|((BCIns)(c)<<16))
  58. #define BCINS_AD(o, a, d) \
  59.     (((BCIns)(o))|((BCIns)(a)<<8)|((BCIns)(d)<<16))
  60. #define BCINS_AJ(o, a, j)    BCINS_AD(o, a, (BCPos)((int32_t)(j)+BCBIAS_J))

  61. /*
  62. * Bytecode instruction definition. Order matters, see below.
  63. *
  64. * (name, filler, Amode, Bmode, Cmode or Dmode, metamethod)
  65. *
  66. * The opcode name suffixes specify the type for RB/RC or RD:
  67. * V = variable slot
  68. * S = string const
  69. * N = number const
  70. * P = primitive type (~itype)
  71. * B = unsigned byte literal
  72. * M = multiple args/results
  73. */
  74. #define BCDEF(_) \
  75.     /* Comparison ops. ORDER OPR. */ \
  76.     _(ISLT,    var,    ___,    var,    lt) \
  77.     _(ISGE,    var,    ___,    var,    lt) \
  78.     _(ISLE,    var,    ___,    var,    le) \
  79.     _(ISGT,    var,    ___,    var,    le) \
  80.     \
  81.     _(ISEQV,    var,    ___,    var,    eq) \
  82.     _(ISNEV,    var,    ___,    var,    eq) \
  83.     _(ISEQS,    var,    ___,    str,    eq) \
  84.     _(ISNES,    var,    ___,    str,    eq) \
  85.     _(ISEQN,    var,    ___,    num,    eq) \
  86.     _(ISNEN,    var,    ___,    num,    eq) \
  87.     _(ISEQP,    var,    ___,    pri,    eq) \
  88.     _(ISNEP,    var,    ___,    pri,    eq) \
  89.     \
  90.     /* Unary test and copy ops. */ \
  91.     _(ISTC,    dst,    ___,    var,    ___) \
  92.     _(ISFC,    dst,    ___,    var,    ___) \
  93.     _(IST,    ___,    ___,    var,    ___) \
  94.     _(ISF,    ___,    ___,    var,    ___) \
  95.     _(ISTYPE,    var,    ___,    lit,    ___) \
  96.     _(ISNUM,    var,    ___,    lit,    ___) \
  97.     \
  98.     /* Unary ops. */ \
  99.     _(MOV,    dst,    ___,    var,    ___) \
  100.     _(NOT,    dst,    ___,    var,    ___) \
  101.     _(UNM,    dst,    ___,    var,    unm) \
  102.     \
  103.     /* Binary ops. ORDER OPR. VV last, POW must be next. */ \
  104.     _(ADDVN,    dst,    var,    num,    add) \
  105.     _(SUBVN,    dst,    var,    num,    sub) \
  106.     _(MULVN,    dst,    var,    num,    mul) \
  107.     _(DIVVN,    dst,    var,    num,    div) \
  108.     _(MODVN,    dst,    var,    num,    mod) \
  109.     \
  110.     _(ADDNV,    dst,    var,    num,    add) \
  111.     _(SUBNV,    dst,    var,    num,    sub) \
  112.     _(MULNV,    dst,    var,    num,    mul) \
  113.     _(DIVNV,    dst,    var,    num,    div) \
  114.     _(MODNV,    dst,    var,    num,    mod) \
  115.     \
  116.     _(ADDVV,    dst,    var,    var,    add) \
  117.     _(SUBVV,    dst,    var,    var,    sub) \
  118.     _(MULVV,    dst,    var,    var,    mul) \
  119.     _(DIVVV,    dst,    var,    var,    div) \
  120.     _(MODVV,    dst,    var,    var,    mod) \
  121.     \
  122.     _(POW,    dst,    var,    var,    pow) \
  123.     _(CAT,    dst,    rbase,    rbase,    concat) \
  124.     \
  125.     /* Constant ops. */ \
  126.     _(KSTR,    dst,    ___,    str,    ___) \
  127.     _(KCDATA,    dst,    ___,    cdata,    ___) \
  128.     _(KSHORT,    dst,    ___,    lits,    ___) \
  129.     _(KNUM,    dst,    ___,    num,    ___) \
  130.     _(KPRI,    dst,    ___,    pri,    ___) \
  131.     _(KNIL,    base,    ___,    base,    ___) \
  132.     \
  133.     /* Upvalue and function ops. */ \
  134.     _(UGET,    dst,    ___,    uv,    ___) \
  135.     _(USETV,    uv,    ___,    var,    ___) \
  136.     _(UINCV,    uv,    ___,    var,    ___) \
  137.     _(USETS,    uv,    ___,    str,    ___) \
  138.     _(USETN,    uv,    ___,    num,    ___) \
  139.     _(UINCN,    uv,    ___,    num,    ___) \
  140.     _(USETP,    uv,    ___,    pri,    ___) \
  141.     _(UCLO,    rbase,    ___,    jump,    ___) \
  142.     _(FNEW,    dst,    ___,    func,    gc) \
  143.     \
  144.     /* Table ops. */ \
  145.     _(TNEW,    dst,    ___,    lit,    gc) \
  146.     _(TDUP,    dst,    ___,    tab,    gc) \
  147.     _(GGET,    dst,    ___,    str,    index) \
  148.     _(GSET,    var,    ___,    str,    newindex) \
  149.     _(GINC,    var,    ___,    str,    newindex) \
  150.     _(TGETV,    dst,    var,    var,    index) \
  151.     _(TGETS,    dst,    var,    str,    index) \
  152.     _(TGETB,    dst,    var,    lit,    index) \
  153.     _(TGETR,    dst,    var,    var,    index) \
  154.     _(TSETV,    var,    var,    var,    newindex) \
  155.     _(TINCV,    var,    var,    var,    newindex) \
  156.     _(TSETS,    var,    var,    str,    newindex) \
  157.     _(TINCS,    var,    var,    str,    newindex) \
  158.     _(TSETB,    var,    var,    lit,    newindex) \
  159.     _(TINCB,    var,    var,    lit,    newindex) \
  160.     _(TSETM,    base,    ___,    num,    newindex) \
  161.     _(TSETR,    var,    var,    var,    newindex) \
  162.     \
  163.     /* Calls and vararg handling. T = tail call. */ \
  164.     _(CALLM,    base,    lit,    lit,    call) \
  165.     _(CALL,    base,    lit,    lit,    call) \
  166.     _(CALLMT,    base,    ___,    lit,    call) \
  167.     _(CALLT,    base,    ___,    lit,    call) \
  168.     _(ITERC,    base,    lit,    lit,    call) \
  169.     _(ITERN,    base,    lit,    lit,    call) \
  170.     _(VARG,    base,    lit,    lit,    ___) \
  171.     _(ISNEXT,    base,    ___,    jump,    ___) \
  172.     \
  173.     /* Returns. */ \
  174.     _(RETM,    base,    ___,    lit,    ___) \
  175.     _(RET,    rbase,    ___,    lit,    ___) \
  176.     _(RET0,    rbase,    ___,    lit,    ___) \
  177.     _(RET1,    rbase,    ___,    lit,    ___) \
  178.     \
  179.     /* Loops and branches. I/J = interp/JIT, I/C/L = init/call/loop. */ \
  180.     _(FORI,    base,    ___,    jump,    ___) \
  181.     _(JFORI,    base,    ___,    jump,    ___) \
  182.     \
  183.     _(FORL,    base,    ___,    jump,    ___) \
  184.     _(IFORL,    base,    ___,    jump,    ___) \
  185.     _(JFORL,    base,    ___,    lit,    ___) \
  186.     \
  187.     _(ITERL,    base,    ___,    jump,    ___) \
  188.     _(IITERL,    base,    ___,    jump,    ___) \
  189.     _(JITERL,    base,    ___,    lit,    ___) \
  190.     \
  191.     _(LOOP,    rbase,    ___,    jump,    ___) \
  192.     _(ILOOP,    rbase,    ___,    jump,    ___) \
  193.     _(JLOOP,    rbase,    ___,    lit,    ___) \
  194.     \
  195.     _(JMP,    rbase,    ___,    jump,    ___) \
  196.     \
  197.     /*Function headers. I/J = interp/JIT, F/V/C = fixarg/vararg/C func.*/ \
  198.     _(FUNCF,    rbase,    ___,    ___,    ___) \
  199.     _(IFUNCF,    rbase,    ___,    ___,    ___) \
  200.     _(JFUNCF,    rbase,    ___,    lit,    ___) \
  201.     _(FUNCV,    rbase,    ___,    ___,    ___) \
  202.     _(IFUNCV,    rbase,    ___,    ___,    ___) \
  203.     _(JFUNCV,    rbase,    ___,    lit,    ___) \
  204.     _(FUNCC,    rbase,    ___,    ___,    ___) \
  205.     _(FUNCCW,    rbase,    ___,    ___,    ___) \
  206.     \
  207.     /* specific purpose bc. */    \
  208.     _(VARGN,    dst, ___,    lit,    ___) \
  209.     _(VARGSTR,    dst, ___,    lit,    ___) \
  210.     _(VPROBENAME,    dst, ___,    lit,    ___) \
  211.     _(VPID,        dst, ___,    lit,    ___) \
  212.     _(VTID,        dst, ___,    lit,    ___) \
  213.     _(VUID,        dst, ___,    lit,    ___) \
  214.     _(VCPU,        dst, ___,    lit,    ___) \
  215.     _(VEXECNAME,    dst, ___,    lit,    ___) \
  216.     \
  217.     _(GFUNC,    dst, ___,    ___,    ___) /*load global C function*/

  218. /* Bytecode opcode numbers. */
  219. typedef enum {
  220. #define BCENUM(name, ma, mb, mc, mt)    BC_##name,
  221.     BCDEF(BCENUM)
  222. #undef BCENUM
  223.     BC__MAX
  224. } BCOp;

  225. KP_STATIC_ASSERT((int)BC_ISEQV+1 == (int)BC_ISNEV);
  226. KP_STATIC_ASSERT(((int)BC_ISEQV^1) == (int)BC_ISNEV);
  227. KP_STATIC_ASSERT(((int)BC_ISEQS^1) == (int)BC_ISNES);
  228. KP_STATIC_ASSERT(((int)BC_ISEQN^1) == (int)BC_ISNEN);
  229. KP_STATIC_ASSERT(((int)BC_ISEQP^1) == (int)BC_ISNEP);
  230. KP_STATIC_ASSERT(((int)BC_ISLT^1) == (int)BC_ISGE);
  231. KP_STATIC_ASSERT(((int)BC_ISLE^1) == (int)BC_ISGT);
  232. KP_STATIC_ASSERT(((int)BC_ISLT^3) == (int)BC_ISGT);
  233. KP_STATIC_ASSERT((int)BC_IST-(int)BC_ISTC == (int)BC_ISF-(int)BC_ISFC);
  234. KP_STATIC_ASSERT((int)BC_CALLT-(int)BC_CALL == (int)BC_CALLMT-(int)BC_CALLM);
  235. KP_STATIC_ASSERT((int)BC_CALLMT + 1 == (int)BC_CALLT);
  236. KP_STATIC_ASSERT((int)BC_RETM + 1 == (int)BC_RET);
  237. KP_STATIC_ASSERT((int)BC_FORL + 1 == (int)BC_IFORL);
  238. KP_STATIC_ASSERT((int)BC_FORL + 2 == (int)BC_JFORL);
  239. KP_STATIC_ASSERT((int)BC_ITERL + 1 == (int)BC_IITERL);
  240. KP_STATIC_ASSERT((int)BC_ITERL + 2 == (int)BC_JITERL);
  241. KP_STATIC_ASSERT((int)BC_LOOP + 1 == (int)BC_ILOOP);
  242. KP_STATIC_ASSERT((int)BC_LOOP + 2 == (int)BC_JLOOP);
  243. KP_STATIC_ASSERT((int)BC_FUNCF + 1 == (int)BC_IFUNCF);
  244. KP_STATIC_ASSERT((int)BC_FUNCF + 2 == (int)BC_JFUNCF);
  245. KP_STATIC_ASSERT((int)BC_FUNCV + 1 == (int)BC_IFUNCV);
  246. KP_STATIC_ASSERT((int)BC_FUNCV + 2 == (int)BC_JFUNCV);

  247. /* This solves a circular dependency problem, change as needed. */
  248. #define FF_next_N    4

  249. /* Stack slots used by FORI/FORL, relative to operand A. */
  250. enum {
  251.     FORL_IDX, FORL_STOP, FORL_STEP, FORL_EXT
  252. };

  253. /* Bytecode operand modes. ORDER BCMode */
  254. typedef enum {
  255.     /* Mode A must be <= 7 */
  256.     BCMnone, BCMdst, BCMbase, BCMvar, BCMrbase, BCMuv,
  257.     BCMlit, BCMlits, BCMpri, BCMnum, BCMstr, BCMtab, BCMfunc,
  258.     BCMjump, BCMcdata,
  259.     BCM_max
  260. } BCMode;

  261. #define BCM___    BCMnone

  262. #define bcmode_a(op)    ((BCMode)(bc_mode[op] & 7))
  263. #define bcmode_b(op)    ((BCMode)((bc_mode[op] >> 3) & 15))
  264. #define bcmode_c(op)    ((BCMode)((bc_mode[op] >> 7) & 15))
  265. #define bcmode_d(op)    bcmode_c(op)
  266. #define bcmode_hasd(op)    ((bc_mode[op] & (15 << 3)) == (BCMnone << 3))
  267. #define bcmode_mm(op)    ((MMS)(bc_mode[op] >> 11))

  268. #define BCMODE(name, ma, mb, mc, mm) \
  269.     (BCM##ma | (BCM##mb << 3) | (BCM##mc << 7)|(MM_##mm << 11)),
  270. #define BCMODE_FF    0

  271. static inline int bc_isret(BCOp op)
  272. {
  273.     return (op == BC_RETM || op == BC_RET || op == BC_RET0 ||
  274.         op == BC_RET1);
  275. }

  276. /*
  277. * Metamethod definition
  278. * Note ktap don't use any lua methmethod currently.
  279. */
  280. typedef enum {
  281.     MM_lt,
  282.     MM_le,
  283.     MM_eq,
  284.     MM_unm,
  285.     MM_add,
  286.     MM_sub,
  287.     MM_mul,
  288.     MM_div,
  289.     MM_mod,
  290.     MM_pow,
  291.     MM_concat,
  292.     MM_gc,
  293.     MM_index,
  294.     MM_newindex,
  295.     MM_call,
  296.     MM__MAX,
  297.     MM____ = MM__MAX
  298. } MMS;


  299. /* -- Bytecode dump format ------------------------------------------------ */

  300. /*
  301. ** dump   = header proto+ 0U
  302. ** header = ESC 'L' 'J' versionB flagsU [namelenU nameB*]
  303. ** proto  = lengthU pdata
  304. ** pdata  = phead bcinsW* uvdataH* kgc* knum* [debugB*]
  305. ** phead  = flagsB numparamsB framesizeB numuvB numkgcU numknU numbcU
  306. **          [debuglenU [firstlineU numlineU]]
  307. ** kgc    = kgctypeU { ktab | (loU hiU) | (rloU rhiU iloU ihiU) | strB* }
  308. ** knum   = intU0 | (loU1 hiU)
  309. ** ktab   = narrayU nhashU karray* khash*
  310. ** karray = ktabk
  311. ** khash  = ktabk ktabk
  312. ** ktabk  = ktabtypeU { intU | (loU hiU) | strB* }
  313. **
  314. ** B = 8 bit, H = 16 bit, W = 32 bit, U = ULEB128 of W, U0/U1 = ULEB128 of W+1
  315. */

  316. /* Bytecode dump header. */
  317. #define BCDUMP_HEAD1        0x15
  318. #define BCDUMP_HEAD2        0x22
  319. #define BCDUMP_HEAD3        0x06

  320. /* If you perform *any* kind of private modifications to the bytecode itself
  321. ** or to the dump format, you *must* set BCDUMP_VERSION to 0x80 or higher.
  322. */
  323. #define BCDUMP_VERSION        1

  324. /* Compatibility flags. */
  325. #define BCDUMP_F_BE        0x01
  326. #define BCDUMP_F_STRIP        0x02
  327. #define BCDUMP_F_FFI        0x04

  328. #define BCDUMP_F_KNOWN        (BCDUMP_F_FFI*2-1)

  329. /* Type codes for the GC constants of a prototype. Plus length for strings. */
  330. enum {
  331.     BCDUMP_KGC_CHILD, BCDUMP_KGC_TAB, BCDUMP_KGC_I64, BCDUMP_KGC_U64,
  332.     BCDUMP_KGC_COMPLEX, BCDUMP_KGC_STR
  333. };

  334. /* Type codes for the keys/values of a constant table. */
  335. enum {
  336.     BCDUMP_KTAB_NIL, BCDUMP_KTAB_FALSE, BCDUMP_KTAB_TRUE,
  337.     BCDUMP_KTAB_INT, BCDUMP_KTAB_NUM, BCDUMP_KTAB_STR
  338. };

  339. #endif /* __KTAP_BC_H__ */