1/*
   2** $Id: lapi.c $
   3** Lua API
   4** See Copyright Notice in lua.h
   5*/
   6
   7#define lapi_c
   8#define LUA_CORE
   9
  10#include "lprefix.h"
  11
  12
  13#include <limits.h>
  14#include <stdarg.h>
  15#include <string.h>
  16
  17#include "lua.h"
  18
  19#include "lapi.h"
  20#include "ldebug.h"
  21#include "ldo.h"
  22#include "lfunc.h"
  23#include "lgc.h"
  24#include "lmem.h"
  25#include "lobject.h"
  26#include "lstate.h"
  27#include "lstring.h"
  28#include "ltable.h"
  29#include "ltm.h"
  30#include "lundump.h"
  31#include "lvm.h"
  32
  33
  34
  35const char lua_ident[] =
  36  "$LuaVersion: " LUA_COPYRIGHT " $"
  37  "$LuaAuthors: " LUA_AUTHORS " $";
  38
  39
  40
  41/*
  42** Test for a valid index (one that is not the 'nilvalue').
  43** '!ttisnil(o)' implies 'o != &G(L)->nilvalue', so it is not needed.
  44** However, it covers the most common cases in a faster way.
  45*/
  46#define isvalid(L, o)	(!ttisnil(o) || o != &G(L)->nilvalue)
  47
  48
  49/* test for pseudo index */
  50#define ispseudo(i)		((i) <= LUA_REGISTRYINDEX)
  51
  52/* test for upvalue */
  53#define isupvalue(i)		((i) < LUA_REGISTRYINDEX)
  54
  55
  56/*
  57** Convert an acceptable index to a pointer to its respective value.
  58** Non-valid indices return the special nil value 'G(L)->nilvalue'.
  59*/
  60static TValue *index2value (lua_State *L, int idx) {
  61  CallInfo *ci = L->ci;
  62  if (idx > 0) {
  63    StkId o = ci->func.p + idx;
  64    api_check(L, idx <= ci->top.p - (ci->func.p + 1), "unacceptable index");
  65    if (o >= L->top.p) return &G(L)->nilvalue;
  66    else return s2v(o);
  67  }
  68  else if (!ispseudo(idx)) {  /* negative index */
  69    api_check(L, idx != 0 && -idx <= L->top.p - (ci->func.p + 1),
  70                 "invalid index");
  71    return s2v(L->top.p + idx);
  72  }
  73  else if (idx == LUA_REGISTRYINDEX)
  74    return &G(L)->l_registry;
  75  else {  /* upvalues */
  76    idx = LUA_REGISTRYINDEX - idx;
  77    api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
  78    if (ttisCclosure(s2v(ci->func.p))) {  /* C closure? */
  79      CClosure *func = clCvalue(s2v(ci->func.p));
  80      return (idx <= func->nupvalues) ? &func->upvalue[idx-1]
  81                                      : &G(L)->nilvalue;
  82    }
  83    else {  /* light C function or Lua function (through a hook)?) */
  84      api_check(L, ttislcf(s2v(ci->func.p)), "caller not a C function");
  85      return &G(L)->nilvalue;  /* no upvalues */
  86    }
  87  }
  88}
  89
  90
  91
  92/*
  93** Convert a valid actual index (not a pseudo-index) to its address.
  94*/
  95l_sinline StkId index2stack (lua_State *L, int idx) {
  96  CallInfo *ci = L->ci;
  97  if (idx > 0) {
  98    StkId o = ci->func.p + idx;
  99    api_check(L, o < L->top.p, "invalid index");
 100    return o;
 101  }
 102  else {    /* non-positive index */
 103    api_check(L, idx != 0 && -idx <= L->top.p - (ci->func.p + 1),
 104                 "invalid index");
 105    api_check(L, !ispseudo(idx), "invalid index");
 106    return L->top.p + idx;
 107  }
 108}
 109
 110
 111LUA_API int lua_checkstack (lua_State *L, int n) {
 112  int res;
 113  CallInfo *ci;
 114  lua_lock(L);
 115  ci = L->ci;
 116  api_check(L, n >= 0, "negative 'n'");
 117  if (L->stack_last.p - L->top.p > n)  /* stack large enough? */
 118    res = 1;  /* yes; check is OK */
 119  else  /* need to grow stack */
 120    res = luaD_growstack(L, n, 0);
 121  if (res && ci->top.p < L->top.p + n)
 122    ci->top.p = L->top.p + n;  /* adjust frame top */
 123  lua_unlock(L);
 124  return res;
 125}
 126
 127
 128LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
 129  int i;
 130  if (from == to) return;
 131  lua_lock(to);
 132  api_checknelems(from, n);
 133  api_check(from, G(from) == G(to), "moving among independent states");
 134  api_check(from, to->ci->top.p - to->top.p >= n, "stack overflow");
 135  from->top.p -= n;
 136  for (i = 0; i < n; i++) {
 137    setobjs2s(to, to->top.p, from->top.p + i);
 138    to->top.p++;  /* stack already checked by previous 'api_check' */
 139  }
 140  lua_unlock(to);
 141}
 142
 143
 144LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
 145  lua_CFunction old;
 146  lua_lock(L);
 147  old = G(L)->panic;
 148  G(L)->panic = panicf;
 149  lua_unlock(L);
 150  return old;
 151}
 152
 153
 154LUA_API lua_Number lua_version (lua_State *L) {
 155  UNUSED(L);
 156  return LUA_VERSION_NUM;
 157}
 158
 159
 160
 161/*
 162** basic stack manipulation
 163*/
 164
 165
 166/*
 167** convert an acceptable stack index into an absolute index
 168*/
 169LUA_API int lua_absindex (lua_State *L, int idx) {
 170  return (idx > 0 || ispseudo(idx))
 171         ? idx
 172         : cast_int(L->top.p - L->ci->func.p) + idx;
 173}
 174
 175
 176LUA_API int lua_gettop (lua_State *L) {
 177  return cast_int(L->top.p - (L->ci->func.p + 1));
 178}
 179
 180
 181LUA_API void lua_settop (lua_State *L, int idx) {
 182  CallInfo *ci;
 183  StkId func, newtop;
 184  ptrdiff_t diff;  /* difference for new top */
 185  lua_lock(L);
 186  ci = L->ci;
 187  func = ci->func.p;
 188  if (idx >= 0) {
 189    api_check(L, idx <= ci->top.p - (func + 1), "new top too large");
 190    diff = ((func + 1) + idx) - L->top.p;
 191    for (; diff > 0; diff--)
 192      setnilvalue(s2v(L->top.p++));  /* clear new slots */
 193  }
 194  else {
 195    api_check(L, -(idx+1) <= (L->top.p - (func + 1)), "invalid new top");
 196    diff = idx + 1;  /* will "subtract" index (as it is negative) */
 197  }
 198  api_check(L, L->tbclist.p < L->top.p, "previous pop of an unclosed slot");
 199  newtop = L->top.p + diff;
 200  if (diff < 0 && L->tbclist.p >= newtop) {
 201    lua_assert(hastocloseCfunc(ci->nresults));
 202    newtop = luaF_close(L, newtop, CLOSEKTOP, 0);
 203  }
 204  L->top.p = newtop;  /* correct top only after closing any upvalue */
 205  lua_unlock(L);
 206}
 207
 208
 209LUA_API void lua_closeslot (lua_State *L, int idx) {
 210  StkId level;
 211  lua_lock(L);
 212  level = index2stack(L, idx);
 213  api_check(L, hastocloseCfunc(L->ci->nresults) && L->tbclist.p == level,
 214     "no variable to close at given level");
 215  level = luaF_close(L, level, CLOSEKTOP, 0);
 216  setnilvalue(s2v(level));
 217  lua_unlock(L);
 218}
 219
 220
 221/*
 222** Reverse the stack segment from 'from' to 'to'
 223** (auxiliary to 'lua_rotate')
 224** Note that we move(copy) only the value inside the stack.
 225** (We do not move additional fields that may exist.)
 226*/
 227l_sinline void reverse (lua_State *L, StkId from, StkId to) {
 228  for (; from < to; from++, to--) {
 229    TValue temp;
 230    setobj(L, &temp, s2v(from));
 231    setobjs2s(L, from, to);
 232    setobj2s(L, to, &temp);
 233  }
 234}
 235
 236
 237/*
 238** Let x = AB, where A is a prefix of length 'n'. Then,
 239** rotate x n == BA. But BA == (A^r . B^r)^r.
 240*/
 241LUA_API void lua_rotate (lua_State *L, int idx, int n) {
 242  StkId p, t, m;
 243  lua_lock(L);
 244  t = L->top.p - 1;  /* end of stack segment being rotated */
 245  p = index2stack(L, idx);  /* start of segment */
 246  api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
 247  m = (n >= 0 ? t - n : p - n - 1);  /* end of prefix */
 248  reverse(L, p, m);  /* reverse the prefix with length 'n' */
 249  reverse(L, m + 1, t);  /* reverse the suffix */
 250  reverse(L, p, t);  /* reverse the entire segment */
 251  lua_unlock(L);
 252}
 253
 254
 255LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
 256  TValue *fr, *to;
 257  lua_lock(L);
 258  fr = index2value(L, fromidx);
 259  to = index2value(L, toidx);
 260  api_check(L, isvalid(L, to), "invalid index");
 261  setobj(L, to, fr);
 262  if (isupvalue(toidx))  /* function upvalue? */
 263    luaC_barrier(L, clCvalue(s2v(L->ci->func.p)), fr);
 264  /* LUA_REGISTRYINDEX does not need gc barrier
 265     (collector revisits it before finishing collection) */
 266  lua_unlock(L);
 267}
 268
 269
 270LUA_API void lua_pushvalue (lua_State *L, int idx) {
 271  lua_lock(L);
 272  setobj2s(L, L->top.p, index2value(L, idx));
 273  api_incr_top(L);
 274  lua_unlock(L);
 275}
 276
 277
 278
 279/*
 280** access functions (stack -> C)
 281*/
 282
 283
 284LUA_API int lua_type (lua_State *L, int idx) {
 285  const TValue *o = index2value(L, idx);
 286  return (isvalid(L, o) ? ttype(o) : LUA_TNONE);
 287}
 288
 289
 290LUA_API const char *lua_typename (lua_State *L, int t) {
 291  UNUSED(L);
 292  api_check(L, LUA_TNONE <= t && t < LUA_NUMTYPES, "invalid type");
 293  return ttypename(t);
 294}
 295
 296
 297LUA_API int lua_iscfunction (lua_State *L, int idx) {
 298  const TValue *o = index2value(L, idx);
 299  return (ttislcf(o) || (ttisCclosure(o)));
 300}
 301
 302
 303LUA_API int lua_isinteger (lua_State *L, int idx) {
 304  const TValue *o = index2value(L, idx);
 305  return ttisinteger(o);
 306}
 307
 308
 309LUA_API int lua_isnumber (lua_State *L, int idx) {
 310  lua_Number n;
 311  const TValue *o = index2value(L, idx);
 312  return tonumber(o, &n);
 313}
 314
 315
 316LUA_API int lua_isstring (lua_State *L, int idx) {
 317  const TValue *o = index2value(L, idx);
 318  return (ttisstring(o) || cvt2str(o));
 319}
 320
 321
 322LUA_API int lua_isuserdata (lua_State *L, int idx) {
 323  const TValue *o = index2value(L, idx);
 324  return (ttisfulluserdata(o) || ttislightuserdata(o));
 325}
 326
 327
 328LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
 329  const TValue *o1 = index2value(L, index1);
 330  const TValue *o2 = index2value(L, index2);
 331  return (isvalid(L, o1) && isvalid(L, o2)) ? luaV_rawequalobj(o1, o2) : 0;
 332}
 333
 334
 335LUA_API void lua_arith (lua_State *L, int op) {
 336  lua_lock(L);
 337  if (op != LUA_OPUNM && op != LUA_OPBNOT)
 338    api_checknelems(L, 2);  /* all other operations expect two operands */
 339  else {  /* for unary operations, add fake 2nd operand */
 340    api_checknelems(L, 1);
 341    setobjs2s(L, L->top.p, L->top.p - 1);
 342    api_incr_top(L);
 343  }
 344  /* first operand at top - 2, second at top - 1; result go to top - 2 */
 345  luaO_arith(L, op, s2v(L->top.p - 2), s2v(L->top.p - 1), L->top.p - 2);
 346  L->top.p--;  /* remove second operand */
 347  lua_unlock(L);
 348}
 349
 350
 351LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
 352  const TValue *o1;
 353  const TValue *o2;
 354  int i = 0;
 355  lua_lock(L);  /* may call tag method */
 356  o1 = index2value(L, index1);
 357  o2 = index2value(L, index2);
 358  if (isvalid(L, o1) && isvalid(L, o2)) {
 359    switch (op) {
 360      case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break;
 361      case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
 362      case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
 363      default: api_check(L, 0, "invalid option");
 364    }
 365  }
 366  lua_unlock(L);
 367  return i;
 368}
 369
 370
 371LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
 372  size_t sz = luaO_str2num(s, s2v(L->top.p));
 373  if (sz != 0)
 374    api_incr_top(L);
 375  return sz;
 376}
 377
 378
 379LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) {
 380  lua_Number n = 0;
 381  const TValue *o = index2value(L, idx);
 382  int isnum = tonumber(o, &n);
 383  if (pisnum)
 384    *pisnum = isnum;
 385  return n;
 386}
 387
 388
 389LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) {
 390  lua_Integer res = 0;
 391  const TValue *o = index2value(L, idx);
 392  int isnum = tointeger(o, &res);
 393  if (pisnum)
 394    *pisnum = isnum;
 395  return res;
 396}
 397
 398
 399LUA_API int lua_toboolean (lua_State *L, int idx) {
 400  const TValue *o = index2value(L, idx);
 401  return !l_isfalse(o);
 402}
 403
 404
 405LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
 406  TValue *o;
 407  lua_lock(L);
 408  o = index2value(L, idx);
 409  if (!ttisstring(o)) {
 410    if (!cvt2str(o)) {  /* not convertible? */
 411      if (len != NULL) *len = 0;
 412      lua_unlock(L);
 413      return NULL;
 414    }
 415    luaO_tostring(L, o);
 416    luaC_checkGC(L);
 417    o = index2value(L, idx);  /* previous call may reallocate the stack */
 418  }
 419  if (len != NULL)
 420    *len = tsslen(tsvalue(o));
 421  lua_unlock(L);
 422  return getstr(tsvalue(o));
 423}
 424
 425
 426LUA_API lua_Unsigned lua_rawlen (lua_State *L, int idx) {
 427  const TValue *o = index2value(L, idx);
 428  switch (ttypetag(o)) {
 429    case LUA_VSHRSTR: return tsvalue(o)->shrlen;
 430    case LUA_VLNGSTR: return tsvalue(o)->u.lnglen;
 431    case LUA_VUSERDATA: return uvalue(o)->len;
 432    case LUA_VTABLE: return luaH_getn(hvalue(o));
 433    default: return 0;
 434  }
 435}
 436
 437
 438LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
 439  const TValue *o = index2value(L, idx);
 440  if (ttislcf(o)) return fvalue(o);
 441  else if (ttisCclosure(o))
 442    return clCvalue(o)->f;
 443  else return NULL;  /* not a C function */
 444}
 445
 446
 447l_sinline void *touserdata (const TValue *o) {
 448  switch (ttype(o)) {
 449    case LUA_TUSERDATA: return getudatamem(uvalue(o));
 450    case LUA_TLIGHTUSERDATA: return pvalue(o);
 451    default: return NULL;
 452  }
 453}
 454
 455
 456LUA_API void *lua_touserdata (lua_State *L, int idx) {
 457  const TValue *o = index2value(L, idx);
 458  return touserdata(o);
 459}
 460
 461
 462LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
 463  const TValue *o = index2value(L, idx);
 464  return (!ttisthread(o)) ? NULL : thvalue(o);
 465}
 466
 467
 468/*
 469** Returns a pointer to the internal representation of an object.
 470** Note that ANSI C does not allow the conversion of a pointer to
 471** function to a 'void*', so the conversion here goes through
 472** a 'size_t'. (As the returned pointer is only informative, this
 473** conversion should not be a problem.)
 474*/
 475LUA_API const void *lua_topointer (lua_State *L, int idx) {
 476  const TValue *o = index2value(L, idx);
 477  switch (ttypetag(o)) {
 478    case LUA_VLCF: return cast_voidp(cast_sizet(fvalue(o)));
 479    case LUA_VUSERDATA: case LUA_VLIGHTUSERDATA:
 480      return touserdata(o);
 481    default: {
 482      if (iscollectable(o))
 483        return gcvalue(o);
 484      else
 485        return NULL;
 486    }
 487  }
 488}
 489
 490
 491
 492/*
 493** push functions (C -> stack)
 494*/
 495
 496
 497LUA_API void lua_pushnil (lua_State *L) {
 498  lua_lock(L);
 499  setnilvalue(s2v(L->top.p));
 500  api_incr_top(L);
 501  lua_unlock(L);
 502}
 503
 504
 505LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
 506  lua_lock(L);
 507  setfltvalue(s2v(L->top.p), n);
 508  api_incr_top(L);
 509  lua_unlock(L);
 510}
 511
 512
 513LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
 514  lua_lock(L);
 515  setivalue(s2v(L->top.p), n);
 516  api_incr_top(L);
 517  lua_unlock(L);
 518}
 519
 520
 521/*
 522** Pushes on the stack a string with given length. Avoid using 's' when
 523** 'len' == 0 (as 's' can be NULL in that case), due to later use of
 524** 'memcmp' and 'memcpy'.
 525*/
 526LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
 527  TString *ts;
 528  lua_lock(L);
 529  ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len);
 530  setsvalue2s(L, L->top.p, ts);
 531  api_incr_top(L);
 532  luaC_checkGC(L);
 533  lua_unlock(L);
 534  return getstr(ts);
 535}
 536
 537
 538LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
 539  lua_lock(L);
 540  if (s == NULL)
 541    setnilvalue(s2v(L->top.p));
 542  else {
 543    TString *ts;
 544    ts = luaS_new(L, s);
 545    setsvalue2s(L, L->top.p, ts);
 546    s = getstr(ts);  /* internal copy's address */
 547  }
 548  api_incr_top(L);
 549  luaC_checkGC(L);
 550  lua_unlock(L);
 551  return s;
 552}
 553
 554
 555LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
 556                                      va_list argp) {
 557  const char *ret;
 558  lua_lock(L);
 559  ret = luaO_pushvfstring(L, fmt, argp);
 560  luaC_checkGC(L);
 561  lua_unlock(L);
 562  return ret;
 563}
 564
 565
 566LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
 567  const char *ret;
 568  va_list argp;
 569  lua_lock(L);
 570  va_start(argp, fmt);
 571  ret = luaO_pushvfstring(L, fmt, argp);
 572  va_end(argp);
 573  luaC_checkGC(L);
 574  lua_unlock(L);
 575  return ret;
 576}
 577
 578
 579LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
 580  lua_lock(L);
 581  if (n == 0) {
 582    setfvalue(s2v(L->top.p), fn);
 583    api_incr_top(L);
 584  }
 585  else {
 586    CClosure *cl;
 587    api_checknelems(L, n);
 588    api_check(L, n <= MAXUPVAL, "upvalue index too large");
 589    cl = luaF_newCclosure(L, n);
 590    cl->f = fn;
 591    L->top.p -= n;
 592    while (n--) {
 593      setobj2n(L, &cl->upvalue[n], s2v(L->top.p + n));
 594      /* does not need barrier because closure is white */
 595      lua_assert(iswhite(cl));
 596    }
 597    setclCvalue(L, s2v(L->top.p), cl);
 598    api_incr_top(L);
 599    luaC_checkGC(L);
 600  }
 601  lua_unlock(L);
 602}
 603
 604
 605LUA_API void lua_pushboolean (lua_State *L, int b) {
 606  lua_lock(L);
 607  if (b)
 608    setbtvalue(s2v(L->top.p));
 609  else
 610    setbfvalue(s2v(L->top.p));
 611  api_incr_top(L);
 612  lua_unlock(L);
 613}
 614
 615
 616LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
 617  lua_lock(L);
 618  setpvalue(s2v(L->top.p), p);
 619  api_incr_top(L);
 620  lua_unlock(L);
 621}
 622
 623
 624LUA_API int lua_pushthread (lua_State *L) {
 625  lua_lock(L);
 626  setthvalue(L, s2v(L->top.p), L);
 627  api_incr_top(L);
 628  lua_unlock(L);
 629  return (G(L)->mainthread == L);
 630}
 631
 632
 633
 634/*
 635** get functions (Lua -> stack)
 636*/
 637
 638
 639l_sinline int auxgetstr (lua_State *L, const TValue *t, const char *k) {
 640  const TValue *slot;
 641  TString *str = luaS_new(L, k);
 642  if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
 643    setobj2s(L, L->top.p, slot);
 644    api_incr_top(L);
 645  }
 646  else {
 647    setsvalue2s(L, L->top.p, str);
 648    api_incr_top(L);
 649    luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, slot);
 650  }
 651  lua_unlock(L);
 652  return ttype(s2v(L->top.p - 1));
 653}
 654
 655
 656/*
 657** Get the global table in the registry. Since all predefined
 658** indices in the registry were inserted right when the registry
 659** was created and never removed, they must always be in the array
 660** part of the registry.
 661*/
 662#define getGtable(L)  \
 663	(&hvalue(&G(L)->l_registry)->array[LUA_RIDX_GLOBALS - 1])
 664
 665
 666LUA_API int lua_getglobal (lua_State *L, const char *name) {
 667  const TValue *G;
 668  lua_lock(L);
 669  G = getGtable(L);
 670  return auxgetstr(L, G, name);
 671}
 672
 673
 674LUA_API int lua_gettable (lua_State *L, int idx) {
 675  const TValue *slot;
 676  TValue *t;
 677  lua_lock(L);
 678  t = index2value(L, idx);
 679  if (luaV_fastget(L, t, s2v(L->top.p - 1), slot, luaH_get)) {
 680    setobj2s(L, L->top.p - 1, slot);
 681  }
 682  else
 683    luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, slot);
 684  lua_unlock(L);
 685  return ttype(s2v(L->top.p - 1));
 686}
 687
 688
 689LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
 690  lua_lock(L);
 691  return auxgetstr(L, index2value(L, idx), k);
 692}
 693
 694
 695LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
 696  TValue *t;
 697  const TValue *slot;
 698  lua_lock(L);
 699  t = index2value(L, idx);
 700  if (luaV_fastgeti(L, t, n, slot)) {
 701    setobj2s(L, L->top.p, slot);
 702  }
 703  else {
 704    TValue aux;
 705    setivalue(&aux, n);
 706    luaV_finishget(L, t, &aux, L->top.p, slot);
 707  }
 708  api_incr_top(L);
 709  lua_unlock(L);
 710  return ttype(s2v(L->top.p - 1));
 711}
 712
 713
 714l_sinline int finishrawget (lua_State *L, const TValue *val) {
 715  if (isempty(val))  /* avoid copying empty items to the stack */
 716    setnilvalue(s2v(L->top.p));
 717  else
 718    setobj2s(L, L->top.p, val);
 719  api_incr_top(L);
 720  lua_unlock(L);
 721  return ttype(s2v(L->top.p - 1));
 722}
 723
 724
 725static Table *gettable (lua_State *L, int idx) {
 726  TValue *t = index2value(L, idx);
 727  api_check(L, ttistable(t), "table expected");
 728  return hvalue(t);
 729}
 730
 731
 732LUA_API int lua_rawget (lua_State *L, int idx) {
 733  Table *t;
 734  const TValue *val;
 735  lua_lock(L);
 736  api_checknelems(L, 1);
 737  t = gettable(L, idx);
 738  val = luaH_get(t, s2v(L->top.p - 1));
 739  L->top.p--;  /* remove key */
 740  return finishrawget(L, val);
 741}
 742
 743
 744LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
 745  Table *t;
 746  lua_lock(L);
 747  t = gettable(L, idx);
 748  return finishrawget(L, luaH_getint(t, n));
 749}
 750
 751
 752LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
 753  Table *t;
 754  TValue k;
 755  lua_lock(L);
 756  t = gettable(L, idx);
 757  setpvalue(&k, cast_voidp(p));
 758  return finishrawget(L, luaH_get(t, &k));
 759}
 760
 761
 762LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
 763  Table *t;
 764  lua_lock(L);
 765  t = luaH_new(L);
 766  sethvalue2s(L, L->top.p, t);
 767  api_incr_top(L);
 768  if (narray > 0 || nrec > 0)
 769    luaH_resize(L, t, narray, nrec);
 770  luaC_checkGC(L);
 771  lua_unlock(L);
 772}
 773
 774
 775LUA_API int lua_getmetatable (lua_State *L, int objindex) {
 776  const TValue *obj;
 777  Table *mt;
 778  int res = 0;
 779  lua_lock(L);
 780  obj = index2value(L, objindex);
 781  switch (ttype(obj)) {
 782    case LUA_TTABLE:
 783      mt = hvalue(obj)->metatable;
 784      break;
 785    case LUA_TUSERDATA:
 786      mt = uvalue(obj)->metatable;
 787      break;
 788    default:
 789      mt = G(L)->mt[ttype(obj)];
 790      break;
 791  }
 792  if (mt != NULL) {
 793    sethvalue2s(L, L->top.p, mt);
 794    api_incr_top(L);
 795    res = 1;
 796  }
 797  lua_unlock(L);
 798  return res;
 799}
 800
 801
 802LUA_API int lua_getiuservalue (lua_State *L, int idx, int n) {
 803  TValue *o;
 804  int t;
 805  lua_lock(L);
 806  o = index2value(L, idx);
 807  api_check(L, ttisfulluserdata(o), "full userdata expected");
 808  if (n <= 0 || n > uvalue(o)->nuvalue) {
 809    setnilvalue(s2v(L->top.p));
 810    t = LUA_TNONE;
 811  }
 812  else {
 813    setobj2s(L, L->top.p, &uvalue(o)->uv[n - 1].uv);
 814    t = ttype(s2v(L->top.p));
 815  }
 816  api_incr_top(L);
 817  lua_unlock(L);
 818  return t;
 819}
 820
 821
 822/*
 823** set functions (stack -> Lua)
 824*/
 825
 826/*
 827** t[k] = value at the top of the stack (where 'k' is a string)
 828*/
 829static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
 830  const TValue *slot;
 831  TString *str = luaS_new(L, k);
 832  api_checknelems(L, 1);
 833  if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
 834    luaV_finishfastset(L, t, slot, s2v(L->top.p - 1));
 835    L->top.p--;  /* pop value */
 836  }
 837  else {
 838    setsvalue2s(L, L->top.p, str);  /* push 'str' (to make it a TValue) */
 839    api_incr_top(L);
 840    luaV_finishset(L, t, s2v(L->top.p - 1), s2v(L->top.p - 2), slot);
 841    L->top.p -= 2;  /* pop value and key */
 842  }
 843  lua_unlock(L);  /* lock done by caller */
 844}
 845
 846
 847LUA_API void lua_setglobal (lua_State *L, const char *name) {
 848  const TValue *G;
 849  lua_lock(L);  /* unlock done in 'auxsetstr' */
 850  G = getGtable(L);
 851  auxsetstr(L, G, name);
 852}
 853
 854
 855LUA_API void lua_settable (lua_State *L, int idx) {
 856  TValue *t;
 857  const TValue *slot;
 858  lua_lock(L);
 859  api_checknelems(L, 2);
 860  t = index2value(L, idx);
 861  if (luaV_fastget(L, t, s2v(L->top.p - 2), slot, luaH_get)) {
 862    luaV_finishfastset(L, t, slot, s2v(L->top.p - 1));
 863  }
 864  else
 865    luaV_finishset(L, t, s2v(L->top.p - 2), s2v(L->top.p - 1), slot);
 866  L->top.p -= 2;  /* pop index and value */
 867  lua_unlock(L);
 868}
 869
 870
 871LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
 872  lua_lock(L);  /* unlock done in 'auxsetstr' */
 873  auxsetstr(L, index2value(L, idx), k);
 874}
 875
 876
 877LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
 878  TValue *t;
 879  const TValue *slot;
 880  lua_lock(L);
 881  api_checknelems(L, 1);
 882  t = index2value(L, idx);
 883  if (luaV_fastgeti(L, t, n, slot)) {
 884    luaV_finishfastset(L, t, slot, s2v(L->top.p - 1));
 885  }
 886  else {
 887    TValue aux;
 888    setivalue(&aux, n);
 889    luaV_finishset(L, t, &aux, s2v(L->top.p - 1), slot);
 890  }
 891  L->top.p--;  /* pop value */
 892  lua_unlock(L);
 893}
 894
 895
 896static void aux_rawset (lua_State *L, int idx, TValue *key, int n) {
 897  Table *t;
 898  lua_lock(L);
 899  api_checknelems(L, n);
 900  t = gettable(L, idx);
 901  luaH_set(L, t, key, s2v(L->top.p - 1));
 902  invalidateTMcache(t);
 903  luaC_barrierback(L, obj2gco(t), s2v(L->top.p - 1));
 904  L->top.p -= n;
 905  lua_unlock(L);
 906}
 907
 908
 909LUA_API void lua_rawset (lua_State *L, int idx) {
 910  aux_rawset(L, idx, s2v(L->top.p - 2), 2);
 911}
 912
 913
 914LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
 915  TValue k;
 916  setpvalue(&k, cast_voidp(p));
 917  aux_rawset(L, idx, &k, 1);
 918}
 919
 920
 921LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
 922  Table *t;
 923  lua_lock(L);
 924  api_checknelems(L, 1);
 925  t = gettable(L, idx);
 926  luaH_setint(L, t, n, s2v(L->top.p - 1));
 927  luaC_barrierback(L, obj2gco(t), s2v(L->top.p - 1));
 928  L->top.p--;
 929  lua_unlock(L);
 930}
 931
 932
 933LUA_API int lua_setmetatable (lua_State *L, int objindex) {
 934  TValue *obj;
 935  Table *mt;
 936  lua_lock(L);
 937  api_checknelems(L, 1);
 938  obj = index2value(L, objindex);
 939  if (ttisnil(s2v(L->top.p - 1)))
 940    mt = NULL;
 941  else {
 942    api_check(L, ttistable(s2v(L->top.p - 1)), "table expected");
 943    mt = hvalue(s2v(L->top.p - 1));
 944  }
 945  switch (ttype(obj)) {
 946    case LUA_TTABLE: {
 947      hvalue(obj)->metatable = mt;
 948      if (mt) {
 949        luaC_objbarrier(L, gcvalue(obj), mt);
 950        luaC_checkfinalizer(L, gcvalue(obj), mt);
 951      }
 952      break;
 953    }
 954    case LUA_TUSERDATA: {
 955      uvalue(obj)->metatable = mt;
 956      if (mt) {
 957        luaC_objbarrier(L, uvalue(obj), mt);
 958        luaC_checkfinalizer(L, gcvalue(obj), mt);
 959      }
 960      break;
 961    }
 962    default: {
 963      G(L)->mt[ttype(obj)] = mt;
 964      break;
 965    }
 966  }
 967  L->top.p--;
 968  lua_unlock(L);
 969  return 1;
 970}
 971
 972
 973LUA_API int lua_setiuservalue (lua_State *L, int idx, int n) {
 974  TValue *o;
 975  int res;
 976  lua_lock(L);
 977  api_checknelems(L, 1);
 978  o = index2value(L, idx);
 979  api_check(L, ttisfulluserdata(o), "full userdata expected");
 980  if (!(cast_uint(n) - 1u < cast_uint(uvalue(o)->nuvalue)))
 981    res = 0;  /* 'n' not in [1, uvalue(o)->nuvalue] */
 982  else {
 983    setobj(L, &uvalue(o)->uv[n - 1].uv, s2v(L->top.p - 1));
 984    luaC_barrierback(L, gcvalue(o), s2v(L->top.p - 1));
 985    res = 1;
 986  }
 987  L->top.p--;
 988  lua_unlock(L);
 989  return res;
 990}
 991
 992
 993/*
 994** 'load' and 'call' functions (run Lua code)
 995*/
 996
 997
 998#define checkresults(L,na,nr) \
 999     api_check(L, (nr) == LUA_MULTRET \
1000               || (L->ci->top.p - L->top.p >= (nr) - (na)), \
1001	"results from function overflow current stack size")
1002
1003
1004LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
1005                        lua_KContext ctx, lua_KFunction k) {
1006  StkId func;
1007  lua_lock(L);
1008  api_check(L, k == NULL || !isLua(L->ci),
1009    "cannot use continuations inside hooks");
1010  api_checknelems(L, nargs+1);
1011  api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
1012  checkresults(L, nargs, nresults);
1013  func = L->top.p - (nargs+1);
1014  if (k != NULL && yieldable(L)) {  /* need to prepare continuation? */
1015    L->ci->u.c.k = k;  /* save continuation */
1016    L->ci->u.c.ctx = ctx;  /* save context */
1017    luaD_call(L, func, nresults);  /* do the call */
1018  }
1019  else  /* no continuation or no yieldable */
1020    luaD_callnoyield(L, func, nresults);  /* just do the call */
1021  adjustresults(L, nresults);
1022  lua_unlock(L);
1023}
1024
1025
1026
1027/*
1028** Execute a protected call.
1029*/
1030struct CallS {  /* data to 'f_call' */
1031  StkId func;
1032  int nresults;
1033};
1034
1035
1036static void f_call (lua_State *L, void *ud) {
1037  struct CallS *c = cast(struct CallS *, ud);
1038  luaD_callnoyield(L, c->func, c->nresults);
1039}
1040
1041
1042
1043LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
1044                        lua_KContext ctx, lua_KFunction k) {
1045  struct CallS c;
1046  int status;
1047  ptrdiff_t func;
1048  lua_lock(L);
1049  api_check(L, k == NULL || !isLua(L->ci),
1050    "cannot use continuations inside hooks");
1051  api_checknelems(L, nargs+1);
1052  api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
1053  checkresults(L, nargs, nresults);
1054  if (errfunc == 0)
1055    func = 0;
1056  else {
1057    StkId o = index2stack(L, errfunc);
1058    api_check(L, ttisfunction(s2v(o)), "error handler must be a function");
1059    func = savestack(L, o);
1060  }
1061  c.func = L->top.p - (nargs+1);  /* function to be called */
1062  if (k == NULL || !yieldable(L)) {  /* no continuation or no yieldable? */
1063    c.nresults = nresults;  /* do a 'conventional' protected call */
1064    status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
1065  }
1066  else {  /* prepare continuation (call is already protected by 'resume') */
1067    CallInfo *ci = L->ci;
1068    ci->u.c.k = k;  /* save continuation */
1069    ci->u.c.ctx = ctx;  /* save context */
1070    /* save information for error recovery */
1071    ci->u2.funcidx = cast_int(savestack(L, c.func));
1072    ci->u.c.old_errfunc = L->errfunc;
1073    L->errfunc = func;
1074    setoah(ci->callstatus, L->allowhook);  /* save value of 'allowhook' */
1075    ci->callstatus |= CIST_YPCALL;  /* function can do error recovery */
1076    luaD_call(L, c.func, nresults);  /* do the call */
1077    ci->callstatus &= ~CIST_YPCALL;
1078    L->errfunc = ci->u.c.old_errfunc;
1079    status = LUA_OK;  /* if it is here, there were no errors */
1080  }
1081  adjustresults(L, nresults);
1082  lua_unlock(L);
1083  return status;
1084}
1085
1086
1087LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
1088                      const char *chunkname, const char *mode) {
1089  ZIO z;
1090  int status;
1091  lua_lock(L);
1092  if (!chunkname) chunkname = "?";
1093  luaZ_init(L, &z, reader, data);
1094  status = luaD_protectedparser(L, &z, chunkname, mode);
1095  if (status == LUA_OK) {  /* no errors? */
1096    LClosure *f = clLvalue(s2v(L->top.p - 1));  /* get new function */
1097    if (f->nupvalues >= 1) {  /* does it have an upvalue? */
1098      /* get global table from registry */
1099      const TValue *gt = getGtable(L);
1100      /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
1101      setobj(L, f->upvals[0]->v.p, gt);
1102      luaC_barrier(L, f->upvals[0], gt);
1103    }
1104  }
1105  lua_unlock(L);
1106  return status;
1107}
1108
1109
1110LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
1111  int status;
1112  TValue *o;
1113  lua_lock(L);
1114  api_checknelems(L, 1);
1115  o = s2v(L->top.p - 1);
1116  if (isLfunction(o))
1117    status = luaU_dump(L, getproto(o), writer, data, strip);
1118  else
1119    status = 1;
1120  lua_unlock(L);
1121  return status;
1122}
1123
1124
1125LUA_API int lua_status (lua_State *L) {
1126  return L->status;
1127}
1128
1129
1130/*
1131** Garbage-collection function
1132*/
1133LUA_API int lua_gc (lua_State *L, int what, ...) {
1134  va_list argp;
1135  int res = 0;
1136  global_State *g = G(L);
1137  if (g->gcstp & GCSTPGC)  /* internal stop? */
1138    return -1;  /* all options are invalid when stopped */
1139  lua_lock(L);
1140  va_start(argp, what);
1141  switch (what) {
1142    case LUA_GCSTOP: {
1143      g->gcstp = GCSTPUSR;  /* stopped by the user */
1144      break;
1145    }
1146    case LUA_GCRESTART: {
1147      luaE_setdebt(g, 0);
1148      g->gcstp = 0;  /* (GCSTPGC must be already zero here) */
1149      break;
1150    }
1151    case LUA_GCCOLLECT: {
1152      luaC_fullgc(L, 0);
1153      break;
1154    }
1155    case LUA_GCCOUNT: {
1156      /* GC values are expressed in Kbytes: #bytes/2^10 */
1157      res = cast_int(gettotalbytes(g) >> 10);
1158      break;
1159    }
1160    case LUA_GCCOUNTB: {
1161      res = cast_int(gettotalbytes(g) & 0x3ff);
1162      break;
1163    }
1164    case LUA_GCSTEP: {
1165      int data = va_arg(argp, int);
1166      l_mem debt = 1;  /* =1 to signal that it did an actual step */
1167      lu_byte oldstp = g->gcstp;
1168      g->gcstp = 0;  /* allow GC to run (GCSTPGC must be zero here) */
1169      if (data == 0) {
1170        luaE_setdebt(g, 0);  /* do a basic step */
1171        luaC_step(L);
1172      }
1173      else {  /* add 'data' to total debt */
1174        debt = cast(l_mem, data) * 1024 + g->GCdebt;
1175        luaE_setdebt(g, debt);
1176        luaC_checkGC(L);
1177      }
1178      g->gcstp = oldstp;  /* restore previous state */
1179      if (debt > 0 && g->gcstate == GCSpause)  /* end of cycle? */
1180        res = 1;  /* signal it */
1181      break;
1182    }
1183    case LUA_GCSETPAUSE: {
1184      int data = va_arg(argp, int);
1185      res = getgcparam(g->gcpause);
1186      setgcparam(g->gcpause, data);
1187      break;
1188    }
1189    case LUA_GCSETSTEPMUL: {
1190      int data = va_arg(argp, int);
1191      res = getgcparam(g->gcstepmul);
1192      setgcparam(g->gcstepmul, data);
1193      break;
1194    }
1195    case LUA_GCISRUNNING: {
1196      res = gcrunning(g);
1197      break;
1198    }
1199    case LUA_GCGEN: {
1200      int minormul = va_arg(argp, int);
1201      int majormul = va_arg(argp, int);
1202      res = isdecGCmodegen(g) ? LUA_GCGEN : LUA_GCINC;
1203      if (minormul != 0)
1204        g->genminormul = minormul;
1205      if (majormul != 0)
1206        setgcparam(g->genmajormul, majormul);
1207      luaC_changemode(L, KGC_GEN);
1208      break;
1209    }
1210    case LUA_GCINC: {
1211      int pause = va_arg(argp, int);
1212      int stepmul = va_arg(argp, int);
1213      int stepsize = va_arg(argp, int);
1214      res = isdecGCmodegen(g) ? LUA_GCGEN : LUA_GCINC;
1215      if (pause != 0)
1216        setgcparam(g->gcpause, pause);
1217      if (stepmul != 0)
1218        setgcparam(g->gcstepmul, stepmul);
1219      if (stepsize != 0)
1220        g->gcstepsize = stepsize;
1221      luaC_changemode(L, KGC_INC);
1222      break;
1223    }
1224    default: res = -1;  /* invalid option */
1225  }
1226  va_end(argp);
1227  lua_unlock(L);
1228  return res;
1229}
1230
1231
1232
1233/*
1234** miscellaneous functions
1235*/
1236
1237
1238LUA_API int lua_error (lua_State *L) {
1239  TValue *errobj;
1240  lua_lock(L);
1241  errobj = s2v(L->top.p - 1);
1242  api_checknelems(L, 1);
1243  /* error object is the memory error message? */
1244  if (ttisshrstring(errobj) && eqshrstr(tsvalue(errobj), G(L)->memerrmsg))
1245    luaM_error(L);  /* raise a memory error */
1246  else
1247    luaG_errormsg(L);  /* raise a regular error */
1248  /* code unreachable; will unlock when control actually leaves the kernel */
1249  return 0;  /* to avoid warnings */
1250}
1251
1252
1253LUA_API int lua_next (lua_State *L, int idx) {
1254  Table *t;
1255  int more;
1256  lua_lock(L);
1257  api_checknelems(L, 1);
1258  t = gettable(L, idx);
1259  more = luaH_next(L, t, L->top.p - 1);
1260  if (more) {
1261    api_incr_top(L);
1262  }
1263  else  /* no more elements */
1264    L->top.p -= 1;  /* remove key */
1265  lua_unlock(L);
1266  return more;
1267}
1268
1269
1270LUA_API void lua_toclose (lua_State *L, int idx) {
1271  int nresults;
1272  StkId o;
1273  lua_lock(L);
1274  o = index2stack(L, idx);
1275  nresults = L->ci->nresults;
1276  api_check(L, L->tbclist.p < o, "given index below or equal a marked one");
1277  luaF_newtbcupval(L, o);  /* create new to-be-closed upvalue */
1278  if (!hastocloseCfunc(nresults))  /* function not marked yet? */
1279    L->ci->nresults = codeNresults(nresults);  /* mark it */
1280  lua_assert(hastocloseCfunc(L->ci->nresults));
1281  lua_unlock(L);
1282}
1283
1284
1285LUA_API void lua_concat (lua_State *L, int n) {
1286  lua_lock(L);
1287  api_checknelems(L, n);
1288  if (n > 0)
1289    luaV_concat(L, n);
1290  else {  /* nothing to concatenate */
1291    setsvalue2s(L, L->top.p, luaS_newlstr(L, "", 0));  /* push empty string */
1292    api_incr_top(L);
1293  }
1294  luaC_checkGC(L);
1295  lua_unlock(L);
1296}
1297
1298
1299LUA_API void lua_len (lua_State *L, int idx) {
1300  TValue *t;
1301  lua_lock(L);
1302  t = index2value(L, idx);
1303  luaV_objlen(L, L->top.p, t);
1304  api_incr_top(L);
1305  lua_unlock(L);
1306}
1307
1308
1309LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
1310  lua_Alloc f;
1311  lua_lock(L);
1312  if (ud) *ud = G(L)->ud;
1313  f = G(L)->frealloc;
1314  lua_unlock(L);
1315  return f;
1316}
1317
1318
1319LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
1320  lua_lock(L);
1321  G(L)->ud = ud;
1322  G(L)->frealloc = f;
1323  lua_unlock(L);
1324}
1325
1326
1327void lua_setwarnf (lua_State *L, lua_WarnFunction f, void *ud) {
1328  lua_lock(L);
1329  G(L)->ud_warn = ud;
1330  G(L)->warnf = f;
1331  lua_unlock(L);
1332}
1333
1334
1335void lua_warning (lua_State *L, const char *msg, int tocont) {
1336  lua_lock(L);
1337  luaE_warning(L, msg, tocont);
1338  lua_unlock(L);
1339}
1340
1341
1342
1343LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) {
1344  Udata *u;
1345  lua_lock(L);
1346  api_check(L, 0 <= nuvalue && nuvalue < USHRT_MAX, "invalid value");
1347  u = luaS_newudata(L, size, nuvalue);
1348  setuvalue(L, s2v(L->top.p), u);
1349  api_incr_top(L);
1350  luaC_checkGC(L);
1351  lua_unlock(L);
1352  return getudatamem(u);
1353}
1354
1355
1356
1357static const char *aux_upvalue (TValue *fi, int n, TValue **val,
1358                                GCObject **owner) {
1359  switch (ttypetag(fi)) {
1360    case LUA_VCCL: {  /* C closure */
1361      CClosure *f = clCvalue(fi);
1362      if (!(cast_uint(n) - 1u < cast_uint(f->nupvalues)))
1363        return NULL;  /* 'n' not in [1, f->nupvalues] */
1364      *val = &f->upvalue[n-1];
1365      if (owner) *owner = obj2gco(f);
1366      return "";
1367    }
1368    case LUA_VLCL: {  /* Lua closure */
1369      LClosure *f = clLvalue(fi);
1370      TString *name;
1371      Proto *p = f->p;
1372      if (!(cast_uint(n) - 1u  < cast_uint(p->sizeupvalues)))
1373        return NULL;  /* 'n' not in [1, p->sizeupvalues] */
1374      *val = f->upvals[n-1]->v.p;
1375      if (owner) *owner = obj2gco(f->upvals[n - 1]);
1376      name = p->upvalues[n-1].name;
1377      return (name == NULL) ? "(no name)" : getstr(name);
1378    }
1379    default: return NULL;  /* not a closure */
1380  }
1381}
1382
1383
1384LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
1385  const char *name;
1386  TValue *val = NULL;  /* to avoid warnings */
1387  lua_lock(L);
1388  name = aux_upvalue(index2value(L, funcindex), n, &val, NULL);
1389  if (name) {
1390    setobj2s(L, L->top.p, val);
1391    api_incr_top(L);
1392  }
1393  lua_unlock(L);
1394  return name;
1395}
1396
1397
1398LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
1399  const char *name;
1400  TValue *val = NULL;  /* to avoid warnings */
1401  GCObject *owner = NULL;  /* to avoid warnings */
1402  TValue *fi;
1403  lua_lock(L);
1404  fi = index2value(L, funcindex);
1405  api_checknelems(L, 1);
1406  name = aux_upvalue(fi, n, &val, &owner);
1407  if (name) {
1408    L->top.p--;
1409    setobj(L, val, s2v(L->top.p));
1410    luaC_barrier(L, owner, val);
1411  }
1412  lua_unlock(L);
1413  return name;
1414}
1415
1416
1417static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
1418  static const UpVal *const nullup = NULL;
1419  LClosure *f;
1420  TValue *fi = index2value(L, fidx);
1421  api_check(L, ttisLclosure(fi), "Lua function expected");
1422  f = clLvalue(fi);
1423  if (pf) *pf = f;
1424  if (1 <= n && n <= f->p->sizeupvalues)
1425    return &f->upvals[n - 1];  /* get its upvalue pointer */
1426  else
1427    return (UpVal**)&nullup;
1428}
1429
1430
1431LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
1432  TValue *fi = index2value(L, fidx);
1433  switch (ttypetag(fi)) {
1434    case LUA_VLCL: {  /* lua closure */
1435      return *getupvalref(L, fidx, n, NULL);
1436    }
1437    case LUA_VCCL: {  /* C closure */
1438      CClosure *f = clCvalue(fi);
1439      if (1 <= n && n <= f->nupvalues)
1440        return &f->upvalue[n - 1];
1441      /* else */
1442    }  /* FALLTHROUGH */
1443    case LUA_VLCF:
1444      return NULL;  /* light C functions have no upvalues */
1445    default: {
1446      api_check(L, 0, "function expected");
1447      return NULL;
1448    }
1449  }
1450}
1451
1452
1453LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
1454                                            int fidx2, int n2) {
1455  LClosure *f1;
1456  UpVal **up1 = getupvalref(L, fidx1, n1, &f1);
1457  UpVal **up2 = getupvalref(L, fidx2, n2, NULL);
1458  api_check(L, *up1 != NULL && *up2 != NULL, "invalid upvalue index");
1459  *up1 = *up2;
1460  luaC_objbarrier(L, f1, *up1);
1461}
1462
1463