lua/lapi.c
changeset 0 d7ee4e2ed49d
equal deleted inserted replaced
-1:000000000000 0:d7ee4e2ed49d
       
     1 /*
       
     2 ** $Id: lapi.c,v 2.171.1.1 2013/04/12 18:48:47 roberto Exp $
       
     3 ** Lua API
       
     4 ** See Copyright Notice in lua.h
       
     5 */
       
     6 
       
     7 
       
     8 #include <stdarg.h>
       
     9 #include <string.h>
       
    10 
       
    11 #define lapi_c
       
    12 #define LUA_CORE
       
    13 
       
    14 #include "lua.h"
       
    15 
       
    16 #include "lapi.h"
       
    17 #include "ldebug.h"
       
    18 #include "ldo.h"
       
    19 #include "lfunc.h"
       
    20 #include "lgc.h"
       
    21 #include "lmem.h"
       
    22 #include "lobject.h"
       
    23 #include "lstate.h"
       
    24 #include "lstring.h"
       
    25 #include "ltable.h"
       
    26 #include "ltm.h"
       
    27 #include "lundump.h"
       
    28 #include "lvm.h"
       
    29 
       
    30 
       
    31 
       
    32 const char lua_ident[] =
       
    33   "$LuaVersion: " LUA_COPYRIGHT " $"
       
    34   "$LuaAuthors: " LUA_AUTHORS " $";
       
    35 
       
    36 
       
    37 /* value at a non-valid index */
       
    38 #define NONVALIDVALUE		cast(TValue *, luaO_nilobject)
       
    39 
       
    40 /* corresponding test */
       
    41 #define isvalid(o)	((o) != luaO_nilobject)
       
    42 
       
    43 /* test for pseudo index */
       
    44 #define ispseudo(i)		((i) <= LUA_REGISTRYINDEX)
       
    45 
       
    46 /* test for valid but not pseudo index */
       
    47 #define isstackindex(i, o)	(isvalid(o) && !ispseudo(i))
       
    48 
       
    49 #define api_checkvalidindex(L, o)  api_check(L, isvalid(o), "invalid index")
       
    50 
       
    51 #define api_checkstackindex(L, i, o)  \
       
    52 	api_check(L, isstackindex(i, o), "index not in the stack")
       
    53 
       
    54 
       
    55 static TValue *index2addr (lua_State *L, int idx) {
       
    56   CallInfo *ci = L->ci;
       
    57   if (idx > 0) {
       
    58     TValue *o = ci->func + idx;
       
    59     api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
       
    60     if (o >= L->top) return NONVALIDVALUE;
       
    61     else return o;
       
    62   }
       
    63   else if (!ispseudo(idx)) {  /* negative index */
       
    64     api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
       
    65     return L->top + idx;
       
    66   }
       
    67   else if (idx == LUA_REGISTRYINDEX)
       
    68     return &G(L)->l_registry;
       
    69   else {  /* upvalues */
       
    70     idx = LUA_REGISTRYINDEX - idx;
       
    71     api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
       
    72     if (ttislcf(ci->func))  /* light C function? */
       
    73       return NONVALIDVALUE;  /* it has no upvalues */
       
    74     else {
       
    75       CClosure *func = clCvalue(ci->func);
       
    76       return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE;
       
    77     }
       
    78   }
       
    79 }
       
    80 
       
    81 
       
    82 /*
       
    83 ** to be called by 'lua_checkstack' in protected mode, to grow stack
       
    84 ** capturing memory errors
       
    85 */
       
    86 static void growstack (lua_State *L, void *ud) {
       
    87   int size = *(int *)ud;
       
    88   luaD_growstack(L, size);
       
    89 }
       
    90 
       
    91 
       
    92 LUA_API int lua_checkstack (lua_State *L, int size) {
       
    93   int res;
       
    94   CallInfo *ci = L->ci;
       
    95   lua_lock(L);
       
    96   if (L->stack_last - L->top > size)  /* stack large enough? */
       
    97     res = 1;  /* yes; check is OK */
       
    98   else {  /* no; need to grow stack */
       
    99     int inuse = cast_int(L->top - L->stack) + EXTRA_STACK;
       
   100     if (inuse > LUAI_MAXSTACK - size)  /* can grow without overflow? */
       
   101       res = 0;  /* no */
       
   102     else  /* try to grow stack */
       
   103       res = (luaD_rawrunprotected(L, &growstack, &size) == LUA_OK);
       
   104   }
       
   105   if (res && ci->top < L->top + size)
       
   106     ci->top = L->top + size;  /* adjust frame top */
       
   107   lua_unlock(L);
       
   108   return res;
       
   109 }
       
   110 
       
   111 
       
   112 LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
       
   113   int i;
       
   114   if (from == to) return;
       
   115   lua_lock(to);
       
   116   api_checknelems(from, n);
       
   117   api_check(from, G(from) == G(to), "moving among independent states");
       
   118   api_check(from, to->ci->top - to->top >= n, "not enough elements to move");
       
   119   from->top -= n;
       
   120   for (i = 0; i < n; i++) {
       
   121     setobj2s(to, to->top++, from->top + i);
       
   122   }
       
   123   lua_unlock(to);
       
   124 }
       
   125 
       
   126 
       
   127 LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
       
   128   lua_CFunction old;
       
   129   lua_lock(L);
       
   130   old = G(L)->panic;
       
   131   G(L)->panic = panicf;
       
   132   lua_unlock(L);
       
   133   return old;
       
   134 }
       
   135 
       
   136 
       
   137 LUA_API const lua_Number *lua_version (lua_State *L) {
       
   138   static const lua_Number version = LUA_VERSION_NUM;
       
   139   if (L == NULL) return &version;
       
   140   else return G(L)->version;
       
   141 }
       
   142 
       
   143 
       
   144 
       
   145 /*
       
   146 ** basic stack manipulation
       
   147 */
       
   148 
       
   149 
       
   150 /*
       
   151 ** convert an acceptable stack index into an absolute index
       
   152 */
       
   153 LUA_API int lua_absindex (lua_State *L, int idx) {
       
   154   return (idx > 0 || ispseudo(idx))
       
   155          ? idx
       
   156          : cast_int(L->top - L->ci->func + idx);
       
   157 }
       
   158 
       
   159 
       
   160 LUA_API int lua_gettop (lua_State *L) {
       
   161   return cast_int(L->top - (L->ci->func + 1));
       
   162 }
       
   163 
       
   164 
       
   165 LUA_API void lua_settop (lua_State *L, int idx) {
       
   166   StkId func = L->ci->func;
       
   167   lua_lock(L);
       
   168   if (idx >= 0) {
       
   169     api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
       
   170     while (L->top < (func + 1) + idx)
       
   171       setnilvalue(L->top++);
       
   172     L->top = (func + 1) + idx;
       
   173   }
       
   174   else {
       
   175     api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
       
   176     L->top += idx+1;  /* `subtract' index (index is negative) */
       
   177   }
       
   178   lua_unlock(L);
       
   179 }
       
   180 
       
   181 
       
   182 LUA_API void lua_remove (lua_State *L, int idx) {
       
   183   StkId p;
       
   184   lua_lock(L);
       
   185   p = index2addr(L, idx);
       
   186   api_checkstackindex(L, idx, p);
       
   187   while (++p < L->top) setobjs2s(L, p-1, p);
       
   188   L->top--;
       
   189   lua_unlock(L);
       
   190 }
       
   191 
       
   192 
       
   193 LUA_API void lua_insert (lua_State *L, int idx) {
       
   194   StkId p;
       
   195   StkId q;
       
   196   lua_lock(L);
       
   197   p = index2addr(L, idx);
       
   198   api_checkstackindex(L, idx, p);
       
   199   for (q = L->top; q > p; q--)  /* use L->top as a temporary */
       
   200     setobjs2s(L, q, q - 1);
       
   201   setobjs2s(L, p, L->top);
       
   202   lua_unlock(L);
       
   203 }
       
   204 
       
   205 
       
   206 static void moveto (lua_State *L, TValue *fr, int idx) {
       
   207   TValue *to = index2addr(L, idx);
       
   208   api_checkvalidindex(L, to);
       
   209   setobj(L, to, fr);
       
   210   if (idx < LUA_REGISTRYINDEX)  /* function upvalue? */
       
   211     luaC_barrier(L, clCvalue(L->ci->func), fr);
       
   212   /* LUA_REGISTRYINDEX does not need gc barrier
       
   213      (collector revisits it before finishing collection) */
       
   214 }
       
   215 
       
   216 
       
   217 LUA_API void lua_replace (lua_State *L, int idx) {
       
   218   lua_lock(L);
       
   219   api_checknelems(L, 1);
       
   220   moveto(L, L->top - 1, idx);
       
   221   L->top--;
       
   222   lua_unlock(L);
       
   223 }
       
   224 
       
   225 
       
   226 LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
       
   227   TValue *fr;
       
   228   lua_lock(L);
       
   229   fr = index2addr(L, fromidx);
       
   230   moveto(L, fr, toidx);
       
   231   lua_unlock(L);
       
   232 }
       
   233 
       
   234 
       
   235 LUA_API void lua_pushvalue (lua_State *L, int idx) {
       
   236   lua_lock(L);
       
   237   setobj2s(L, L->top, index2addr(L, idx));
       
   238   api_incr_top(L);
       
   239   lua_unlock(L);
       
   240 }
       
   241 
       
   242 
       
   243 
       
   244 /*
       
   245 ** access functions (stack -> C)
       
   246 */
       
   247 
       
   248 
       
   249 LUA_API int lua_type (lua_State *L, int idx) {
       
   250   StkId o = index2addr(L, idx);
       
   251   return (isvalid(o) ? ttypenv(o) : LUA_TNONE);
       
   252 }
       
   253 
       
   254 
       
   255 LUA_API const char *lua_typename (lua_State *L, int t) {
       
   256   UNUSED(L);
       
   257   return ttypename(t);
       
   258 }
       
   259 
       
   260 
       
   261 LUA_API int lua_iscfunction (lua_State *L, int idx) {
       
   262   StkId o = index2addr(L, idx);
       
   263   return (ttislcf(o) || (ttisCclosure(o)));
       
   264 }
       
   265 
       
   266 
       
   267 LUA_API int lua_isnumber (lua_State *L, int idx) {
       
   268   TValue n;
       
   269   const TValue *o = index2addr(L, idx);
       
   270   return tonumber(o, &n);
       
   271 }
       
   272 
       
   273 
       
   274 LUA_API int lua_isstring (lua_State *L, int idx) {
       
   275   int t = lua_type(L, idx);
       
   276   return (t == LUA_TSTRING || t == LUA_TNUMBER);
       
   277 }
       
   278 
       
   279 
       
   280 LUA_API int lua_isuserdata (lua_State *L, int idx) {
       
   281   const TValue *o = index2addr(L, idx);
       
   282   return (ttisuserdata(o) || ttislightuserdata(o));
       
   283 }
       
   284 
       
   285 
       
   286 LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
       
   287   StkId o1 = index2addr(L, index1);
       
   288   StkId o2 = index2addr(L, index2);
       
   289   return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0;
       
   290 }
       
   291 
       
   292 
       
   293 LUA_API void lua_arith (lua_State *L, int op) {
       
   294   StkId o1;  /* 1st operand */
       
   295   StkId o2;  /* 2nd operand */
       
   296   lua_lock(L);
       
   297   if (op != LUA_OPUNM) /* all other operations expect two operands */
       
   298     api_checknelems(L, 2);
       
   299   else {  /* for unary minus, add fake 2nd operand */
       
   300     api_checknelems(L, 1);
       
   301     setobjs2s(L, L->top, L->top - 1);
       
   302     L->top++;
       
   303   }
       
   304   o1 = L->top - 2;
       
   305   o2 = L->top - 1;
       
   306   if (ttisnumber(o1) && ttisnumber(o2)) {
       
   307     setnvalue(o1, luaO_arith(op, nvalue(o1), nvalue(o2)));
       
   308   }
       
   309   else
       
   310     luaV_arith(L, o1, o1, o2, cast(TMS, op - LUA_OPADD + TM_ADD));
       
   311   L->top--;
       
   312   lua_unlock(L);
       
   313 }
       
   314 
       
   315 
       
   316 LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
       
   317   StkId o1, o2;
       
   318   int i = 0;
       
   319   lua_lock(L);  /* may call tag method */
       
   320   o1 = index2addr(L, index1);
       
   321   o2 = index2addr(L, index2);
       
   322   if (isvalid(o1) && isvalid(o2)) {
       
   323     switch (op) {
       
   324       case LUA_OPEQ: i = equalobj(L, o1, o2); break;
       
   325       case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
       
   326       case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
       
   327       default: api_check(L, 0, "invalid option");
       
   328     }
       
   329   }
       
   330   lua_unlock(L);
       
   331   return i;
       
   332 }
       
   333 
       
   334 
       
   335 LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum) {
       
   336   TValue n;
       
   337   const TValue *o = index2addr(L, idx);
       
   338   if (tonumber(o, &n)) {
       
   339     if (isnum) *isnum = 1;
       
   340     return nvalue(o);
       
   341   }
       
   342   else {
       
   343     if (isnum) *isnum = 0;
       
   344     return 0;
       
   345   }
       
   346 }
       
   347 
       
   348 
       
   349 LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) {
       
   350   TValue n;
       
   351   const TValue *o = index2addr(L, idx);
       
   352   if (tonumber(o, &n)) {
       
   353     lua_Integer res;
       
   354     lua_Number num = nvalue(o);
       
   355     lua_number2integer(res, num);
       
   356     if (isnum) *isnum = 1;
       
   357     return res;
       
   358   }
       
   359   else {
       
   360     if (isnum) *isnum = 0;
       
   361     return 0;
       
   362   }
       
   363 }
       
   364 
       
   365 
       
   366 LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) {
       
   367   TValue n;
       
   368   const TValue *o = index2addr(L, idx);
       
   369   if (tonumber(o, &n)) {
       
   370     lua_Unsigned res;
       
   371     lua_Number num = nvalue(o);
       
   372     lua_number2unsigned(res, num);
       
   373     if (isnum) *isnum = 1;
       
   374     return res;
       
   375   }
       
   376   else {
       
   377     if (isnum) *isnum = 0;
       
   378     return 0;
       
   379   }
       
   380 }
       
   381 
       
   382 
       
   383 LUA_API int lua_toboolean (lua_State *L, int idx) {
       
   384   const TValue *o = index2addr(L, idx);
       
   385   return !l_isfalse(o);
       
   386 }
       
   387 
       
   388 
       
   389 LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
       
   390   StkId o = index2addr(L, idx);
       
   391   if (!ttisstring(o)) {
       
   392     lua_lock(L);  /* `luaV_tostring' may create a new string */
       
   393     if (!luaV_tostring(L, o)) {  /* conversion failed? */
       
   394       if (len != NULL) *len = 0;
       
   395       lua_unlock(L);
       
   396       return NULL;
       
   397     }
       
   398     luaC_checkGC(L);
       
   399     o = index2addr(L, idx);  /* previous call may reallocate the stack */
       
   400     lua_unlock(L);
       
   401   }
       
   402   if (len != NULL) *len = tsvalue(o)->len;
       
   403   return svalue(o);
       
   404 }
       
   405 
       
   406 
       
   407 LUA_API size_t lua_rawlen (lua_State *L, int idx) {
       
   408   StkId o = index2addr(L, idx);
       
   409   switch (ttypenv(o)) {
       
   410     case LUA_TSTRING: return tsvalue(o)->len;
       
   411     case LUA_TUSERDATA: return uvalue(o)->len;
       
   412     case LUA_TTABLE: return luaH_getn(hvalue(o));
       
   413     default: return 0;
       
   414   }
       
   415 }
       
   416 
       
   417 
       
   418 LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
       
   419   StkId o = index2addr(L, idx);
       
   420   if (ttislcf(o)) return fvalue(o);
       
   421   else if (ttisCclosure(o))
       
   422     return clCvalue(o)->f;
       
   423   else return NULL;  /* not a C function */
       
   424 }
       
   425 
       
   426 
       
   427 LUA_API void *lua_touserdata (lua_State *L, int idx) {
       
   428   StkId o = index2addr(L, idx);
       
   429   switch (ttypenv(o)) {
       
   430     case LUA_TUSERDATA: return (rawuvalue(o) + 1);
       
   431     case LUA_TLIGHTUSERDATA: return pvalue(o);
       
   432     default: return NULL;
       
   433   }
       
   434 }
       
   435 
       
   436 
       
   437 LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
       
   438   StkId o = index2addr(L, idx);
       
   439   return (!ttisthread(o)) ? NULL : thvalue(o);
       
   440 }
       
   441 
       
   442 
       
   443 LUA_API const void *lua_topointer (lua_State *L, int idx) {
       
   444   StkId o = index2addr(L, idx);
       
   445   switch (ttype(o)) {
       
   446     case LUA_TTABLE: return hvalue(o);
       
   447     case LUA_TLCL: return clLvalue(o);
       
   448     case LUA_TCCL: return clCvalue(o);
       
   449     case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
       
   450     case LUA_TTHREAD: return thvalue(o);
       
   451     case LUA_TUSERDATA:
       
   452     case LUA_TLIGHTUSERDATA:
       
   453       return lua_touserdata(L, idx);
       
   454     default: return NULL;
       
   455   }
       
   456 }
       
   457 
       
   458 
       
   459 
       
   460 /*
       
   461 ** push functions (C -> stack)
       
   462 */
       
   463 
       
   464 
       
   465 LUA_API void lua_pushnil (lua_State *L) {
       
   466   lua_lock(L);
       
   467   setnilvalue(L->top);
       
   468   api_incr_top(L);
       
   469   lua_unlock(L);
       
   470 }
       
   471 
       
   472 
       
   473 LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
       
   474   lua_lock(L);
       
   475   setnvalue(L->top, n);
       
   476   luai_checknum(L, L->top,
       
   477     luaG_runerror(L, "C API - attempt to push a signaling NaN"));
       
   478   api_incr_top(L);
       
   479   lua_unlock(L);
       
   480 }
       
   481 
       
   482 
       
   483 LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
       
   484   lua_lock(L);
       
   485   setnvalue(L->top, cast_num(n));
       
   486   api_incr_top(L);
       
   487   lua_unlock(L);
       
   488 }
       
   489 
       
   490 
       
   491 LUA_API void lua_pushunsigned (lua_State *L, lua_Unsigned u) {
       
   492   lua_Number n;
       
   493   lua_lock(L);
       
   494   n = lua_unsigned2number(u);
       
   495   setnvalue(L->top, n);
       
   496   api_incr_top(L);
       
   497   lua_unlock(L);
       
   498 }
       
   499 
       
   500 
       
   501 LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
       
   502   TString *ts;
       
   503   lua_lock(L);
       
   504   luaC_checkGC(L);
       
   505   ts = luaS_newlstr(L, s, len);
       
   506   setsvalue2s(L, L->top, ts);
       
   507   api_incr_top(L);
       
   508   lua_unlock(L);
       
   509   return getstr(ts);
       
   510 }
       
   511 
       
   512 
       
   513 LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
       
   514   if (s == NULL) {
       
   515     lua_pushnil(L);
       
   516     return NULL;
       
   517   }
       
   518   else {
       
   519     TString *ts;
       
   520     lua_lock(L);
       
   521     luaC_checkGC(L);
       
   522     ts = luaS_new(L, s);
       
   523     setsvalue2s(L, L->top, ts);
       
   524     api_incr_top(L);
       
   525     lua_unlock(L);
       
   526     return getstr(ts);
       
   527   }
       
   528 }
       
   529 
       
   530 
       
   531 LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
       
   532                                       va_list argp) {
       
   533   const char *ret;
       
   534   lua_lock(L);
       
   535   luaC_checkGC(L);
       
   536   ret = luaO_pushvfstring(L, fmt, argp);
       
   537   lua_unlock(L);
       
   538   return ret;
       
   539 }
       
   540 
       
   541 
       
   542 LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
       
   543   const char *ret;
       
   544   va_list argp;
       
   545   lua_lock(L);
       
   546   luaC_checkGC(L);
       
   547   va_start(argp, fmt);
       
   548   ret = luaO_pushvfstring(L, fmt, argp);
       
   549   va_end(argp);
       
   550   lua_unlock(L);
       
   551   return ret;
       
   552 }
       
   553 
       
   554 
       
   555 LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
       
   556   lua_lock(L);
       
   557   if (n == 0) {
       
   558     setfvalue(L->top, fn);
       
   559   }
       
   560   else {
       
   561     Closure *cl;
       
   562     api_checknelems(L, n);
       
   563     api_check(L, n <= MAXUPVAL, "upvalue index too large");
       
   564     luaC_checkGC(L);
       
   565     cl = luaF_newCclosure(L, n);
       
   566     cl->c.f = fn;
       
   567     L->top -= n;
       
   568     while (n--)
       
   569       setobj2n(L, &cl->c.upvalue[n], L->top + n);
       
   570     setclCvalue(L, L->top, cl);
       
   571   }
       
   572   api_incr_top(L);
       
   573   lua_unlock(L);
       
   574 }
       
   575 
       
   576 
       
   577 LUA_API void lua_pushboolean (lua_State *L, int b) {
       
   578   lua_lock(L);
       
   579   setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
       
   580   api_incr_top(L);
       
   581   lua_unlock(L);
       
   582 }
       
   583 
       
   584 
       
   585 LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
       
   586   lua_lock(L);
       
   587   setpvalue(L->top, p);
       
   588   api_incr_top(L);
       
   589   lua_unlock(L);
       
   590 }
       
   591 
       
   592 
       
   593 LUA_API int lua_pushthread (lua_State *L) {
       
   594   lua_lock(L);
       
   595   setthvalue(L, L->top, L);
       
   596   api_incr_top(L);
       
   597   lua_unlock(L);
       
   598   return (G(L)->mainthread == L);
       
   599 }
       
   600 
       
   601 
       
   602 
       
   603 /*
       
   604 ** get functions (Lua -> stack)
       
   605 */
       
   606 
       
   607 
       
   608 LUA_API void lua_getglobal (lua_State *L, const char *var) {
       
   609   Table *reg = hvalue(&G(L)->l_registry);
       
   610   const TValue *gt;  /* global table */
       
   611   lua_lock(L);
       
   612   gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
       
   613   setsvalue2s(L, L->top++, luaS_new(L, var));
       
   614   luaV_gettable(L, gt, L->top - 1, L->top - 1);
       
   615   lua_unlock(L);
       
   616 }
       
   617 
       
   618 
       
   619 LUA_API void lua_gettable (lua_State *L, int idx) {
       
   620   StkId t;
       
   621   lua_lock(L);
       
   622   t = index2addr(L, idx);
       
   623   luaV_gettable(L, t, L->top - 1, L->top - 1);
       
   624   lua_unlock(L);
       
   625 }
       
   626 
       
   627 
       
   628 LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
       
   629   StkId t;
       
   630   lua_lock(L);
       
   631   t = index2addr(L, idx);
       
   632   setsvalue2s(L, L->top, luaS_new(L, k));
       
   633   api_incr_top(L);
       
   634   luaV_gettable(L, t, L->top - 1, L->top - 1);
       
   635   lua_unlock(L);
       
   636 }
       
   637 
       
   638 
       
   639 LUA_API void lua_rawget (lua_State *L, int idx) {
       
   640   StkId t;
       
   641   lua_lock(L);
       
   642   t = index2addr(L, idx);
       
   643   api_check(L, ttistable(t), "table expected");
       
   644   setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
       
   645   lua_unlock(L);
       
   646 }
       
   647 
       
   648 
       
   649 LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
       
   650   StkId t;
       
   651   lua_lock(L);
       
   652   t = index2addr(L, idx);
       
   653   api_check(L, ttistable(t), "table expected");
       
   654   setobj2s(L, L->top, luaH_getint(hvalue(t), n));
       
   655   api_incr_top(L);
       
   656   lua_unlock(L);
       
   657 }
       
   658 
       
   659 
       
   660 LUA_API void lua_rawgetp (lua_State *L, int idx, const void *p) {
       
   661   StkId t;
       
   662   TValue k;
       
   663   lua_lock(L);
       
   664   t = index2addr(L, idx);
       
   665   api_check(L, ttistable(t), "table expected");
       
   666   setpvalue(&k, cast(void *, p));
       
   667   setobj2s(L, L->top, luaH_get(hvalue(t), &k));
       
   668   api_incr_top(L);
       
   669   lua_unlock(L);
       
   670 }
       
   671 
       
   672 
       
   673 LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
       
   674   Table *t;
       
   675   lua_lock(L);
       
   676   luaC_checkGC(L);
       
   677   t = luaH_new(L);
       
   678   sethvalue(L, L->top, t);
       
   679   api_incr_top(L);
       
   680   if (narray > 0 || nrec > 0)
       
   681     luaH_resize(L, t, narray, nrec);
       
   682   lua_unlock(L);
       
   683 }
       
   684 
       
   685 
       
   686 LUA_API int lua_getmetatable (lua_State *L, int objindex) {
       
   687   const TValue *obj;
       
   688   Table *mt = NULL;
       
   689   int res;
       
   690   lua_lock(L);
       
   691   obj = index2addr(L, objindex);
       
   692   switch (ttypenv(obj)) {
       
   693     case LUA_TTABLE:
       
   694       mt = hvalue(obj)->metatable;
       
   695       break;
       
   696     case LUA_TUSERDATA:
       
   697       mt = uvalue(obj)->metatable;
       
   698       break;
       
   699     default:
       
   700       mt = G(L)->mt[ttypenv(obj)];
       
   701       break;
       
   702   }
       
   703   if (mt == NULL)
       
   704     res = 0;
       
   705   else {
       
   706     sethvalue(L, L->top, mt);
       
   707     api_incr_top(L);
       
   708     res = 1;
       
   709   }
       
   710   lua_unlock(L);
       
   711   return res;
       
   712 }
       
   713 
       
   714 
       
   715 LUA_API void lua_getuservalue (lua_State *L, int idx) {
       
   716   StkId o;
       
   717   lua_lock(L);
       
   718   o = index2addr(L, idx);
       
   719   api_check(L, ttisuserdata(o), "userdata expected");
       
   720   if (uvalue(o)->env) {
       
   721     sethvalue(L, L->top, uvalue(o)->env);
       
   722   } else
       
   723     setnilvalue(L->top);
       
   724   api_incr_top(L);
       
   725   lua_unlock(L);
       
   726 }
       
   727 
       
   728 
       
   729 /*
       
   730 ** set functions (stack -> Lua)
       
   731 */
       
   732 
       
   733 
       
   734 LUA_API void lua_setglobal (lua_State *L, const char *var) {
       
   735   Table *reg = hvalue(&G(L)->l_registry);
       
   736   const TValue *gt;  /* global table */
       
   737   lua_lock(L);
       
   738   api_checknelems(L, 1);
       
   739   gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
       
   740   setsvalue2s(L, L->top++, luaS_new(L, var));
       
   741   luaV_settable(L, gt, L->top - 1, L->top - 2);
       
   742   L->top -= 2;  /* pop value and key */
       
   743   lua_unlock(L);
       
   744 }
       
   745 
       
   746 
       
   747 LUA_API void lua_settable (lua_State *L, int idx) {
       
   748   StkId t;
       
   749   lua_lock(L);
       
   750   api_checknelems(L, 2);
       
   751   t = index2addr(L, idx);
       
   752   luaV_settable(L, t, L->top - 2, L->top - 1);
       
   753   L->top -= 2;  /* pop index and value */
       
   754   lua_unlock(L);
       
   755 }
       
   756 
       
   757 
       
   758 LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
       
   759   StkId t;
       
   760   lua_lock(L);
       
   761   api_checknelems(L, 1);
       
   762   t = index2addr(L, idx);
       
   763   setsvalue2s(L, L->top++, luaS_new(L, k));
       
   764   luaV_settable(L, t, L->top - 1, L->top - 2);
       
   765   L->top -= 2;  /* pop value and key */
       
   766   lua_unlock(L);
       
   767 }
       
   768 
       
   769 
       
   770 LUA_API void lua_rawset (lua_State *L, int idx) {
       
   771   StkId t;
       
   772   lua_lock(L);
       
   773   api_checknelems(L, 2);
       
   774   t = index2addr(L, idx);
       
   775   api_check(L, ttistable(t), "table expected");
       
   776   setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
       
   777   invalidateTMcache(hvalue(t));
       
   778   luaC_barrierback(L, gcvalue(t), L->top-1);
       
   779   L->top -= 2;
       
   780   lua_unlock(L);
       
   781 }
       
   782 
       
   783 
       
   784 LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
       
   785   StkId t;
       
   786   lua_lock(L);
       
   787   api_checknelems(L, 1);
       
   788   t = index2addr(L, idx);
       
   789   api_check(L, ttistable(t), "table expected");
       
   790   luaH_setint(L, hvalue(t), n, L->top - 1);
       
   791   luaC_barrierback(L, gcvalue(t), L->top-1);
       
   792   L->top--;
       
   793   lua_unlock(L);
       
   794 }
       
   795 
       
   796 
       
   797 LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
       
   798   StkId t;
       
   799   TValue k;
       
   800   lua_lock(L);
       
   801   api_checknelems(L, 1);
       
   802   t = index2addr(L, idx);
       
   803   api_check(L, ttistable(t), "table expected");
       
   804   setpvalue(&k, cast(void *, p));
       
   805   setobj2t(L, luaH_set(L, hvalue(t), &k), L->top - 1);
       
   806   luaC_barrierback(L, gcvalue(t), L->top - 1);
       
   807   L->top--;
       
   808   lua_unlock(L);
       
   809 }
       
   810 
       
   811 
       
   812 LUA_API int lua_setmetatable (lua_State *L, int objindex) {
       
   813   TValue *obj;
       
   814   Table *mt;
       
   815   lua_lock(L);
       
   816   api_checknelems(L, 1);
       
   817   obj = index2addr(L, objindex);
       
   818   if (ttisnil(L->top - 1))
       
   819     mt = NULL;
       
   820   else {
       
   821     api_check(L, ttistable(L->top - 1), "table expected");
       
   822     mt = hvalue(L->top - 1);
       
   823   }
       
   824   switch (ttypenv(obj)) {
       
   825     case LUA_TTABLE: {
       
   826       hvalue(obj)->metatable = mt;
       
   827       if (mt) {
       
   828         luaC_objbarrierback(L, gcvalue(obj), mt);
       
   829         luaC_checkfinalizer(L, gcvalue(obj), mt);
       
   830       }
       
   831       break;
       
   832     }
       
   833     case LUA_TUSERDATA: {
       
   834       uvalue(obj)->metatable = mt;
       
   835       if (mt) {
       
   836         luaC_objbarrier(L, rawuvalue(obj), mt);
       
   837         luaC_checkfinalizer(L, gcvalue(obj), mt);
       
   838       }
       
   839       break;
       
   840     }
       
   841     default: {
       
   842       G(L)->mt[ttypenv(obj)] = mt;
       
   843       break;
       
   844     }
       
   845   }
       
   846   L->top--;
       
   847   lua_unlock(L);
       
   848   return 1;
       
   849 }
       
   850 
       
   851 
       
   852 LUA_API void lua_setuservalue (lua_State *L, int idx) {
       
   853   StkId o;
       
   854   lua_lock(L);
       
   855   api_checknelems(L, 1);
       
   856   o = index2addr(L, idx);
       
   857   api_check(L, ttisuserdata(o), "userdata expected");
       
   858   if (ttisnil(L->top - 1))
       
   859     uvalue(o)->env = NULL;
       
   860   else {
       
   861     api_check(L, ttistable(L->top - 1), "table expected");
       
   862     uvalue(o)->env = hvalue(L->top - 1);
       
   863     luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
       
   864   }
       
   865   L->top--;
       
   866   lua_unlock(L);
       
   867 }
       
   868 
       
   869 
       
   870 /*
       
   871 ** `load' and `call' functions (run Lua code)
       
   872 */
       
   873 
       
   874 
       
   875 #define checkresults(L,na,nr) \
       
   876      api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
       
   877 	"results from function overflow current stack size")
       
   878 
       
   879 
       
   880 LUA_API int lua_getctx (lua_State *L, int *ctx) {
       
   881   if (L->ci->callstatus & CIST_YIELDED) {
       
   882     if (ctx) *ctx = L->ci->u.c.ctx;
       
   883     return L->ci->u.c.status;
       
   884   }
       
   885   else return LUA_OK;
       
   886 }
       
   887 
       
   888 
       
   889 LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx,
       
   890                         lua_CFunction k) {
       
   891   StkId func;
       
   892   lua_lock(L);
       
   893   api_check(L, k == NULL || !isLua(L->ci),
       
   894     "cannot use continuations inside hooks");
       
   895   api_checknelems(L, nargs+1);
       
   896   api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
       
   897   checkresults(L, nargs, nresults);
       
   898   func = L->top - (nargs+1);
       
   899   if (k != NULL && L->nny == 0) {  /* need to prepare continuation? */
       
   900     L->ci->u.c.k = k;  /* save continuation */
       
   901     L->ci->u.c.ctx = ctx;  /* save context */
       
   902     luaD_call(L, func, nresults, 1);  /* do the call */
       
   903   }
       
   904   else  /* no continuation or no yieldable */
       
   905     luaD_call(L, func, nresults, 0);  /* just do the call */
       
   906   adjustresults(L, nresults);
       
   907   lua_unlock(L);
       
   908 }
       
   909 
       
   910 
       
   911 
       
   912 /*
       
   913 ** Execute a protected call.
       
   914 */
       
   915 struct CallS {  /* data to `f_call' */
       
   916   StkId func;
       
   917   int nresults;
       
   918 };
       
   919 
       
   920 
       
   921 static void f_call (lua_State *L, void *ud) {
       
   922   struct CallS *c = cast(struct CallS *, ud);
       
   923   luaD_call(L, c->func, c->nresults, 0);
       
   924 }
       
   925 
       
   926 
       
   927 
       
   928 LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
       
   929                         int ctx, lua_CFunction k) {
       
   930   struct CallS c;
       
   931   int status;
       
   932   ptrdiff_t func;
       
   933   lua_lock(L);
       
   934   api_check(L, k == NULL || !isLua(L->ci),
       
   935     "cannot use continuations inside hooks");
       
   936   api_checknelems(L, nargs+1);
       
   937   api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
       
   938   checkresults(L, nargs, nresults);
       
   939   if (errfunc == 0)
       
   940     func = 0;
       
   941   else {
       
   942     StkId o = index2addr(L, errfunc);
       
   943     api_checkstackindex(L, errfunc, o);
       
   944     func = savestack(L, o);
       
   945   }
       
   946   c.func = L->top - (nargs+1);  /* function to be called */
       
   947   if (k == NULL || L->nny > 0) {  /* no continuation or no yieldable? */
       
   948     c.nresults = nresults;  /* do a 'conventional' protected call */
       
   949     status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
       
   950   }
       
   951   else {  /* prepare continuation (call is already protected by 'resume') */
       
   952     CallInfo *ci = L->ci;
       
   953     ci->u.c.k = k;  /* save continuation */
       
   954     ci->u.c.ctx = ctx;  /* save context */
       
   955     /* save information for error recovery */
       
   956     ci->extra = savestack(L, c.func);
       
   957     ci->u.c.old_allowhook = L->allowhook;
       
   958     ci->u.c.old_errfunc = L->errfunc;
       
   959     L->errfunc = func;
       
   960     /* mark that function may do error recovery */
       
   961     ci->callstatus |= CIST_YPCALL;
       
   962     luaD_call(L, c.func, nresults, 1);  /* do the call */
       
   963     ci->callstatus &= ~CIST_YPCALL;
       
   964     L->errfunc = ci->u.c.old_errfunc;
       
   965     status = LUA_OK;  /* if it is here, there were no errors */
       
   966   }
       
   967   adjustresults(L, nresults);
       
   968   lua_unlock(L);
       
   969   return status;
       
   970 }
       
   971 
       
   972 
       
   973 LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
       
   974                       const char *chunkname, const char *mode) {
       
   975   ZIO z;
       
   976   int status;
       
   977   lua_lock(L);
       
   978   if (!chunkname) chunkname = "?";
       
   979   luaZ_init(L, &z, reader, data);
       
   980   status = luaD_protectedparser(L, &z, chunkname, mode);
       
   981   if (status == LUA_OK) {  /* no errors? */
       
   982     LClosure *f = clLvalue(L->top - 1);  /* get newly created function */
       
   983     if (f->nupvalues == 1) {  /* does it have one upvalue? */
       
   984       /* get global table from registry */
       
   985       Table *reg = hvalue(&G(L)->l_registry);
       
   986       const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
       
   987       /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
       
   988       setobj(L, f->upvals[0]->v, gt);
       
   989       luaC_barrier(L, f->upvals[0], gt);
       
   990     }
       
   991   }
       
   992   lua_unlock(L);
       
   993   return status;
       
   994 }
       
   995 
       
   996 
       
   997 LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
       
   998   int status;
       
   999   TValue *o;
       
  1000   lua_lock(L);
       
  1001   api_checknelems(L, 1);
       
  1002   o = L->top - 1;
       
  1003   if (isLfunction(o))
       
  1004     status = luaU_dump(L, getproto(o), writer, data, 0);
       
  1005   else
       
  1006     status = 1;
       
  1007   lua_unlock(L);
       
  1008   return status;
       
  1009 }
       
  1010 
       
  1011 
       
  1012 LUA_API int lua_status (lua_State *L) {
       
  1013   return L->status;
       
  1014 }
       
  1015 
       
  1016 
       
  1017 /*
       
  1018 ** Garbage-collection function
       
  1019 */
       
  1020 
       
  1021 LUA_API int lua_gc (lua_State *L, int what, int data) {
       
  1022   int res = 0;
       
  1023   global_State *g;
       
  1024   lua_lock(L);
       
  1025   g = G(L);
       
  1026   switch (what) {
       
  1027     case LUA_GCSTOP: {
       
  1028       g->gcrunning = 0;
       
  1029       break;
       
  1030     }
       
  1031     case LUA_GCRESTART: {
       
  1032       luaE_setdebt(g, 0);
       
  1033       g->gcrunning = 1;
       
  1034       break;
       
  1035     }
       
  1036     case LUA_GCCOLLECT: {
       
  1037       luaC_fullgc(L, 0);
       
  1038       break;
       
  1039     }
       
  1040     case LUA_GCCOUNT: {
       
  1041       /* GC values are expressed in Kbytes: #bytes/2^10 */
       
  1042       res = cast_int(gettotalbytes(g) >> 10);
       
  1043       break;
       
  1044     }
       
  1045     case LUA_GCCOUNTB: {
       
  1046       res = cast_int(gettotalbytes(g) & 0x3ff);
       
  1047       break;
       
  1048     }
       
  1049     case LUA_GCSTEP: {
       
  1050       if (g->gckind == KGC_GEN) {  /* generational mode? */
       
  1051         res = (g->GCestimate == 0);  /* true if it will do major collection */
       
  1052         luaC_forcestep(L);  /* do a single step */
       
  1053       }
       
  1054       else {
       
  1055        lu_mem debt = cast(lu_mem, data) * 1024 - GCSTEPSIZE;
       
  1056        if (g->gcrunning)
       
  1057          debt += g->GCdebt;  /* include current debt */
       
  1058        luaE_setdebt(g, debt);
       
  1059        luaC_forcestep(L);
       
  1060        if (g->gcstate == GCSpause)  /* end of cycle? */
       
  1061          res = 1;  /* signal it */
       
  1062       }
       
  1063       break;
       
  1064     }
       
  1065     case LUA_GCSETPAUSE: {
       
  1066       res = g->gcpause;
       
  1067       g->gcpause = data;
       
  1068       break;
       
  1069     }
       
  1070     case LUA_GCSETMAJORINC: {
       
  1071       res = g->gcmajorinc;
       
  1072       g->gcmajorinc = data;
       
  1073       break;
       
  1074     }
       
  1075     case LUA_GCSETSTEPMUL: {
       
  1076       res = g->gcstepmul;
       
  1077       g->gcstepmul = data;
       
  1078       break;
       
  1079     }
       
  1080     case LUA_GCISRUNNING: {
       
  1081       res = g->gcrunning;
       
  1082       break;
       
  1083     }
       
  1084     case LUA_GCGEN: {  /* change collector to generational mode */
       
  1085       luaC_changemode(L, KGC_GEN);
       
  1086       break;
       
  1087     }
       
  1088     case LUA_GCINC: {  /* change collector to incremental mode */
       
  1089       luaC_changemode(L, KGC_NORMAL);
       
  1090       break;
       
  1091     }
       
  1092     default: res = -1;  /* invalid option */
       
  1093   }
       
  1094   lua_unlock(L);
       
  1095   return res;
       
  1096 }
       
  1097 
       
  1098 
       
  1099 
       
  1100 /*
       
  1101 ** miscellaneous functions
       
  1102 */
       
  1103 
       
  1104 
       
  1105 LUA_API int lua_error (lua_State *L) {
       
  1106   lua_lock(L);
       
  1107   api_checknelems(L, 1);
       
  1108   luaG_errormsg(L);
       
  1109   /* code unreachable; will unlock when control actually leaves the kernel */
       
  1110   return 0;  /* to avoid warnings */
       
  1111 }
       
  1112 
       
  1113 
       
  1114 LUA_API int lua_next (lua_State *L, int idx) {
       
  1115   StkId t;
       
  1116   int more;
       
  1117   lua_lock(L);
       
  1118   t = index2addr(L, idx);
       
  1119   api_check(L, ttistable(t), "table expected");
       
  1120   more = luaH_next(L, hvalue(t), L->top - 1);
       
  1121   if (more) {
       
  1122     api_incr_top(L);
       
  1123   }
       
  1124   else  /* no more elements */
       
  1125     L->top -= 1;  /* remove key */
       
  1126   lua_unlock(L);
       
  1127   return more;
       
  1128 }
       
  1129 
       
  1130 
       
  1131 LUA_API void lua_concat (lua_State *L, int n) {
       
  1132   lua_lock(L);
       
  1133   api_checknelems(L, n);
       
  1134   if (n >= 2) {
       
  1135     luaC_checkGC(L);
       
  1136     luaV_concat(L, n);
       
  1137   }
       
  1138   else if (n == 0) {  /* push empty string */
       
  1139     setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
       
  1140     api_incr_top(L);
       
  1141   }
       
  1142   /* else n == 1; nothing to do */
       
  1143   lua_unlock(L);
       
  1144 }
       
  1145 
       
  1146 
       
  1147 LUA_API void lua_len (lua_State *L, int idx) {
       
  1148   StkId t;
       
  1149   lua_lock(L);
       
  1150   t = index2addr(L, idx);
       
  1151   luaV_objlen(L, L->top, t);
       
  1152   api_incr_top(L);
       
  1153   lua_unlock(L);
       
  1154 }
       
  1155 
       
  1156 
       
  1157 LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
       
  1158   lua_Alloc f;
       
  1159   lua_lock(L);
       
  1160   if (ud) *ud = G(L)->ud;
       
  1161   f = G(L)->frealloc;
       
  1162   lua_unlock(L);
       
  1163   return f;
       
  1164 }
       
  1165 
       
  1166 
       
  1167 LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
       
  1168   lua_lock(L);
       
  1169   G(L)->ud = ud;
       
  1170   G(L)->frealloc = f;
       
  1171   lua_unlock(L);
       
  1172 }
       
  1173 
       
  1174 
       
  1175 LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
       
  1176   Udata *u;
       
  1177   lua_lock(L);
       
  1178   luaC_checkGC(L);
       
  1179   u = luaS_newudata(L, size, NULL);
       
  1180   setuvalue(L, L->top, u);
       
  1181   api_incr_top(L);
       
  1182   lua_unlock(L);
       
  1183   return u + 1;
       
  1184 }
       
  1185 
       
  1186 
       
  1187 
       
  1188 static const char *aux_upvalue (StkId fi, int n, TValue **val,
       
  1189                                 GCObject **owner) {
       
  1190   switch (ttype(fi)) {
       
  1191     case LUA_TCCL: {  /* C closure */
       
  1192       CClosure *f = clCvalue(fi);
       
  1193       if (!(1 <= n && n <= f->nupvalues)) return NULL;
       
  1194       *val = &f->upvalue[n-1];
       
  1195       if (owner) *owner = obj2gco(f);
       
  1196       return "";
       
  1197     }
       
  1198     case LUA_TLCL: {  /* Lua closure */
       
  1199       LClosure *f = clLvalue(fi);
       
  1200       TString *name;
       
  1201       Proto *p = f->p;
       
  1202       if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
       
  1203       *val = f->upvals[n-1]->v;
       
  1204       if (owner) *owner = obj2gco(f->upvals[n - 1]);
       
  1205       name = p->upvalues[n-1].name;
       
  1206       return (name == NULL) ? "" : getstr(name);
       
  1207     }
       
  1208     default: return NULL;  /* not a closure */
       
  1209   }
       
  1210 }
       
  1211 
       
  1212 
       
  1213 LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
       
  1214   const char *name;
       
  1215   TValue *val = NULL;  /* to avoid warnings */
       
  1216   lua_lock(L);
       
  1217   name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL);
       
  1218   if (name) {
       
  1219     setobj2s(L, L->top, val);
       
  1220     api_incr_top(L);
       
  1221   }
       
  1222   lua_unlock(L);
       
  1223   return name;
       
  1224 }
       
  1225 
       
  1226 
       
  1227 LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
       
  1228   const char *name;
       
  1229   TValue *val = NULL;  /* to avoid warnings */
       
  1230   GCObject *owner = NULL;  /* to avoid warnings */
       
  1231   StkId fi;
       
  1232   lua_lock(L);
       
  1233   fi = index2addr(L, funcindex);
       
  1234   api_checknelems(L, 1);
       
  1235   name = aux_upvalue(fi, n, &val, &owner);
       
  1236   if (name) {
       
  1237     L->top--;
       
  1238     setobj(L, val, L->top);
       
  1239     luaC_barrier(L, owner, L->top);
       
  1240   }
       
  1241   lua_unlock(L);
       
  1242   return name;
       
  1243 }
       
  1244 
       
  1245 
       
  1246 static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
       
  1247   LClosure *f;
       
  1248   StkId fi = index2addr(L, fidx);
       
  1249   api_check(L, ttisLclosure(fi), "Lua function expected");
       
  1250   f = clLvalue(fi);
       
  1251   api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
       
  1252   if (pf) *pf = f;
       
  1253   return &f->upvals[n - 1];  /* get its upvalue pointer */
       
  1254 }
       
  1255 
       
  1256 
       
  1257 LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
       
  1258   StkId fi = index2addr(L, fidx);
       
  1259   switch (ttype(fi)) {
       
  1260     case LUA_TLCL: {  /* lua closure */
       
  1261       return *getupvalref(L, fidx, n, NULL);
       
  1262     }
       
  1263     case LUA_TCCL: {  /* C closure */
       
  1264       CClosure *f = clCvalue(fi);
       
  1265       api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index");
       
  1266       return &f->upvalue[n - 1];
       
  1267     }
       
  1268     default: {
       
  1269       api_check(L, 0, "closure expected");
       
  1270       return NULL;
       
  1271     }
       
  1272   }
       
  1273 }
       
  1274 
       
  1275 
       
  1276 LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
       
  1277                                             int fidx2, int n2) {
       
  1278   LClosure *f1;
       
  1279   UpVal **up1 = getupvalref(L, fidx1, n1, &f1);
       
  1280   UpVal **up2 = getupvalref(L, fidx2, n2, NULL);
       
  1281   *up1 = *up2;
       
  1282   luaC_objbarrier(L, f1, *up2);
       
  1283 }
       
  1284