PageRenderTime 92ms CodeModel.GetById 9ms app.highlight 76ms RepoModel.GetById 1ms app.codeStats 1ms

/src/middleware/lua/lapi.c

https://bitbucket.org/vivkin/gam3b00bs/
C | 1087 lines | 853 code | 196 blank | 38 comment | 109 complexity | 2751d5c9103e098a6eb4850009a6a205 MD5 | raw file
   1/*
   2** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $
   3** Lua API
   4** See Copyright Notice in lua.h
   5*/
   6
   7
   8#include <assert.h>
   9#include <math.h>
  10#include <stdarg.h>
  11#include <string.h>
  12
  13#define lapi_c
  14#define LUA_CORE
  15
  16#include "lua.h"
  17
  18#include "lapi.h"
  19#include "ldebug.h"
  20#include "ldo.h"
  21#include "lfunc.h"
  22#include "lgc.h"
  23#include "lmem.h"
  24#include "lobject.h"
  25#include "lstate.h"
  26#include "lstring.h"
  27#include "ltable.h"
  28#include "ltm.h"
  29#include "lundump.h"
  30#include "lvm.h"
  31
  32
  33
  34const char lua_ident[] =
  35  "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n"
  36  "$Authors: " LUA_AUTHORS " $\n"
  37  "$URL: www.lua.org $\n";
  38
  39
  40
  41#define api_checknelems(L, n)	api_check(L, (n) <= (L->top - L->base))
  42
  43#define api_checkvalidindex(L, i)	api_check(L, (i) != luaO_nilobject)
  44
  45#define api_incr_top(L)   {api_check(L, L->top < L->ci->top); L->top++;}
  46
  47
  48
  49static TValue *index2adr (lua_State *L, int idx) {
  50  if (idx > 0) {
  51    TValue *o = L->base + (idx - 1);
  52    api_check(L, idx <= L->ci->top - L->base);
  53    if (o >= L->top) return cast(TValue *, luaO_nilobject);
  54    else return o;
  55  }
  56  else if (idx > LUA_REGISTRYINDEX) {
  57    api_check(L, idx != 0 && -idx <= L->top - L->base);
  58    return L->top + idx;
  59  }
  60  else switch (idx) {  /* pseudo-indices */
  61    case LUA_REGISTRYINDEX: return registry(L);
  62    case LUA_ENVIRONINDEX: {
  63      Closure *func = curr_func(L);
  64      sethvalue(L, &L->env, func->c.env);
  65      return &L->env;
  66    }
  67    case LUA_GLOBALSINDEX: return gt(L);
  68    default: {
  69      Closure *func = curr_func(L);
  70      idx = LUA_GLOBALSINDEX - idx;
  71      return (idx <= func->c.nupvalues)
  72                ? &func->c.upvalue[idx-1]
  73                : cast(TValue *, luaO_nilobject);
  74    }
  75  }
  76}
  77
  78
  79static Table *getcurrenv (lua_State *L) {
  80  if (L->ci == L->base_ci)  /* no enclosing function? */
  81    return hvalue(gt(L));  /* use global table as environment */
  82  else {
  83    Closure *func = curr_func(L);
  84    return func->c.env;
  85  }
  86}
  87
  88
  89void luaA_pushobject (lua_State *L, const TValue *o) {
  90  setobj2s(L, L->top, o);
  91  api_incr_top(L);
  92}
  93
  94
  95LUA_API int lua_checkstack (lua_State *L, int size) {
  96  int res = 1;
  97  lua_lock(L);
  98  if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK)
  99    res = 0;  /* stack overflow */
 100  else if (size > 0) {
 101    luaD_checkstack(L, size);
 102    if (L->ci->top < L->top + size)
 103      L->ci->top = L->top + size;
 104  }
 105  lua_unlock(L);
 106  return res;
 107}
 108
 109
 110LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
 111  int i;
 112  if (from == to) return;
 113  lua_lock(to);
 114  api_checknelems(from, n);
 115  api_check(from, G(from) == G(to));
 116  api_check(from, to->ci->top - to->top >= n);
 117  from->top -= n;
 118  for (i = 0; i < n; i++) {
 119    setobj2s(to, to->top++, from->top + i);
 120  }
 121  lua_unlock(to);
 122}
 123
 124
 125LUA_API void lua_setlevel (lua_State *from, lua_State *to) {
 126  to->nCcalls = from->nCcalls;
 127}
 128
 129
 130LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
 131  lua_CFunction old;
 132  lua_lock(L);
 133  old = G(L)->panic;
 134  G(L)->panic = panicf;
 135  lua_unlock(L);
 136  return old;
 137}
 138
 139
 140LUA_API lua_State *lua_newthread (lua_State *L) {
 141  lua_State *L1;
 142  lua_lock(L);
 143  luaC_checkGC(L);
 144  L1 = luaE_newthread(L);
 145  setthvalue(L, L->top, L1);
 146  api_incr_top(L);
 147  lua_unlock(L);
 148  luai_userstatethread(L, L1);
 149  return L1;
 150}
 151
 152
 153
 154/*
 155** basic stack manipulation
 156*/
 157
 158
 159LUA_API int lua_gettop (lua_State *L) {
 160  return cast_int(L->top - L->base);
 161}
 162
 163
 164LUA_API void lua_settop (lua_State *L, int idx) {
 165  lua_lock(L);
 166  if (idx >= 0) {
 167    api_check(L, idx <= L->stack_last - L->base);
 168    while (L->top < L->base + idx)
 169      setnilvalue(L->top++);
 170    L->top = L->base + idx;
 171  }
 172  else {
 173    api_check(L, -(idx+1) <= (L->top - L->base));
 174    L->top += idx+1;  /* `subtract' index (index is negative) */
 175  }
 176  lua_unlock(L);
 177}
 178
 179
 180LUA_API void lua_remove (lua_State *L, int idx) {
 181  StkId p;
 182  lua_lock(L);
 183  p = index2adr(L, idx);
 184  api_checkvalidindex(L, p);
 185  while (++p < L->top) setobjs2s(L, p-1, p);
 186  L->top--;
 187  lua_unlock(L);
 188}
 189
 190
 191LUA_API void lua_insert (lua_State *L, int idx) {
 192  StkId p;
 193  StkId q;
 194  lua_lock(L);
 195  p = index2adr(L, idx);
 196  api_checkvalidindex(L, p);
 197  for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
 198  setobjs2s(L, p, L->top);
 199  lua_unlock(L);
 200}
 201
 202
 203LUA_API void lua_replace (lua_State *L, int idx) {
 204  StkId o;
 205  lua_lock(L);
 206  /* explicit test for incompatible code */
 207  if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci)
 208    luaG_runerror(L, "no calling environment");
 209  api_checknelems(L, 1);
 210  o = index2adr(L, idx);
 211  api_checkvalidindex(L, o);
 212  if (idx == LUA_ENVIRONINDEX) {
 213    Closure *func = curr_func(L);
 214    api_check(L, ttistable(L->top - 1)); 
 215    func->c.env = hvalue(L->top - 1);
 216    luaC_barrier(L, func, L->top - 1);
 217  }
 218  else {
 219    setobj(L, o, L->top - 1);
 220    if (idx < LUA_GLOBALSINDEX)  /* function upvalue? */
 221      luaC_barrier(L, curr_func(L), L->top - 1);
 222  }
 223  L->top--;
 224  lua_unlock(L);
 225}
 226
 227
 228LUA_API void lua_pushvalue (lua_State *L, int idx) {
 229  lua_lock(L);
 230  setobj2s(L, L->top, index2adr(L, idx));
 231  api_incr_top(L);
 232  lua_unlock(L);
 233}
 234
 235
 236
 237/*
 238** access functions (stack -> C)
 239*/
 240
 241
 242LUA_API int lua_type (lua_State *L, int idx) {
 243  StkId o = index2adr(L, idx);
 244  return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
 245}
 246
 247
 248LUA_API const char *lua_typename (lua_State *L, int t) {
 249  UNUSED(L);
 250  return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
 251}
 252
 253
 254LUA_API int lua_iscfunction (lua_State *L, int idx) {
 255  StkId o = index2adr(L, idx);
 256  return iscfunction(o);
 257}
 258
 259
 260LUA_API int lua_isnumber (lua_State *L, int idx) {
 261  TValue n;
 262  const TValue *o = index2adr(L, idx);
 263  return tonumber(o, &n);
 264}
 265
 266
 267LUA_API int lua_isstring (lua_State *L, int idx) {
 268  int t = lua_type(L, idx);
 269  return (t == LUA_TSTRING || t == LUA_TNUMBER);
 270}
 271
 272
 273LUA_API int lua_isuserdata (lua_State *L, int idx) {
 274  const TValue *o = index2adr(L, idx);
 275  return (ttisuserdata(o) || ttislightuserdata(o));
 276}
 277
 278
 279LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
 280  StkId o1 = index2adr(L, index1);
 281  StkId o2 = index2adr(L, index2);
 282  return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
 283         : luaO_rawequalObj(o1, o2);
 284}
 285
 286
 287LUA_API int lua_equal (lua_State *L, int index1, int index2) {
 288  StkId o1, o2;
 289  int i;
 290  lua_lock(L);  /* may call tag method */
 291  o1 = index2adr(L, index1);
 292  o2 = index2adr(L, index2);
 293  i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2);
 294  lua_unlock(L);
 295  return i;
 296}
 297
 298
 299LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
 300  StkId o1, o2;
 301  int i;
 302  lua_lock(L);  /* may call tag method */
 303  o1 = index2adr(L, index1);
 304  o2 = index2adr(L, index2);
 305  i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
 306       : luaV_lessthan(L, o1, o2);
 307  lua_unlock(L);
 308  return i;
 309}
 310
 311
 312
 313LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
 314  TValue n;
 315  const TValue *o = index2adr(L, idx);
 316  if (tonumber(o, &n))
 317    return nvalue(o);
 318  else
 319    return 0;
 320}
 321
 322
 323LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
 324  TValue n;
 325  const TValue *o = index2adr(L, idx);
 326  if (tonumber(o, &n)) {
 327    lua_Integer res;
 328    lua_Number num = nvalue(o);
 329    lua_number2integer(res, num);
 330    return res;
 331  }
 332  else
 333    return 0;
 334}
 335
 336
 337LUA_API int lua_toboolean (lua_State *L, int idx) {
 338  const TValue *o = index2adr(L, idx);
 339  return !l_isfalse(o);
 340}
 341
 342
 343LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
 344  StkId o = index2adr(L, idx);
 345  if (!ttisstring(o)) {
 346    lua_lock(L);  /* `luaV_tostring' may create a new string */
 347    if (!luaV_tostring(L, o)) {  /* conversion failed? */
 348      if (len != NULL) *len = 0;
 349      lua_unlock(L);
 350      return NULL;
 351    }
 352    luaC_checkGC(L);
 353    o = index2adr(L, idx);  /* previous call may reallocate the stack */
 354    lua_unlock(L);
 355  }
 356  if (len != NULL) *len = tsvalue(o)->len;
 357  return svalue(o);
 358}
 359
 360
 361LUA_API size_t lua_objlen (lua_State *L, int idx) {
 362  StkId o = index2adr(L, idx);
 363  switch (ttype(o)) {
 364    case LUA_TSTRING: return tsvalue(o)->len;
 365    case LUA_TUSERDATA: return uvalue(o)->len;
 366    case LUA_TTABLE: return luaH_getn(hvalue(o));
 367    case LUA_TNUMBER: {
 368      size_t l;
 369      lua_lock(L);  /* `luaV_tostring' may create a new string */
 370      l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
 371      lua_unlock(L);
 372      return l;
 373    }
 374    default: return 0;
 375  }
 376}
 377
 378
 379LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
 380  StkId o = index2adr(L, idx);
 381  return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;
 382}
 383
 384
 385LUA_API void *lua_touserdata (lua_State *L, int idx) {
 386  StkId o = index2adr(L, idx);
 387  switch (ttype(o)) {
 388    case LUA_TUSERDATA: return (rawuvalue(o) + 1);
 389    case LUA_TLIGHTUSERDATA: return pvalue(o);
 390    default: return NULL;
 391  }
 392}
 393
 394
 395LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
 396  StkId o = index2adr(L, idx);
 397  return (!ttisthread(o)) ? NULL : thvalue(o);
 398}
 399
 400
 401LUA_API const void *lua_topointer (lua_State *L, int idx) {
 402  StkId o = index2adr(L, idx);
 403  switch (ttype(o)) {
 404    case LUA_TTABLE: return hvalue(o);
 405    case LUA_TFUNCTION: return clvalue(o);
 406    case LUA_TTHREAD: return thvalue(o);
 407    case LUA_TUSERDATA:
 408    case LUA_TLIGHTUSERDATA:
 409      return lua_touserdata(L, idx);
 410    default: return NULL;
 411  }
 412}
 413
 414
 415
 416/*
 417** push functions (C -> stack)
 418*/
 419
 420
 421LUA_API void lua_pushnil (lua_State *L) {
 422  lua_lock(L);
 423  setnilvalue(L->top);
 424  api_incr_top(L);
 425  lua_unlock(L);
 426}
 427
 428
 429LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
 430  lua_lock(L);
 431  setnvalue(L->top, n);
 432  api_incr_top(L);
 433  lua_unlock(L);
 434}
 435
 436
 437LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
 438  lua_lock(L);
 439  setnvalue(L->top, cast_num(n));
 440  api_incr_top(L);
 441  lua_unlock(L);
 442}
 443
 444
 445LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
 446  lua_lock(L);
 447  luaC_checkGC(L);
 448  setsvalue2s(L, L->top, luaS_newlstr(L, s, len));
 449  api_incr_top(L);
 450  lua_unlock(L);
 451}
 452
 453
 454LUA_API void lua_pushstring (lua_State *L, const char *s) {
 455  if (s == NULL)
 456    lua_pushnil(L);
 457  else
 458    lua_pushlstring(L, s, strlen(s));
 459}
 460
 461
 462LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
 463                                      va_list argp) {
 464  const char *ret;
 465  lua_lock(L);
 466  luaC_checkGC(L);
 467  ret = luaO_pushvfstring(L, fmt, argp);
 468  lua_unlock(L);
 469  return ret;
 470}
 471
 472
 473LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
 474  const char *ret;
 475  va_list argp;
 476  lua_lock(L);
 477  luaC_checkGC(L);
 478  va_start(argp, fmt);
 479  ret = luaO_pushvfstring(L, fmt, argp);
 480  va_end(argp);
 481  lua_unlock(L);
 482  return ret;
 483}
 484
 485
 486LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
 487  Closure *cl;
 488  lua_lock(L);
 489  luaC_checkGC(L);
 490  api_checknelems(L, n);
 491  cl = luaF_newCclosure(L, n, getcurrenv(L));
 492  cl->c.f = fn;
 493  L->top -= n;
 494  while (n--)
 495    setobj2n(L, &cl->c.upvalue[n], L->top+n);
 496  setclvalue(L, L->top, cl);
 497  lua_assert(iswhite(obj2gco(cl)));
 498  api_incr_top(L);
 499  lua_unlock(L);
 500}
 501
 502
 503LUA_API void lua_pushboolean (lua_State *L, int b) {
 504  lua_lock(L);
 505  setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
 506  api_incr_top(L);
 507  lua_unlock(L);
 508}
 509
 510
 511LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
 512  lua_lock(L);
 513  setpvalue(L->top, p);
 514  api_incr_top(L);
 515  lua_unlock(L);
 516}
 517
 518
 519LUA_API int lua_pushthread (lua_State *L) {
 520  lua_lock(L);
 521  setthvalue(L, L->top, L);
 522  api_incr_top(L);
 523  lua_unlock(L);
 524  return (G(L)->mainthread == L);
 525}
 526
 527
 528
 529/*
 530** get functions (Lua -> stack)
 531*/
 532
 533
 534LUA_API void lua_gettable (lua_State *L, int idx) {
 535  StkId t;
 536  lua_lock(L);
 537  t = index2adr(L, idx);
 538  api_checkvalidindex(L, t);
 539  luaV_gettable(L, t, L->top - 1, L->top - 1);
 540  lua_unlock(L);
 541}
 542
 543
 544LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
 545  StkId t;
 546  TValue key;
 547  lua_lock(L);
 548  t = index2adr(L, idx);
 549  api_checkvalidindex(L, t);
 550  setsvalue(L, &key, luaS_new(L, k));
 551  luaV_gettable(L, t, &key, L->top);
 552  api_incr_top(L);
 553  lua_unlock(L);
 554}
 555
 556
 557LUA_API void lua_rawget (lua_State *L, int idx) {
 558  StkId t;
 559  lua_lock(L);
 560  t = index2adr(L, idx);
 561  api_check(L, ttistable(t));
 562  setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
 563  lua_unlock(L);
 564}
 565
 566
 567LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
 568  StkId o;
 569  lua_lock(L);
 570  o = index2adr(L, idx);
 571  api_check(L, ttistable(o));
 572  setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
 573  api_incr_top(L);
 574  lua_unlock(L);
 575}
 576
 577
 578LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
 579  lua_lock(L);
 580  luaC_checkGC(L);
 581  sethvalue(L, L->top, luaH_new(L, narray, nrec));
 582  api_incr_top(L);
 583  lua_unlock(L);
 584}
 585
 586
 587LUA_API int lua_getmetatable (lua_State *L, int objindex) {
 588  const TValue *obj;
 589  Table *mt = NULL;
 590  int res;
 591  lua_lock(L);
 592  obj = index2adr(L, objindex);
 593  switch (ttype(obj)) {
 594    case LUA_TTABLE:
 595      mt = hvalue(obj)->metatable;
 596      break;
 597    case LUA_TUSERDATA:
 598      mt = uvalue(obj)->metatable;
 599      break;
 600    default:
 601      mt = G(L)->mt[ttype(obj)];
 602      break;
 603  }
 604  if (mt == NULL)
 605    res = 0;
 606  else {
 607    sethvalue(L, L->top, mt);
 608    api_incr_top(L);
 609    res = 1;
 610  }
 611  lua_unlock(L);
 612  return res;
 613}
 614
 615
 616LUA_API void lua_getfenv (lua_State *L, int idx) {
 617  StkId o;
 618  lua_lock(L);
 619  o = index2adr(L, idx);
 620  api_checkvalidindex(L, o);
 621  switch (ttype(o)) {
 622    case LUA_TFUNCTION:
 623      sethvalue(L, L->top, clvalue(o)->c.env);
 624      break;
 625    case LUA_TUSERDATA:
 626      sethvalue(L, L->top, uvalue(o)->env);
 627      break;
 628    case LUA_TTHREAD:
 629      setobj2s(L, L->top,  gt(thvalue(o)));
 630      break;
 631    default:
 632      setnilvalue(L->top);
 633      break;
 634  }
 635  api_incr_top(L);
 636  lua_unlock(L);
 637}
 638
 639
 640/*
 641** set functions (stack -> Lua)
 642*/
 643
 644
 645LUA_API void lua_settable (lua_State *L, int idx) {
 646  StkId t;
 647  lua_lock(L);
 648  api_checknelems(L, 2);
 649  t = index2adr(L, idx);
 650  api_checkvalidindex(L, t);
 651  luaV_settable(L, t, L->top - 2, L->top - 1);
 652  L->top -= 2;  /* pop index and value */
 653  lua_unlock(L);
 654}
 655
 656
 657LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
 658  StkId t;
 659  TValue key;
 660  lua_lock(L);
 661  api_checknelems(L, 1);
 662  t = index2adr(L, idx);
 663  api_checkvalidindex(L, t);
 664  setsvalue(L, &key, luaS_new(L, k));
 665  luaV_settable(L, t, &key, L->top - 1);
 666  L->top--;  /* pop value */
 667  lua_unlock(L);
 668}
 669
 670
 671LUA_API void lua_rawset (lua_State *L, int idx) {
 672  StkId t;
 673  lua_lock(L);
 674  api_checknelems(L, 2);
 675  t = index2adr(L, idx);
 676  api_check(L, ttistable(t));
 677  setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
 678  luaC_barriert(L, hvalue(t), L->top-1);
 679  L->top -= 2;
 680  lua_unlock(L);
 681}
 682
 683
 684LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
 685  StkId o;
 686  lua_lock(L);
 687  api_checknelems(L, 1);
 688  o = index2adr(L, idx);
 689  api_check(L, ttistable(o));
 690  setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
 691  luaC_barriert(L, hvalue(o), L->top-1);
 692  L->top--;
 693  lua_unlock(L);
 694}
 695
 696
 697LUA_API int lua_setmetatable (lua_State *L, int objindex) {
 698  TValue *obj;
 699  Table *mt;
 700  lua_lock(L);
 701  api_checknelems(L, 1);
 702  obj = index2adr(L, objindex);
 703  api_checkvalidindex(L, obj);
 704  if (ttisnil(L->top - 1))
 705    mt = NULL;
 706  else {
 707    api_check(L, ttistable(L->top - 1));
 708    mt = hvalue(L->top - 1);
 709  }
 710  switch (ttype(obj)) {
 711    case LUA_TTABLE: {
 712      hvalue(obj)->metatable = mt;
 713      if (mt)
 714        luaC_objbarriert(L, hvalue(obj), mt);
 715      break;
 716    }
 717    case LUA_TUSERDATA: {
 718      uvalue(obj)->metatable = mt;
 719      if (mt)
 720        luaC_objbarrier(L, rawuvalue(obj), mt);
 721      break;
 722    }
 723    default: {
 724      G(L)->mt[ttype(obj)] = mt;
 725      break;
 726    }
 727  }
 728  L->top--;
 729  lua_unlock(L);
 730  return 1;
 731}
 732
 733
 734LUA_API int lua_setfenv (lua_State *L, int idx) {
 735  StkId o;
 736  int res = 1;
 737  lua_lock(L);
 738  api_checknelems(L, 1);
 739  o = index2adr(L, idx);
 740  api_checkvalidindex(L, o);
 741  api_check(L, ttistable(L->top - 1));
 742  switch (ttype(o)) {
 743    case LUA_TFUNCTION:
 744      clvalue(o)->c.env = hvalue(L->top - 1);
 745      break;
 746    case LUA_TUSERDATA:
 747      uvalue(o)->env = hvalue(L->top - 1);
 748      break;
 749    case LUA_TTHREAD:
 750      sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1));
 751      break;
 752    default:
 753      res = 0;
 754      break;
 755  }
 756  if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
 757  L->top--;
 758  lua_unlock(L);
 759  return res;
 760}
 761
 762
 763/*
 764** `load' and `call' functions (run Lua code)
 765*/
 766
 767
 768#define adjustresults(L,nres) \
 769    { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; }
 770
 771
 772#define checkresults(L,na,nr) \
 773     api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
 774	
 775
 776LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
 777  StkId func;
 778  lua_lock(L);
 779  api_checknelems(L, nargs+1);
 780  checkresults(L, nargs, nresults);
 781  func = L->top - (nargs+1);
 782  luaD_call(L, func, nresults);
 783  adjustresults(L, nresults);
 784  lua_unlock(L);
 785}
 786
 787
 788
 789/*
 790** Execute a protected call.
 791*/
 792struct CallS {  /* data to `f_call' */
 793  StkId func;
 794  int nresults;
 795};
 796
 797
 798static void f_call (lua_State *L, void *ud) {
 799  struct CallS *c = cast(struct CallS *, ud);
 800  luaD_call(L, c->func, c->nresults);
 801}
 802
 803
 804
 805LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
 806  struct CallS c;
 807  int status;
 808  ptrdiff_t func;
 809  lua_lock(L);
 810  api_checknelems(L, nargs+1);
 811  checkresults(L, nargs, nresults);
 812  if (errfunc == 0)
 813    func = 0;
 814  else {
 815    StkId o = index2adr(L, errfunc);
 816    api_checkvalidindex(L, o);
 817    func = savestack(L, o);
 818  }
 819  c.func = L->top - (nargs+1);  /* function to be called */
 820  c.nresults = nresults;
 821  status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
 822  adjustresults(L, nresults);
 823  lua_unlock(L);
 824  return status;
 825}
 826
 827
 828/*
 829** Execute a protected C call.
 830*/
 831struct CCallS {  /* data to `f_Ccall' */
 832  lua_CFunction func;
 833  void *ud;
 834};
 835
 836
 837static void f_Ccall (lua_State *L, void *ud) {
 838  struct CCallS *c = cast(struct CCallS *, ud);
 839  Closure *cl;
 840  cl = luaF_newCclosure(L, 0, getcurrenv(L));
 841  cl->c.f = c->func;
 842  setclvalue(L, L->top, cl);  /* push function */
 843  api_incr_top(L);
 844  setpvalue(L->top, c->ud);  /* push only argument */
 845  api_incr_top(L);
 846  luaD_call(L, L->top - 2, 0);
 847}
 848
 849
 850LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
 851  struct CCallS c;
 852  int status;
 853  lua_lock(L);
 854  c.func = func;
 855  c.ud = ud;
 856  status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
 857  lua_unlock(L);
 858  return status;
 859}
 860
 861
 862LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
 863                      const char *chunkname) {
 864  ZIO z;
 865  int status;
 866  lua_lock(L);
 867  if (!chunkname) chunkname = "?";
 868  luaZ_init(L, &z, reader, data);
 869  status = luaD_protectedparser(L, &z, chunkname);
 870  lua_unlock(L);
 871  return status;
 872}
 873
 874
 875LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
 876  int status;
 877  TValue *o;
 878  lua_lock(L);
 879  api_checknelems(L, 1);
 880  o = L->top - 1;
 881  if (isLfunction(o))
 882    status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
 883  else
 884    status = 1;
 885  lua_unlock(L);
 886  return status;
 887}
 888
 889
 890LUA_API int  lua_status (lua_State *L) {
 891  return L->status;
 892}
 893
 894
 895/*
 896** Garbage-collection function
 897*/
 898
 899LUA_API int lua_gc (lua_State *L, int what, int data) {
 900  int res = 0;
 901  global_State *g;
 902  lua_lock(L);
 903  g = G(L);
 904  switch (what) {
 905    case LUA_GCSTOP: {
 906      g->GCthreshold = MAX_LUMEM;
 907      break;
 908    }
 909    case LUA_GCRESTART: {
 910      g->GCthreshold = g->totalbytes;
 911      break;
 912    }
 913    case LUA_GCCOLLECT: {
 914      luaC_fullgc(L);
 915      break;
 916    }
 917    case LUA_GCCOUNT: {
 918      /* GC values are expressed in Kbytes: #bytes/2^10 */
 919      res = cast_int(g->totalbytes >> 10);
 920      break;
 921    }
 922    case LUA_GCCOUNTB: {
 923      res = cast_int(g->totalbytes & 0x3ff);
 924      break;
 925    }
 926    case LUA_GCSTEP: {
 927      lu_mem a = (cast(lu_mem, data) << 10);
 928      if (a <= g->totalbytes)
 929        g->GCthreshold = g->totalbytes - a;
 930      else
 931        g->GCthreshold = 0;
 932      while (g->GCthreshold <= g->totalbytes) {
 933        luaC_step(L);
 934        if (g->gcstate == GCSpause) {  /* end of cycle? */
 935          res = 1;  /* signal it */
 936          break;
 937        }
 938      }
 939      break;
 940    }
 941    case LUA_GCSETPAUSE: {
 942      res = g->gcpause;
 943      g->gcpause = data;
 944      break;
 945    }
 946    case LUA_GCSETSTEPMUL: {
 947      res = g->gcstepmul;
 948      g->gcstepmul = data;
 949      break;
 950    }
 951    default: res = -1;  /* invalid option */
 952  }
 953  lua_unlock(L);
 954  return res;
 955}
 956
 957
 958
 959/*
 960** miscellaneous functions
 961*/
 962
 963
 964LUA_API int lua_error (lua_State *L) {
 965  lua_lock(L);
 966  api_checknelems(L, 1);
 967  luaG_errormsg(L);
 968  lua_unlock(L);
 969  return 0;  /* to avoid warnings */
 970}
 971
 972
 973LUA_API int lua_next (lua_State *L, int idx) {
 974  StkId t;
 975  int more;
 976  lua_lock(L);
 977  t = index2adr(L, idx);
 978  api_check(L, ttistable(t));
 979  more = luaH_next(L, hvalue(t), L->top - 1);
 980  if (more) {
 981    api_incr_top(L);
 982  }
 983  else  /* no more elements */
 984    L->top -= 1;  /* remove key */
 985  lua_unlock(L);
 986  return more;
 987}
 988
 989
 990LUA_API void lua_concat (lua_State *L, int n) {
 991  lua_lock(L);
 992  api_checknelems(L, n);
 993  if (n >= 2) {
 994    luaC_checkGC(L);
 995    luaV_concat(L, n, cast_int(L->top - L->base) - 1);
 996    L->top -= (n-1);
 997  }
 998  else if (n == 0) {  /* push empty string */
 999    setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
1000    api_incr_top(L);
1001  }
1002  /* else n == 1; nothing to do */
1003  lua_unlock(L);
1004}
1005
1006
1007LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
1008  lua_Alloc f;
1009  lua_lock(L);
1010  if (ud) *ud = G(L)->ud;
1011  f = G(L)->frealloc;
1012  lua_unlock(L);
1013  return f;
1014}
1015
1016
1017LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
1018  lua_lock(L);
1019  G(L)->ud = ud;
1020  G(L)->frealloc = f;
1021  lua_unlock(L);
1022}
1023
1024
1025LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
1026  Udata *u;
1027  lua_lock(L);
1028  luaC_checkGC(L);
1029  u = luaS_newudata(L, size, getcurrenv(L));
1030  setuvalue(L, L->top, u);
1031  api_incr_top(L);
1032  lua_unlock(L);
1033  return u + 1;
1034}
1035
1036
1037
1038
1039static const char *aux_upvalue (StkId fi, int n, TValue **val) {
1040  Closure *f;
1041  if (!ttisfunction(fi)) return NULL;
1042  f = clvalue(fi);
1043  if (f->c.isC) {
1044    if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
1045    *val = &f->c.upvalue[n-1];
1046    return "";
1047  }
1048  else {
1049    Proto *p = f->l.p;
1050    if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
1051    *val = f->l.upvals[n-1]->v;
1052    return getstr(p->upvalues[n-1]);
1053  }
1054}
1055
1056
1057LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
1058  const char *name;
1059  TValue *val;
1060  lua_lock(L);
1061  name = aux_upvalue(index2adr(L, funcindex), n, &val);
1062  if (name) {
1063    setobj2s(L, L->top, val);
1064    api_incr_top(L);
1065  }
1066  lua_unlock(L);
1067  return name;
1068}
1069
1070
1071LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
1072  const char *name;
1073  TValue *val;
1074  StkId fi;
1075  lua_lock(L);
1076  fi = index2adr(L, funcindex);
1077  api_checknelems(L, 1);
1078  name = aux_upvalue(fi, n, &val);
1079  if (name) {
1080    L->top--;
1081    setobj(L, val, L->top);
1082    luaC_barrier(L, clvalue(fi), L->top);
1083  }
1084  lua_unlock(L);
1085  return name;
1086}
1087