root/lj_lib.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. lib_create_table
  2. lib_read_lfunc
  3. lj_lib_register
  4. lj_lib_pushcc
  5. lj_lib_prereg
  6. lj_lib_postreg
  7. lj_lib_checkany
  8. lj_lib_checkstr
  9. lj_lib_optstr
  10. lj_lib_checknumber
  11. lj_lib_checknum
  12. lj_lib_checkint
  13. lj_lib_optint
  14. lj_lib_checkfunc
  15. lj_lib_checktab
  16. lj_lib_checktabornil
  17. lj_lib_checkopt

   1 /*
   2 ** Library function support.
   3 ** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
   4 */
   5 
   6 #define lj_lib_c
   7 #define LUA_CORE
   8 
   9 #include "lauxlib.h"
  10 
  11 #include "lj_obj.h"
  12 #include "lj_gc.h"
  13 #include "lj_err.h"
  14 #include "lj_str.h"
  15 #include "lj_tab.h"
  16 #include "lj_func.h"
  17 #include "lj_bc.h"
  18 #include "lj_dispatch.h"
  19 #include "lj_vm.h"
  20 #include "lj_strscan.h"
  21 #include "lj_strfmt.h"
  22 #include "lj_lex.h"
  23 #include "lj_bcdump.h"
  24 #include "lj_lib.h"
  25 
  26 /* -- Library initialization ---------------------------------------------- */
  27 
  28 static GCtab *lib_create_table(lua_State *L, const char *libname, int hsize)
  29 {
  30   if (libname) {
  31     luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
  32     lua_getfield(L, -1, libname);
  33     if (!tvistab(L->top-1)) {
  34       L->top--;
  35       if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, hsize) != NULL)
  36         lj_err_callerv(L, LJ_ERR_BADMODN, libname);
  37       settabV(L, L->top, tabV(L->top-1));
  38       L->top++;
  39       lua_setfield(L, -3, libname);  /* _LOADED[libname] = new table */
  40     }
  41     L->top--;
  42     settabV(L, L->top-1, tabV(L->top));
  43   } else {
  44     lua_createtable(L, 0, hsize);
  45   }
  46   return tabV(L->top-1);
  47 }
  48 
  49 static const uint8_t *lib_read_lfunc(lua_State *L, const uint8_t *p, GCtab *tab)
  50 {
  51   int len = *p++;
  52   GCstr *name = lj_str_new(L, (const char *)p, len);
  53   LexState ls;
  54   GCproto *pt;
  55   GCfunc *fn;
  56   memset(&ls, 0, sizeof(ls));
  57   ls.L = L;
  58   ls.p = (const char *)(p+len);
  59   ls.pe = (const char *)~(uintptr_t)0;
  60   ls.c = -1;
  61   ls.level = (BCDUMP_F_STRIP|(LJ_BE*BCDUMP_F_BE));
  62   ls.chunkname = name;
  63   pt = lj_bcread_proto(&ls);
  64   pt->firstline = ~(BCLine)0;
  65   fn = lj_func_newL_empty(L, pt, tabref(L->env));
  66   /* NOBARRIER: See below for common barrier. */
  67   setfuncV(L, lj_tab_setstr(L, tab, name), fn);
  68   return (const uint8_t *)ls.p;
  69 }
  70 
  71 void lj_lib_register(lua_State *L, const char *libname,
  72                      const uint8_t *p, const lua_CFunction *cf)
  73 {
  74   GCtab *env = tabref(L->env);
  75   GCfunc *ofn = NULL;
  76   int ffid = *p++;
  77   BCIns *bcff = &L2GG(L)->bcff[*p++];
  78   GCtab *tab = lib_create_table(L, libname, *p++);
  79   ptrdiff_t tpos = L->top - L->base;
  80 
  81   /* Avoid barriers further down. */
  82   lj_gc_anybarriert(L, tab);
  83   tab->nomm = 0;
  84 
  85   for (;;) {
  86     uint32_t tag = *p++;
  87     MSize len = tag & LIBINIT_LENMASK;
  88     tag &= LIBINIT_TAGMASK;
  89     if (tag != LIBINIT_STRING) {
  90       const char *name;
  91       MSize nuv = (MSize)(L->top - L->base - tpos);
  92       GCfunc *fn = lj_func_newC(L, nuv, env);
  93       if (nuv) {
  94         L->top = L->base + tpos;
  95         memcpy(fn->c.upvalue, L->top, sizeof(TValue)*nuv);
  96       }
  97       fn->c.ffid = (uint8_t)(ffid++);
  98       name = (const char *)p;
  99       p += len;
 100       if (tag == LIBINIT_CF)
 101         setmref(fn->c.pc, &G(L)->bc_cfunc_int);
 102       else
 103         setmref(fn->c.pc, bcff++);
 104       if (tag == LIBINIT_ASM_)
 105         fn->c.f = ofn->c.f;  /* Copy handler from previous function. */
 106       else
 107         fn->c.f = *cf++;  /* Get cf or handler from C function table. */
 108       if (len) {
 109         /* NOBARRIER: See above for common barrier. */
 110         setfuncV(L, lj_tab_setstr(L, tab, lj_str_new(L, name, len)), fn);
 111       }
 112       ofn = fn;
 113     } else {
 114       switch (tag | len) {
 115       case LIBINIT_LUA:
 116         p = lib_read_lfunc(L, p, tab);
 117         break;
 118       case LIBINIT_SET:
 119         L->top -= 2;
 120         if (tvisstr(L->top+1) && strV(L->top+1)->len == 0)
 121           env = tabV(L->top);
 122         else  /* NOBARRIER: See above for common barrier. */
 123           copyTV(L, lj_tab_set(L, tab, L->top+1), L->top);
 124         break;
 125       case LIBINIT_NUMBER:
 126         memcpy(&L->top->n, p, sizeof(double));
 127         L->top++;
 128         p += sizeof(double);
 129         break;
 130       case LIBINIT_COPY:
 131         copyTV(L, L->top, L->top - *p++);
 132         L->top++;
 133         break;
 134       case LIBINIT_LASTCL:
 135         setfuncV(L, L->top++, ofn);
 136         break;
 137       case LIBINIT_FFID:
 138         ffid++;
 139         break;
 140       case LIBINIT_END:
 141         return;
 142       default:
 143         setstrV(L, L->top++, lj_str_new(L, (const char *)p, len));
 144         p += len;
 145         break;
 146       }
 147     }
 148   }
 149 }
 150 
 151 /* Push internal function on the stack. */
 152 GCfunc *lj_lib_pushcc(lua_State *L, lua_CFunction f, int id, int n)
 153 {
 154   GCfunc *fn;
 155   lua_pushcclosure(L, f, n);
 156   fn = funcV(L->top-1);
 157   fn->c.ffid = (uint8_t)id;
 158   setmref(fn->c.pc, &G(L)->bc_cfunc_int);
 159   return fn;
 160 }
 161 
 162 void lj_lib_prereg(lua_State *L, const char *name, lua_CFunction f, GCtab *env)
 163 {
 164   luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD", 4);
 165   lua_pushcfunction(L, f);
 166   /* NOBARRIER: The function is new (marked white). */
 167   setgcref(funcV(L->top-1)->c.env, obj2gco(env));
 168   lua_setfield(L, -2, name);
 169   L->top--;
 170 }
 171 
 172 int lj_lib_postreg(lua_State *L, lua_CFunction cf, int id, const char *name)
 173 {
 174   GCfunc *fn = lj_lib_pushcf(L, cf, id);
 175   GCtab *t = tabref(curr_func(L)->c.env);  /* Reference to parent table. */
 176   setfuncV(L, lj_tab_setstr(L, t, lj_str_newz(L, name)), fn);
 177   lj_gc_anybarriert(L, t);
 178   setfuncV(L, L->top++, fn);
 179   return 1;
 180 }
 181 
 182 /* -- Type checks --------------------------------------------------------- */
 183 
 184 TValue *lj_lib_checkany(lua_State *L, int narg)
 185 {
 186   TValue *o = L->base + narg-1;
 187   if (o >= L->top)
 188     lj_err_arg(L, narg, LJ_ERR_NOVAL);
 189   return o;
 190 }
 191 
 192 GCstr *lj_lib_checkstr(lua_State *L, int narg)
 193 {
 194   TValue *o = L->base + narg-1;
 195   if (o < L->top) {
 196     if (LJ_LIKELY(tvisstr(o))) {
 197       return strV(o);
 198     } else if (tvisnumber(o)) {
 199       GCstr *s = lj_strfmt_number(L, o);
 200       setstrV(L, o, s);
 201       return s;
 202     }
 203   }
 204   lj_err_argt(L, narg, LUA_TSTRING);
 205   return NULL;  /* unreachable */
 206 }
 207 
 208 GCstr *lj_lib_optstr(lua_State *L, int narg)
 209 {
 210   TValue *o = L->base + narg-1;
 211   return (o < L->top && !tvisnil(o)) ? lj_lib_checkstr(L, narg) : NULL;
 212 }
 213 
 214 #if LJ_DUALNUM
 215 void lj_lib_checknumber(lua_State *L, int narg)
 216 {
 217   TValue *o = L->base + narg-1;
 218   if (!(o < L->top && lj_strscan_numberobj(o)))
 219     lj_err_argt(L, narg, LUA_TNUMBER);
 220 }
 221 #endif
 222 
 223 lua_Number lj_lib_checknum(lua_State *L, int narg)
 224 {
 225   TValue *o = L->base + narg-1;
 226   if (!(o < L->top &&
 227         (tvisnumber(o) || (tvisstr(o) && lj_strscan_num(strV(o), o)))))
 228     lj_err_argt(L, narg, LUA_TNUMBER);
 229   if (LJ_UNLIKELY(tvisint(o))) {
 230     lua_Number n = (lua_Number)intV(o);
 231     setnumV(o, n);
 232     return n;
 233   } else {
 234     return numV(o);
 235   }
 236 }
 237 
 238 int32_t lj_lib_checkint(lua_State *L, int narg)
 239 {
 240   TValue *o = L->base + narg-1;
 241   if (!(o < L->top && lj_strscan_numberobj(o)))
 242     lj_err_argt(L, narg, LUA_TNUMBER);
 243   if (LJ_LIKELY(tvisint(o))) {
 244     return intV(o);
 245   } else {
 246     int32_t i = lj_num2int(numV(o));
 247     if (LJ_DUALNUM) setintV(o, i);
 248     return i;
 249   }
 250 }
 251 
 252 int32_t lj_lib_optint(lua_State *L, int narg, int32_t def)
 253 {
 254   TValue *o = L->base + narg-1;
 255   return (o < L->top && !tvisnil(o)) ? lj_lib_checkint(L, narg) : def;
 256 }
 257 
 258 GCfunc *lj_lib_checkfunc(lua_State *L, int narg)
 259 {
 260   TValue *o = L->base + narg-1;
 261   if (!(o < L->top && tvisfunc(o)))
 262     lj_err_argt(L, narg, LUA_TFUNCTION);
 263   return funcV(o);
 264 }
 265 
 266 GCtab *lj_lib_checktab(lua_State *L, int narg)
 267 {
 268   TValue *o = L->base + narg-1;
 269   if (!(o < L->top && tvistab(o)))
 270     lj_err_argt(L, narg, LUA_TTABLE);
 271   return tabV(o);
 272 }
 273 
 274 GCtab *lj_lib_checktabornil(lua_State *L, int narg)
 275 {
 276   TValue *o = L->base + narg-1;
 277   if (o < L->top) {
 278     if (tvistab(o))
 279       return tabV(o);
 280     else if (tvisnil(o))
 281       return NULL;
 282   }
 283   lj_err_arg(L, narg, LJ_ERR_NOTABN);
 284   return NULL;  /* unreachable */
 285 }
 286 
 287 int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst)
 288 {
 289   GCstr *s = def >= 0 ? lj_lib_optstr(L, narg) : lj_lib_checkstr(L, narg);
 290   if (s) {
 291     const char *opt = strdata(s);
 292     MSize len = s->len;
 293     int i;
 294     for (i = 0; *(const uint8_t *)lst; i++) {
 295       if (*(const uint8_t *)lst == len && memcmp(opt, lst+1, len) == 0)
 296         return i;
 297       lst += 1+*(const uint8_t *)lst;
 298     }
 299     lj_err_argv(L, narg, LJ_ERR_INVOPTM, opt);
 300   }
 301   return def;
 302 }
 303 

/* [<][>][^][v][top][bottom][index][help] */