src/lib_base.c - luajit-2.0-src

Functions defined

Macros defined

Source code

  1. /*
  2. ** Base and coroutine library.
  3. ** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
  4. **
  5. ** Major portions taken verbatim or adapted from the Lua interpreter.
  6. ** Copyright (C) 1994-2011 Lua.org, PUC-Rio. See Copyright Notice in lua.h
  7. */

  8. #include <stdio.h>

  9. #define lib_base_c
  10. #define LUA_LIB

  11. #include "lua.h"
  12. #include "lauxlib.h"
  13. #include "lualib.h"

  14. #include "lj_obj.h"
  15. #include "lj_gc.h"
  16. #include "lj_err.h"
  17. #include "lj_debug.h"
  18. #include "lj_str.h"
  19. #include "lj_tab.h"
  20. #include "lj_meta.h"
  21. #include "lj_state.h"
  22. #if LJ_HASFFI
  23. #include "lj_ctype.h"
  24. #include "lj_cconv.h"
  25. #endif
  26. #include "lj_bc.h"
  27. #include "lj_ff.h"
  28. #include "lj_dispatch.h"
  29. #include "lj_char.h"
  30. #include "lj_strscan.h"
  31. #include "lj_strfmt.h"
  32. #include "lj_lib.h"

  33. /* -- Base library: checks ------------------------------------------------ */

  34. #define LJLIB_MODULE_base

  35. LJLIB_ASM(assert)                LJLIB_REC(.)
  36. {
  37.   GCstr *s;
  38.   lj_lib_checkany(L, 1);
  39.   s = lj_lib_optstr(L, 2);
  40.   if (s)
  41.     lj_err_callermsg(L, strdata(s));
  42.   else
  43.     lj_err_caller(L, LJ_ERR_ASSERT);
  44.   return FFH_UNREACHABLE;
  45. }

  46. /* ORDER LJ_T */
  47. LJLIB_PUSH("nil")
  48. LJLIB_PUSH("boolean")
  49. LJLIB_PUSH(top-1/* boolean */
  50. LJLIB_PUSH("userdata")
  51. LJLIB_PUSH("string")
  52. LJLIB_PUSH("upval")
  53. LJLIB_PUSH("thread")
  54. LJLIB_PUSH("proto")
  55. LJLIB_PUSH("function")
  56. LJLIB_PUSH("trace")
  57. LJLIB_PUSH("cdata")
  58. LJLIB_PUSH("table")
  59. LJLIB_PUSH(top-9/* userdata */
  60. LJLIB_PUSH("number")
  61. LJLIB_ASM_(type)                LJLIB_REC(.)
  62. /* Recycle the lj_lib_checkany(L, 1) from assert. */

  63. /* -- Base library: iterators --------------------------------------------- */

  64. /* This solves a circular dependency problem -- change FF_next_N as needed. */
  65. LJ_STATIC_ASSERT((int)FF_next == FF_next_N);

  66. LJLIB_ASM(next)
  67. {
  68.   lj_lib_checktab(L, 1);
  69.   return FFH_UNREACHABLE;
  70. }

  71. #if LJ_52 || LJ_HASFFI
  72. static int ffh_pairs(lua_State *L, MMS mm)
  73. {
  74.   TValue *o = lj_lib_checkany(L, 1);
  75.   cTValue *mo = lj_meta_lookup(L, o, mm);
  76.   if ((LJ_52 || tviscdata(o)) && !tvisnil(mo)) {
  77.     L->top = o+1/* Only keep one argument. */
  78.     copyTV(L, L->base-1-LJ_FR2, mo);  /* Replace callable. */
  79.     return FFH_TAILCALL;
  80.   } else {
  81.     if (!tvistab(o)) lj_err_argt(L, 1, LUA_TTABLE);
  82.     if (LJ_FR2) { copyTV(L, o-1, o); o--; }
  83.     setfuncV(L, o-1, funcV(lj_lib_upvalue(L, 1)));
  84.     if (mm == MM_pairs) setnilV(o+1); else setintV(o+1, 0);
  85.     return FFH_RES(3);
  86.   }
  87. }
  88. #else
  89. #define ffh_pairs(L, mm)        (lj_lib_checktab(L, 1), FFH_UNREACHABLE)
  90. #endif

  91. LJLIB_PUSH(lastcl)
  92. LJLIB_ASM(pairs)                LJLIB_REC(xpairs 0)
  93. {
  94.   return ffh_pairs(L, MM_pairs);
  95. }

  96. LJLIB_NOREGUV LJLIB_ASM(ipairs_aux)        LJLIB_REC(.)
  97. {
  98.   lj_lib_checktab(L, 1);
  99.   lj_lib_checkint(L, 2);
  100.   return FFH_UNREACHABLE;
  101. }

  102. LJLIB_PUSH(lastcl)
  103. LJLIB_ASM(ipairs)                LJLIB_REC(xpairs 1)
  104. {
  105.   return ffh_pairs(L, MM_ipairs);
  106. }

  107. /* -- Base library: getters and setters ----------------------------------- */

  108. LJLIB_ASM_(getmetatable)        LJLIB_REC(.)
  109. /* Recycle the lj_lib_checkany(L, 1) from assert. */

  110. LJLIB_ASM(setmetatable)                LJLIB_REC(.)
  111. {
  112.   GCtab *t = lj_lib_checktab(L, 1);
  113.   GCtab *mt = lj_lib_checktabornil(L, 2);
  114.   if (!tvisnil(lj_meta_lookup(L, L->base, MM_metatable)))
  115.     lj_err_caller(L, LJ_ERR_PROTMT);
  116.   setgcref(t->metatable, obj2gco(mt));
  117.   if (mt) { lj_gc_objbarriert(L, t, mt); }
  118.   settabV(L, L->base-1-LJ_FR2, t);
  119.   return FFH_RES(1);
  120. }

  121. LJLIB_CF(getfenv)                LJLIB_REC(.)
  122. {
  123.   GCfunc *fn;
  124.   cTValue *o = L->base;
  125.   if (!(o < L->top && tvisfunc(o))) {
  126.     int level = lj_lib_optint(L, 1, 1);
  127.     o = lj_debug_frame(L, level, &level);
  128.     if (o == NULL)
  129.       lj_err_arg(L, 1, LJ_ERR_INVLVL);
  130.     if (LJ_FR2) o--;
  131.   }
  132.   fn = &gcval(o)->fn;
  133.   settabV(L, L->top++, isluafunc(fn) ? tabref(fn->l.env) : tabref(L->env));
  134.   return 1;
  135. }

  136. LJLIB_CF(setfenv)
  137. {
  138.   GCfunc *fn;
  139.   GCtab *t = lj_lib_checktab(L, 2);
  140.   cTValue *o = L->base;
  141.   if (!(o < L->top && tvisfunc(o))) {
  142.     int level = lj_lib_checkint(L, 1);
  143.     if (level == 0) {
  144.       /* NOBARRIER: A thread (i.e. L) is never black. */
  145.       setgcref(L->env, obj2gco(t));
  146.       return 0;
  147.     }
  148.     o = lj_debug_frame(L, level, &level);
  149.     if (o == NULL)
  150.       lj_err_arg(L, 1, LJ_ERR_INVLVL);
  151.     if (LJ_FR2) o--;
  152.   }
  153.   fn = &gcval(o)->fn;
  154.   if (!isluafunc(fn))
  155.     lj_err_caller(L, LJ_ERR_SETFENV);
  156.   setgcref(fn->l.env, obj2gco(t));
  157.   lj_gc_objbarrier(L, obj2gco(fn), t);
  158.   setfuncV(L, L->top++, fn);
  159.   return 1;
  160. }

  161. LJLIB_ASM(rawget)                LJLIB_REC(.)
  162. {
  163.   lj_lib_checktab(L, 1);
  164.   lj_lib_checkany(L, 2);
  165.   return FFH_UNREACHABLE;
  166. }

  167. LJLIB_CF(rawset)                LJLIB_REC(.)
  168. {
  169.   lj_lib_checktab(L, 1);
  170.   lj_lib_checkany(L, 2);
  171.   L->top = 1+lj_lib_checkany(L, 3);
  172.   lua_rawset(L, 1);
  173.   return 1;
  174. }

  175. LJLIB_CF(rawequal)                LJLIB_REC(.)
  176. {
  177.   cTValue *o1 = lj_lib_checkany(L, 1);
  178.   cTValue *o2 = lj_lib_checkany(L, 2);
  179.   setboolV(L->top-1, lj_obj_equal(o1, o2));
  180.   return 1;
  181. }

  182. #if LJ_52
  183. LJLIB_CF(rawlen)                LJLIB_REC(.)
  184. {
  185.   cTValue *o = L->base;
  186.   int32_t len;
  187.   if (L->top > o && tvisstr(o))
  188.     len = (int32_t)strV(o)->len;
  189.   else
  190.     len = (int32_t)lj_tab_len(lj_lib_checktab(L, 1));
  191.   setintV(L->top-1, len);
  192.   return 1;
  193. }
  194. #endif

  195. LJLIB_CF(unpack)
  196. {
  197.   GCtab *t = lj_lib_checktab(L, 1);
  198.   int32_t n, i = lj_lib_optint(L, 2, 1);
  199.   int32_t e = (L->base+3-1 < L->top && !tvisnil(L->base+3-1)) ?
  200.               lj_lib_checkint(L, 3) : (int32_t)lj_tab_len(t);
  201.   if (i > e) return 0;
  202.   n = e - i + 1;
  203.   if (n <= 0 || !lua_checkstack(L, n))
  204.     lj_err_caller(L, LJ_ERR_UNPACK);
  205.   do {
  206.     cTValue *tv = lj_tab_getint(t, i);
  207.     if (tv) {
  208.       copyTV(L, L->top++, tv);
  209.     } else {
  210.       setnilV(L->top++);
  211.     }
  212.   } while (i++ < e);
  213.   return n;
  214. }

  215. LJLIB_CF(select)                LJLIB_REC(.)
  216. {
  217.   int32_t n = (int32_t)(L->top - L->base);
  218.   if (n >= 1 && tvisstr(L->base) && *strVdata(L->base) == '#') {
  219.     setintV(L->top-1, n-1);
  220.     return 1;
  221.   } else {
  222.     int32_t i = lj_lib_checkint(L, 1);
  223.     if (i < 0) i = n + i; else if (i > n) i = n;
  224.     if (i < 1)
  225.       lj_err_arg(L, 1, LJ_ERR_IDXRNG);
  226.     return n - i;
  227.   }
  228. }

  229. /* -- Base library: conversions ------------------------------------------- */

  230. LJLIB_ASM(tonumber)                LJLIB_REC(.)
  231. {
  232.   int32_t base = lj_lib_optint(L, 2, 10);
  233.   if (base == 10) {
  234.     TValue *o = lj_lib_checkany(L, 1);
  235.     if (lj_strscan_numberobj(o)) {
  236.       copyTV(L, L->base-1-LJ_FR2, o);
  237.       return FFH_RES(1);
  238.     }
  239. #if LJ_HASFFI
  240.     if (tviscdata(o)) {
  241.       CTState *cts = ctype_cts(L);
  242.       CType *ct = lj_ctype_rawref(cts, cdataV(o)->ctypeid);
  243.       if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
  244.       if (ctype_isnum(ct->info) || ctype_iscomplex(ct->info)) {
  245.         if (LJ_DUALNUM && ctype_isinteger_or_bool(ct->info) &&
  246.             ct->size <= 4 && !(ct->size == 4 && (ct->info & CTF_UNSIGNED))) {
  247.           int32_t i;
  248.           lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o, 0);
  249.           setintV(L->base-1-LJ_FR2, i);
  250.           return FFH_RES(1);
  251.         }
  252.         lj_cconv_ct_tv(cts, ctype_get(cts, CTID_DOUBLE),
  253.                        (uint8_t *)&(L->base-1-LJ_FR2)->n, o, 0);
  254.         return FFH_RES(1);
  255.       }
  256.     }
  257. #endif
  258.   } else {
  259.     const char *p = strdata(lj_lib_checkstr(L, 1));
  260.     char *ep;
  261.     unsigned long ul;
  262.     if (base < 2 || base > 36)
  263.       lj_err_arg(L, 2, LJ_ERR_BASERNG);
  264.     ul = strtoul(p, &ep, base);
  265.     if (p != ep) {
  266.       while (lj_char_isspace((unsigned char)(*ep))) ep++;
  267.       if (*ep == '\0') {
  268.         if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u))
  269.           setintV(L->base-1-LJ_FR2, (int32_t)ul);
  270.         else
  271.           setnumV(L->base-1-LJ_FR2, (lua_Number)ul);
  272.         return FFH_RES(1);
  273.       }
  274.     }
  275.   }
  276.   setnilV(L->base-1-LJ_FR2);
  277.   return FFH_RES(1);
  278. }

  279. LJLIB_ASM(tostring)                LJLIB_REC(.)
  280. {
  281.   TValue *o = lj_lib_checkany(L, 1);
  282.   cTValue *mo;
  283.   L->top = o+1/* Only keep one argument. */
  284.   if (!tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) {
  285.     copyTV(L, L->base-1-LJ_FR2, mo);  /* Replace callable. */
  286.     return FFH_TAILCALL;
  287.   }
  288.   lj_gc_check(L);
  289.   setstrV(L, L->base-1-LJ_FR2, lj_strfmt_obj(L, L->base));
  290.   return FFH_RES(1);
  291. }

  292. /* -- Base library: throw and catch errors -------------------------------- */

  293. LJLIB_CF(error)
  294. {
  295.   int32_t level = lj_lib_optint(L, 2, 1);
  296.   lua_settop(L, 1);
  297.   if (lua_isstring(L, 1) && level > 0) {
  298.     luaL_where(L, level);
  299.     lua_pushvalue(L, 1);
  300.     lua_concat(L, 2);
  301.   }
  302.   return lua_error(L);
  303. }

  304. LJLIB_ASM(pcall)                LJLIB_REC(.)
  305. {
  306.   lj_lib_checkany(L, 1);
  307.   lj_lib_checkfunc(L, 2);  /* For xpcall only. */
  308.   return FFH_UNREACHABLE;
  309. }
  310. LJLIB_ASM_(xpcall)                LJLIB_REC(.)

  311. /* -- Base library: load Lua code ----------------------------------------- */

  312. static int load_aux(lua_State *L, int status, int envarg)
  313. {
  314.   if (status == 0) {
  315.     if (tvistab(L->base+envarg-1)) {
  316.       GCfunc *fn = funcV(L->top-1);
  317.       GCtab *t = tabV(L->base+envarg-1);
  318.       setgcref(fn->c.env, obj2gco(t));
  319.       lj_gc_objbarrier(L, fn, t);
  320.     }
  321.     return 1;
  322.   } else {
  323.     setnilV(L->top-2);
  324.     return 2;
  325.   }
  326. }

  327. LJLIB_CF(loadfile)
  328. {
  329.   GCstr *fname = lj_lib_optstr(L, 1);
  330.   GCstr *mode = lj_lib_optstr(L, 2);
  331.   int status;
  332.   lua_settop(L, 3);  /* Ensure env arg exists. */
  333.   status = luaL_loadfilex(L, fname ? strdata(fname) : NULL,
  334.                           mode ? strdata(mode) : NULL);
  335.   return load_aux(L, status, 3);
  336. }

  337. static const char *reader_func(lua_State *L, void *ud, size_t *size)
  338. {
  339.   UNUSED(ud);
  340.   luaL_checkstack(L, 2, "too many nested functions");
  341.   copyTV(L, L->top++, L->base);
  342.   lua_call(L, 0, 1);  /* Call user-supplied function. */
  343.   L->top--;
  344.   if (tvisnil(L->top)) {
  345.     *size = 0;
  346.     return NULL;
  347.   } else if (tvisstr(L->top) || tvisnumber(L->top)) {
  348.     copyTV(L, L->base+4, L->top);  /* Anchor string in reserved stack slot. */
  349.     return lua_tolstring(L, 5, size);
  350.   } else {
  351.     lj_err_caller(L, LJ_ERR_RDRSTR);
  352.     return NULL;
  353.   }
  354. }

  355. LJLIB_CF(load)
  356. {
  357.   GCstr *name = lj_lib_optstr(L, 2);
  358.   GCstr *mode = lj_lib_optstr(L, 3);
  359.   int status;
  360.   if (L->base < L->top && (tvisstr(L->base) || tvisnumber(L->base))) {
  361.     GCstr *s = lj_lib_checkstr(L, 1);
  362.     lua_settop(L, 4);  /* Ensure env arg exists. */
  363.     status = luaL_loadbufferx(L, strdata(s), s->len, strdata(name ? name : s),
  364.                               mode ? strdata(mode) : NULL);
  365.   } else {
  366.     lj_lib_checkfunc(L, 1);
  367.     lua_settop(L, 5);  /* Reserve a slot for the string from the reader. */
  368.     status = lua_loadx(L, reader_func, NULL, name ? strdata(name) : "=(load)",
  369.                        mode ? strdata(mode) : NULL);
  370.   }
  371.   return load_aux(L, status, 4);
  372. }

  373. LJLIB_CF(loadstring)
  374. {
  375.   return lj_cf_load(L);
  376. }

  377. LJLIB_CF(dofile)
  378. {
  379.   GCstr *fname = lj_lib_optstr(L, 1);
  380.   setnilV(L->top);
  381.   L->top = L->base+1;
  382.   if (luaL_loadfile(L, fname ? strdata(fname) : NULL) != 0)
  383.     lua_error(L);
  384.   lua_call(L, 0, LUA_MULTRET);
  385.   return (int)(L->top - L->base) - 1;
  386. }

  387. /* -- Base library: GC control -------------------------------------------- */

  388. LJLIB_CF(gcinfo)
  389. {
  390.   setintV(L->top++, (G(L)->gc.total >> 10));
  391.   return 1;
  392. }

  393. LJLIB_CF(collectgarbage)
  394. {
  395.   int opt = lj_lib_checkopt(L, 1, LUA_GCCOLLECT/* ORDER LUA_GC* */
  396.     "\4stop\7restart\7collect\5count\1\377\4step\10setpause\12setstepmul");
  397.   int32_t data = lj_lib_optint(L, 2, 0);
  398.   if (opt == LUA_GCCOUNT) {
  399.     setnumV(L->top, (lua_Number)G(L)->gc.total/1024.0);
  400.   } else {
  401.     int res = lua_gc(L, opt, data);
  402.     if (opt == LUA_GCSTEP)
  403.       setboolV(L->top, res);
  404.     else
  405.       setintV(L->top, res);
  406.   }
  407.   L->top++;
  408.   return 1;
  409. }

  410. /* -- Base library: miscellaneous functions ------------------------------- */

  411. LJLIB_PUSH(top-2/* Upvalue holds weak table. */
  412. LJLIB_CF(newproxy)
  413. {
  414.   lua_settop(L, 1);
  415.   lua_newuserdata(L, 0);
  416.   if (lua_toboolean(L, 1) == 0) {  /* newproxy(): without metatable. */
  417.     return 1;
  418.   } else if (lua_isboolean(L, 1)) {  /* newproxy(true): with metatable. */
  419.     lua_newtable(L);
  420.     lua_pushvalue(L, -1);
  421.     lua_pushboolean(L, 1);
  422.     lua_rawset(L, lua_upvalueindex(1));  /* Remember mt in weak table. */
  423.   } else/* newproxy(proxy): inherit metatable. */
  424.     int validproxy = 0;
  425.     if (lua_getmetatable(L, 1)) {
  426.       lua_rawget(L, lua_upvalueindex(1));
  427.       validproxy = lua_toboolean(L, -1);
  428.       lua_pop(L, 1);
  429.     }
  430.     if (!validproxy)
  431.       lj_err_arg(L, 1, LJ_ERR_NOPROXY);
  432.     lua_getmetatable(L, 1);
  433.   }
  434.   lua_setmetatable(L, 2);
  435.   return 1;
  436. }

  437. LJLIB_PUSH("tostring")
  438. LJLIB_CF(print)
  439. {
  440.   ptrdiff_t i, nargs = L->top - L->base;
  441.   cTValue *tv = lj_tab_getstr(tabref(L->env), strV(lj_lib_upvalue(L, 1)));
  442.   int shortcut;
  443.   if (tv && !tvisnil(tv)) {
  444.     copyTV(L, L->top++, tv);
  445.   } else {
  446.     setstrV(L, L->top++, strV(lj_lib_upvalue(L, 1)));
  447.     lua_gettable(L, LUA_GLOBALSINDEX);
  448.     tv = L->top-1;
  449.   }
  450.   shortcut = (tvisfunc(tv) && funcV(tv)->c.ffid == FF_tostring);
  451.   for (i = 0; i < nargs; i++) {
  452.     cTValue *o = &L->base[i];
  453.     char buf[STRFMT_MAXBUF_NUM];
  454.     const char *str;
  455.     size_t size;
  456.     MSize len;
  457.     if (shortcut && (str = lj_strfmt_wstrnum(buf, o, &len)) != NULL) {
  458.       size = len;
  459.     } else {
  460.       copyTV(L, L->top+1, o);
  461.       copyTV(L, L->top, L->top-1);
  462.       L->top += 2;
  463.       lua_call(L, 1, 1);
  464.       str = lua_tolstring(L, -1, &size);
  465.       if (!str)
  466.         lj_err_caller(L, LJ_ERR_PRTOSTR);
  467.       L->top--;
  468.     }
  469.     if (i)
  470.       putchar('\t');
  471.     fwrite(str, 1, size, stdout);
  472.   }
  473.   putchar('\n');
  474.   return 0;
  475. }

  476. LJLIB_PUSH(top-3)
  477. LJLIB_SET(_VERSION)

  478. #include "lj_libdef.h"

  479. /* -- Coroutine library --------------------------------------------------- */

  480. #define LJLIB_MODULE_coroutine

  481. LJLIB_CF(coroutine_status)
  482. {
  483.   const char *s;
  484.   lua_State *co;
  485.   if (!(L->top > L->base && tvisthread(L->base)))
  486.     lj_err_arg(L, 1, LJ_ERR_NOCORO);
  487.   co = threadV(L->base);
  488.   if (co == L) s = "running";
  489.   else if (co->status == LUA_YIELD) s = "suspended";
  490.   else if (co->status != 0) s = "dead";
  491.   else if (co->base > tvref(co->stack)+1+LJ_FR2) s = "normal";
  492.   else if (co->top == co->base) s = "dead";
  493.   else s = "suspended";
  494.   lua_pushstring(L, s);
  495.   return 1;
  496. }

  497. LJLIB_CF(coroutine_running)
  498. {
  499. #if LJ_52
  500.   int ismain = lua_pushthread(L);
  501.   setboolV(L->top++, ismain);
  502.   return 2;
  503. #else
  504.   if (lua_pushthread(L))
  505.     setnilV(L->top++);
  506.   return 1;
  507. #endif
  508. }

  509. LJLIB_CF(coroutine_create)
  510. {
  511.   lua_State *L1;
  512.   if (!(L->base < L->top && tvisfunc(L->base)))
  513.     lj_err_argt(L, 1, LUA_TFUNCTION);
  514.   L1 = lua_newthread(L);
  515.   setfuncV(L, L1->top++, funcV(L->base));
  516.   return 1;
  517. }

  518. LJLIB_ASM(coroutine_yield)
  519. {
  520.   lj_err_caller(L, LJ_ERR_CYIELD);
  521.   return FFH_UNREACHABLE;
  522. }

  523. static int ffh_resume(lua_State *L, lua_State *co, int wrap)
  524. {
  525.   if (co->cframe != NULL || co->status > LUA_YIELD ||
  526.       (co->status == 0 && co->top == co->base)) {
  527.     ErrMsg em = co->cframe ? LJ_ERR_CORUN : LJ_ERR_CODEAD;
  528.     if (wrap) lj_err_caller(L, em);
  529.     setboolV(L->base-1-LJ_FR2, 0);
  530.     setstrV(L, L->base-LJ_FR2, lj_err_str(L, em));
  531.     return FFH_RES(2);
  532.   }
  533.   lj_state_growstack(co, (MSize)(L->top - L->base));
  534.   return FFH_RETRY;
  535. }

  536. LJLIB_ASM(coroutine_resume)
  537. {
  538.   if (!(L->top > L->base && tvisthread(L->base)))
  539.     lj_err_arg(L, 1, LJ_ERR_NOCORO);
  540.   return ffh_resume(L, threadV(L->base), 0);
  541. }

  542. LJLIB_NOREG LJLIB_ASM(coroutine_wrap_aux)
  543. {
  544.   return ffh_resume(L, threadV(lj_lib_upvalue(L, 1)), 1);
  545. }

  546. /* Inline declarations. */
  547. LJ_ASMF void lj_ff_coroutine_wrap_aux(void);
  548. #if !(LJ_TARGET_MIPS && defined(ljamalg_c))
  549. LJ_FUNCA_NORET void LJ_FASTCALL lj_ffh_coroutine_wrap_err(lua_State *L,
  550.                                                           lua_State *co);
  551. #endif

  552. /* Error handler, called from assembler VM. */
  553. void LJ_FASTCALL lj_ffh_coroutine_wrap_err(lua_State *L, lua_State *co)
  554. {
  555.   co->top--; copyTV(L, L->top, co->top); L->top++;
  556.   if (tvisstr(L->top-1))
  557.     lj_err_callermsg(L, strVdata(L->top-1));
  558.   else
  559.     lj_err_run(L);
  560. }

  561. /* Forward declaration. */
  562. static void setpc_wrap_aux(lua_State *L, GCfunc *fn);

  563. LJLIB_CF(coroutine_wrap)
  564. {
  565.   GCfunc *fn;
  566.   lj_cf_coroutine_create(L);
  567.   fn = lj_lib_pushcc(L, lj_ffh_coroutine_wrap_aux, FF_coroutine_wrap_aux, 1);
  568.   setpc_wrap_aux(L, fn);
  569.   return 1;
  570. }

  571. #include "lj_libdef.h"

  572. /* Fix the PC of wrap_aux. Really ugly workaround. */
  573. static void setpc_wrap_aux(lua_State *L, GCfunc *fn)
  574. {
  575.   setmref(fn->c.pc, &L2GG(L)->bcff[lj_lib_init_coroutine[1]+2]);
  576. }

  577. /* ------------------------------------------------------------------------ */

  578. static void newproxy_weaktable(lua_State *L)
  579. {
  580.   /* NOBARRIER: The table is new (marked white). */
  581.   GCtab *t = lj_tab_new(L, 0, 1);
  582.   settabV(L, L->top++, t);
  583.   setgcref(t->metatable, obj2gco(t));
  584.   setstrV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "__mode")),
  585.             lj_str_newlit(L, "kv"));
  586.   t->nomm = (uint8_t)(~(1u<<MM_mode));
  587. }

  588. LUALIB_API int luaopen_base(lua_State *L)
  589. {
  590.   /* NOBARRIER: Table and value are the same. */
  591.   GCtab *env = tabref(L->env);
  592.   settabV(L, lj_tab_setstr(L, env, lj_str_newlit(L, "_G")), env);
  593.   lua_pushliteral(L, LUA_VERSION);  /* top-3. */
  594.   newproxy_weaktable(L);  /* top-2. */
  595.   LJ_LIB_REG(L, "_G", base);
  596.   LJ_LIB_REG(L, LUA_COLIBNAME, coroutine);
  597.   return 2;
  598. }