src/lj_meta.c - luajit-2.0-src

Functions defined

Macros defined

Source code

  1. /*
  2. ** Metamethod handling.
  3. ** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
  4. **
  5. ** Portions taken verbatim or adapted from the Lua interpreter.
  6. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
  7. */

  8. #define lj_meta_c
  9. #define LUA_CORE

  10. #include "lj_obj.h"
  11. #include "lj_gc.h"
  12. #include "lj_err.h"
  13. #include "lj_buf.h"
  14. #include "lj_str.h"
  15. #include "lj_tab.h"
  16. #include "lj_meta.h"
  17. #include "lj_frame.h"
  18. #include "lj_bc.h"
  19. #include "lj_vm.h"
  20. #include "lj_strscan.h"
  21. #include "lj_strfmt.h"
  22. #include "lj_lib.h"

  23. /* -- Metamethod handling ------------------------------------------------- */

  24. /* String interning of metamethod names for fast indexing. */
  25. void lj_meta_init(lua_State *L)
  26. {
  27. #define MMNAME(name)        "__" #name
  28.   const char *metanames = MMDEF(MMNAME);
  29. #undef MMNAME
  30.   global_State *g = G(L);
  31.   const char *p, *q;
  32.   uint32_t mm;
  33.   for (mm = 0, p = metanames; *p; mm++, p = q) {
  34.     GCstr *s;
  35.     for (q = p+2; *q && *q != '_'; q++) ;
  36.     s = lj_str_new(L, p, (size_t)(q-p));
  37.     /* NOBARRIER: g->gcroot[] is a GC root. */
  38.     setgcref(g->gcroot[GCROOT_MMNAME+mm], obj2gco(s));
  39.   }
  40. }

  41. /* Negative caching of a few fast metamethods. See the lj_meta_fast() macro. */
  42. cTValue *lj_meta_cache(GCtab *mt, MMS mm, GCstr *name)
  43. {
  44.   cTValue *mo = lj_tab_getstr(mt, name);
  45.   lua_assert(mm <= MM_FAST);
  46.   if (!mo || tvisnil(mo)) {  /* No metamethod? */
  47.     mt->nomm |= (uint8_t)(1u<<mm);  /* Set negative cache flag. */
  48.     return NULL;
  49.   }
  50.   return mo;
  51. }

  52. /* Lookup metamethod for object. */
  53. cTValue *lj_meta_lookup(lua_State *L, cTValue *o, MMS mm)
  54. {
  55.   GCtab *mt;
  56.   if (tvistab(o))
  57.     mt = tabref(tabV(o)->metatable);
  58.   else if (tvisudata(o))
  59.     mt = tabref(udataV(o)->metatable);
  60.   else
  61.     mt = tabref(basemt_obj(G(L), o));
  62.   if (mt) {
  63.     cTValue *mo = lj_tab_getstr(mt, mmname_str(G(L), mm));
  64.     if (mo)
  65.       return mo;
  66.   }
  67.   return niltv(L);
  68. }

  69. #if LJ_HASFFI
  70. /* Tailcall from C function. */
  71. int lj_meta_tailcall(lua_State *L, cTValue *tv)
  72. {
  73.   TValue *base = L->base;
  74.   TValue *top = L->top;
  75.   const BCIns *pc = frame_pc(base-1);  /* Preserve old PC from frame. */
  76.   copyTV(L, base-1-LJ_FR2, tv);  /* Replace frame with new object. */
  77.   if (LJ_FR2)
  78.     (top++)->u64 = LJ_CONT_TAILCALL;
  79.   else
  80.     top->u32.lo = LJ_CONT_TAILCALL;
  81.   setframe_pc(top++, pc);
  82.   if (LJ_FR2) top++;
  83.   setframe_gc(top, obj2gco(L), LJ_TTHREAD);  /* Dummy frame object. */
  84.   setframe_ftsz(top, ((char *)(top+1) - (char *)base) + FRAME_CONT);
  85.   L->base = L->top = top+1;
  86.   /*
  87.   ** before:   [old_mo|PC]    [... ...]
  88.   **                         ^base     ^top
  89.   ** after:    [new_mo|itype] [... ...] [NULL|PC] [dummy|delta]
  90.   **                                                           ^base/top
  91.   ** tailcall: [new_mo|PC]    [... ...]
  92.   **                         ^base     ^top
  93.   */
  94.   return 0;
  95. }
  96. #endif

  97. /* Setup call to metamethod to be run by Assembler VM. */
  98. static TValue *mmcall(lua_State *L, ASMFunction cont, cTValue *mo,
  99.                     cTValue *a, cTValue *b)
  100. {
  101.   /*
  102.   **           |-- framesize -> top       top+1       top+2 top+3
  103.   ** before:   [func slots ...]
  104.   ** mm setup: [func slots ...] [cont|?]  [mo|tmtype] [a]   [b]
  105.   ** in asm:   [func slots ...] [cont|PC] [mo|delta]  [a]   [b]
  106.   **           ^-- func base                          ^-- mm base
  107.   ** after mm: [func slots ...]           [result]
  108.   **                ^-- copy to base[PC_RA] --/     for lj_cont_ra
  109.   **                          istruecond + branch   for lj_cont_cond*
  110.   **                                       ignore   for lj_cont_nop
  111.   ** next PC:  [func slots ...]
  112.   */
  113.   TValue *top = L->top;
  114.   if (curr_funcisL(L)) top = curr_topL(L);
  115.   setcont(top++, cont);  /* Assembler VM stores PC in upper word or FR2. */
  116.   if (LJ_FR2) setnilV(top++);
  117.   copyTV(L, top++, mo);  /* Store metamethod and two arguments. */
  118.   if (LJ_FR2) setnilV(top++);
  119.   copyTV(L, top, a);
  120.   copyTV(L, top+1, b);
  121.   return top;  /* Return new base. */
  122. }

  123. /* -- C helpers for some instructions, called from assembler VM ----------- */

  124. /* Helper for TGET*. __index chain and metamethod. */
  125. cTValue *lj_meta_tget(lua_State *L, cTValue *o, cTValue *k)
  126. {
  127.   int loop;
  128.   for (loop = 0; loop < LJ_MAX_IDXCHAIN; loop++) {
  129.     cTValue *mo;
  130.     if (LJ_LIKELY(tvistab(o))) {
  131.       GCtab *t = tabV(o);
  132.       cTValue *tv = lj_tab_get(L, t, k);
  133.       if (!tvisnil(tv) ||
  134.           !(mo = lj_meta_fast(L, tabref(t->metatable), MM_index)))
  135.         return tv;
  136.     } else if (tvisnil(mo = lj_meta_lookup(L, o, MM_index))) {
  137.       lj_err_optype(L, o, LJ_ERR_OPINDEX);
  138.       return NULL/* unreachable */
  139.     }
  140.     if (tvisfunc(mo)) {
  141.       L->top = mmcall(L, lj_cont_ra, mo, o, k);
  142.       return NULL/* Trigger metamethod call. */
  143.     }
  144.     o = mo;
  145.   }
  146.   lj_err_msg(L, LJ_ERR_GETLOOP);
  147.   return NULL/* unreachable */
  148. }

  149. /* Helper for TSET*. __newindex chain and metamethod. */
  150. TValue *lj_meta_tset(lua_State *L, cTValue *o, cTValue *k)
  151. {
  152.   TValue tmp;
  153.   int loop;
  154.   for (loop = 0; loop < LJ_MAX_IDXCHAIN; loop++) {
  155.     cTValue *mo;
  156.     if (LJ_LIKELY(tvistab(o))) {
  157.       GCtab *t = tabV(o);
  158.       cTValue *tv = lj_tab_get(L, t, k);
  159.       if (LJ_LIKELY(!tvisnil(tv))) {
  160.         t->nomm = 0/* Invalidate negative metamethod cache. */
  161.         lj_gc_anybarriert(L, t);
  162.         return (TValue *)tv;
  163.       } else if (!(mo = lj_meta_fast(L, tabref(t->metatable), MM_newindex))) {
  164.         t->nomm = 0/* Invalidate negative metamethod cache. */
  165.         lj_gc_anybarriert(L, t);
  166.         if (tv != niltv(L))
  167.           return (TValue *)tv;
  168.         if (tvisnil(k)) lj_err_msg(L, LJ_ERR_NILIDX);
  169.         else if (tvisint(k)) { setnumV(&tmp, (lua_Number)intV(k)); k = &tmp; }
  170.         else if (tvisnum(k) && tvisnan(k)) lj_err_msg(L, LJ_ERR_NANIDX);
  171.         return lj_tab_newkey(L, t, k);
  172.       }
  173.     } else if (tvisnil(mo = lj_meta_lookup(L, o, MM_newindex))) {
  174.       lj_err_optype(L, o, LJ_ERR_OPINDEX);
  175.       return NULL/* unreachable */
  176.     }
  177.     if (tvisfunc(mo)) {
  178.       L->top = mmcall(L, lj_cont_nop, mo, o, k);
  179.       /* L->top+2 = v filled in by caller. */
  180.       return NULL/* Trigger metamethod call. */
  181.     }
  182.     copyTV(L, &tmp, mo);
  183.     o = &tmp;
  184.   }
  185.   lj_err_msg(L, LJ_ERR_SETLOOP);
  186.   return NULL/* unreachable */
  187. }

  188. static cTValue *str2num(cTValue *o, TValue *n)
  189. {
  190.   if (tvisnum(o))
  191.     return o;
  192.   else if (tvisint(o))
  193.     return (setnumV(n, (lua_Number)intV(o)), n);
  194.   else if (tvisstr(o) && lj_strscan_num(strV(o), n))
  195.     return n;
  196.   else
  197.     return NULL;
  198. }

  199. /* Helper for arithmetic instructions. Coercion, metamethod. */
  200. TValue *lj_meta_arith(lua_State *L, TValue *ra, cTValue *rb, cTValue *rc,
  201.                       BCReg op)
  202. {
  203.   MMS mm = bcmode_mm(op);
  204.   TValue tempb, tempc;
  205.   cTValue *b, *c;
  206.   if ((b = str2num(rb, &tempb)) != NULL &&
  207.       (c = str2num(rc, &tempc)) != NULL) {  /* Try coercion first. */
  208.     setnumV(ra, lj_vm_foldarith(numV(b), numV(c), (int)mm-MM_add));
  209.     return NULL;
  210.   } else {
  211.     cTValue *mo = lj_meta_lookup(L, rb, mm);
  212.     if (tvisnil(mo)) {
  213.       mo = lj_meta_lookup(L, rc, mm);
  214.       if (tvisnil(mo)) {
  215.         if (str2num(rb, &tempb) == NULL) rc = rb;
  216.         lj_err_optype(L, rc, LJ_ERR_OPARITH);
  217.         return NULL/* unreachable */
  218.       }
  219.     }
  220.     return mmcall(L, lj_cont_ra, mo, rb, rc);
  221.   }
  222. }

  223. /* Helper for CAT. Coercion, iterative concat, __concat metamethod. */
  224. TValue *lj_meta_cat(lua_State *L, TValue *top, int left)
  225. {
  226.   int fromc = 0;
  227.   if (left < 0) { left = -left; fromc = 1; }
  228.   do {
  229.     if (!(tvisstr(top) || tvisnumber(top)) ||
  230.         !(tvisstr(top-1) || tvisnumber(top-1))) {
  231.       cTValue *mo = lj_meta_lookup(L, top-1, MM_concat);
  232.       if (tvisnil(mo)) {
  233.         mo = lj_meta_lookup(L, top, MM_concat);
  234.         if (tvisnil(mo)) {
  235.           if (tvisstr(top-1) || tvisnumber(top-1)) top++;
  236.           lj_err_optype(L, top-1, LJ_ERR_OPCAT);
  237.           return NULL/* unreachable */
  238.         }
  239.       }
  240.       /* One of the top two elements is not a string, call __cat metamethod:
  241.       **
  242.       ** before:    [...][CAT stack .........................]
  243.       **                                 top-1     top         top+1 top+2
  244.       ** pick two:  [...][CAT stack ...] [o1]      [o2]
  245.       ** setup mm:  [...][CAT stack ...] [cont|?]  [mo|tmtype] [o1]  [o2]
  246.       ** in asm:    [...][CAT stack ...] [cont|PC] [mo|delta]  [o1]  [o2]
  247.       **            ^-- func base                              ^-- mm base
  248.       ** after mm:  [...][CAT stack ...] <--push-- [result]
  249.       ** next step: [...][CAT stack .............]
  250.       */
  251.       copyTV(L, top+2*LJ_FR2+2, top);  /* Carefully ordered stack copies! */
  252.       copyTV(L, top+2*LJ_FR2+1, top-1);
  253.       copyTV(L, top+LJ_FR2, mo);
  254.       setcont(top-1, lj_cont_cat);
  255.       if (LJ_FR2) { setnilV(top); setnilV(top+2); top += 2; }
  256.       return top+1/* Trigger metamethod call. */
  257.     } else {
  258.       /* Pick as many strings as possible from the top and concatenate them:
  259.       **
  260.       ** before:    [...][CAT stack ...........................]
  261.       ** pick str:  [...][CAT stack ...] [...... strings ......]
  262.       ** concat:    [...][CAT stack ...] [result]
  263.       ** next step: [...][CAT stack ............]
  264.       */
  265.       TValue *e, *o = top;
  266.       uint64_t tlen = tvisstr(o) ? strV(o)->len : STRFMT_MAXBUF_NUM;
  267.       char *p, *buf;
  268.       do {
  269.         o--; tlen += tvisstr(o) ? strV(o)->len : STRFMT_MAXBUF_NUM;
  270.       } while (--left > 0 && (tvisstr(o-1) || tvisnumber(o-1)));
  271.       if (tlen >= LJ_MAX_STR) lj_err_msg(L, LJ_ERR_STROV);
  272.       p = buf = lj_buf_tmp(L, (MSize)tlen);
  273.       for (e = top, top = o; o <= e; o++) {
  274.         if (tvisstr(o)) {
  275.           GCstr *s = strV(o);
  276.           MSize len = s->len;
  277.           p = lj_buf_wmem(p, strdata(s), len);
  278.         } else if (tvisint(o)) {
  279.           p = lj_strfmt_wint(p, intV(o));
  280.         } else {
  281.           lua_assert(tvisnum(o));
  282.           p = lj_strfmt_wnum(p, o);
  283.         }
  284.       }
  285.       setstrV(L, top, lj_str_new(L, buf, (size_t)(p-buf)));
  286.     }
  287.   } while (left >= 1);
  288.   if (LJ_UNLIKELY(G(L)->gc.total >= G(L)->gc.threshold)) {
  289.     if (!fromc) L->top = curr_topL(L);
  290.     lj_gc_step(L);
  291.   }
  292.   return NULL;
  293. }

  294. /* Helper for LEN. __len metamethod. */
  295. TValue * LJ_FASTCALL lj_meta_len(lua_State *L, cTValue *o)
  296. {
  297.   cTValue *mo = lj_meta_lookup(L, o, MM_len);
  298.   if (tvisnil(mo)) {
  299.     if (LJ_52 && tvistab(o))
  300.       tabref(tabV(o)->metatable)->nomm |= (uint8_t)(1u<<MM_len);
  301.     else
  302.       lj_err_optype(L, o, LJ_ERR_OPLEN);
  303.     return NULL;
  304.   }
  305.   return mmcall(L, lj_cont_ra, mo, o, LJ_52 ? o : niltv(L));
  306. }

  307. /* Helper for equality comparisons. __eq metamethod. */
  308. TValue *lj_meta_equal(lua_State *L, GCobj *o1, GCobj *o2, int ne)
  309. {
  310.   /* Field metatable must be at same offset for GCtab and GCudata! */
  311.   cTValue *mo = lj_meta_fast(L, tabref(o1->gch.metatable), MM_eq);
  312.   if (mo) {
  313.     TValue *top;
  314.     uint32_t it;
  315.     if (tabref(o1->gch.metatable) != tabref(o2->gch.metatable)) {
  316.       cTValue *mo2 = lj_meta_fast(L, tabref(o2->gch.metatable), MM_eq);
  317.       if (mo2 == NULL || !lj_obj_equal(mo, mo2))
  318.         return (TValue *)(intptr_t)ne;
  319.     }
  320.     top = curr_top(L);
  321.     setcont(top++, ne ? lj_cont_condf : lj_cont_condt);
  322.     if (LJ_FR2) setnilV(top++);
  323.     copyTV(L, top++, mo);
  324.     if (LJ_FR2) setnilV(top++);
  325.     it = ~(uint32_t)o1->gch.gct;
  326.     setgcV(L, top, o1, it);
  327.     setgcV(L, top+1, o2, it);
  328.     return top;  /* Trigger metamethod call. */
  329.   }
  330.   return (TValue *)(intptr_t)ne;
  331. }

  332. #if LJ_HASFFI
  333. TValue * LJ_FASTCALL lj_meta_equal_cd(lua_State *L, BCIns ins)
  334. {
  335.   ASMFunction cont = (bc_op(ins) & 1) ? lj_cont_condf : lj_cont_condt;
  336.   int op = (int)bc_op(ins) & ~1;
  337.   TValue tv;
  338.   cTValue *mo, *o2, *o1 = &L->base[bc_a(ins)];
  339.   cTValue *o1mm = o1;
  340.   if (op == BC_ISEQV) {
  341.     o2 = &L->base[bc_d(ins)];
  342.     if (!tviscdata(o1mm)) o1mm = o2;
  343.   } else if (op == BC_ISEQS) {
  344.     setstrV(L, &tv, gco2str(proto_kgc(curr_proto(L), ~(ptrdiff_t)bc_d(ins))));
  345.     o2 = &tv;
  346.   } else if (op == BC_ISEQN) {
  347.     o2 = &mref(curr_proto(L)->k, cTValue)[bc_d(ins)];
  348.   } else {
  349.     lua_assert(op == BC_ISEQP);
  350.     setpriV(&tv, ~bc_d(ins));
  351.     o2 = &tv;
  352.   }
  353.   mo = lj_meta_lookup(L, o1mm, MM_eq);
  354.   if (LJ_LIKELY(!tvisnil(mo)))
  355.     return mmcall(L, cont, mo, o1, o2);
  356.   else
  357.     return (TValue *)(intptr_t)(bc_op(ins) & 1);
  358. }
  359. #endif

  360. /* Helper for ordered comparisons. String compare, __lt/__le metamethods. */
  361. TValue *lj_meta_comp(lua_State *L, cTValue *o1, cTValue *o2, int op)
  362. {
  363.   if (LJ_HASFFI && (tviscdata(o1) || tviscdata(o2))) {
  364.     ASMFunction cont = (op & 1) ? lj_cont_condf : lj_cont_condt;
  365.     MMS mm = (op & 2) ? MM_le : MM_lt;
  366.     cTValue *mo = lj_meta_lookup(L, tviscdata(o1) ? o1 : o2, mm);
  367.     if (LJ_UNLIKELY(tvisnil(mo))) goto err;
  368.     return mmcall(L, cont, mo, o1, o2);
  369.   } else if (LJ_52 || itype(o1) == itype(o2)) {
  370.     /* Never called with two numbers. */
  371.     if (tvisstr(o1) && tvisstr(o2)) {
  372.       int32_t res = lj_str_cmp(strV(o1), strV(o2));
  373.       return (TValue *)(intptr_t)(((op&2) ? res <= 0 : res < 0) ^ (op&1));
  374.     } else {
  375.     trymt:
  376.       while (1) {
  377.         ASMFunction cont = (op & 1) ? lj_cont_condf : lj_cont_condt;
  378.         MMS mm = (op & 2) ? MM_le : MM_lt;
  379.         cTValue *mo = lj_meta_lookup(L, o1, mm);
  380. #if LJ_52
  381.         if (tvisnil(mo) && tvisnil((mo = lj_meta_lookup(L, o2, mm))))
  382. #else
  383.         cTValue *mo2 = lj_meta_lookup(L, o2, mm);
  384.         if (tvisnil(mo) || !lj_obj_equal(mo, mo2))
  385. #endif
  386.         {
  387.           if (op & 2) {  /* MM_le not found: retry with MM_lt. */
  388.             cTValue *ot = o1; o1 = o2; o2 = ot;  /* Swap operands. */
  389.             op ^= 3/* Use LT and flip condition. */
  390.             continue;
  391.           }
  392.           goto err;
  393.         }
  394.         return mmcall(L, cont, mo, o1, o2);
  395.       }
  396.     }
  397.   } else if (tvisbool(o1) && tvisbool(o2)) {
  398.     goto trymt;
  399.   } else {
  400.   err:
  401.     lj_err_comp(L, o1, o2);
  402.     return NULL;
  403.   }
  404. }

  405. /* Helper for ISTYPE and ISNUM. Implicit coercion or error. */
  406. void lj_meta_istype(lua_State *L, BCReg ra, BCReg tp)
  407. {
  408.   L->top = curr_topL(L);
  409.   ra++; tp--;
  410.   lua_assert(LJ_DUALNUM || tp != ~LJ_TNUMX);  /* ISTYPE -> ISNUM broken. */
  411.   if (LJ_DUALNUM && tp == ~LJ_TNUMX) lj_lib_checkint(L, ra);
  412.   else if (tp == ~LJ_TNUMX+1) lj_lib_checknum(L, ra);
  413.   else if (tp == ~LJ_TSTR) lj_lib_checkstr(L, ra);
  414.   else lj_err_argtype(L, ra, lj_obj_itypename[tp]);
  415. }

  416. /* Helper for calls. __call metamethod. */
  417. void lj_meta_call(lua_State *L, TValue *func, TValue *top)
  418. {
  419.   cTValue *mo = lj_meta_lookup(L, func, MM_call);
  420.   TValue *p;
  421.   if (!tvisfunc(mo))
  422.     lj_err_optype_call(L, func);
  423.   for (p = top; p > func+2*LJ_FR2; p--) copyTV(L, p, p-1);
  424.   if (LJ_FR2) copyTV(L, func+2, func);
  425.   copyTV(L, func, mo);
  426. }

  427. /* Helper for FORI. Coercion. */
  428. void LJ_FASTCALL lj_meta_for(lua_State *L, TValue *o)
  429. {
  430.   if (!lj_strscan_numberobj(o)) lj_err_msg(L, LJ_ERR_FORINIT);
  431.   if (!lj_strscan_numberobj(o+1)) lj_err_msg(L, LJ_ERR_FORLIM);
  432.   if (!lj_strscan_numberobj(o+2)) lj_err_msg(L, LJ_ERR_FORSTEP);
  433.   if (LJ_DUALNUM) {
  434.     /* Ensure all slots are integers or all slots are numbers. */
  435.     int32_t k[3];
  436.     int nint = 0;
  437.     ptrdiff_t i;
  438.     for (i = 0; i <= 2; i++) {
  439.       if (tvisint(o+i)) {
  440.         k[i] = intV(o+i); nint++;
  441.       } else {
  442.         k[i] = lj_num2int(numV(o+i)); nint += ((lua_Number)k[i] == numV(o+i));
  443.       }
  444.     }
  445.     if (nint == 3) {  /* Narrow to integers. */
  446.       setintV(o, k[0]);
  447.       setintV(o+1, k[1]);
  448.       setintV(o+2, k[2]);
  449.     } else if (nint != 0) {  /* Widen to numbers. */
  450.       if (tvisint(o)) setnumV(o, (lua_Number)intV(o));
  451.       if (tvisint(o+1)) setnumV(o+1, (lua_Number)intV(o+1));
  452.       if (tvisint(o+2)) setnumV(o+2, (lua_Number)intV(o+2));
  453.     }
  454.   }
  455. }