diff src/lua/src/lapi.c @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/lua/src/lapi.c	Sat Mar 03 10:31:27 2012 -0600
     1.3 @@ -0,0 +1,1087 @@
     1.4 +/*
     1.5 +** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $
     1.6 +** Lua API
     1.7 +** See Copyright Notice in lua.h
     1.8 +*/
     1.9 +
    1.10 +
    1.11 +#include <assert.h>
    1.12 +#include <math.h>
    1.13 +#include <stdarg.h>
    1.14 +#include <string.h>
    1.15 +
    1.16 +#define lapi_c
    1.17 +#define LUA_CORE
    1.18 +
    1.19 +#include "lua.h"
    1.20 +
    1.21 +#include "lapi.h"
    1.22 +#include "ldebug.h"
    1.23 +#include "ldo.h"
    1.24 +#include "lfunc.h"
    1.25 +#include "lgc.h"
    1.26 +#include "lmem.h"
    1.27 +#include "lobject.h"
    1.28 +#include "lstate.h"
    1.29 +#include "lstring.h"
    1.30 +#include "ltable.h"
    1.31 +#include "ltm.h"
    1.32 +#include "lundump.h"
    1.33 +#include "lvm.h"
    1.34 +
    1.35 +
    1.36 +
    1.37 +const char lua_ident[] =
    1.38 +  "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n"
    1.39 +  "$Authors: " LUA_AUTHORS " $\n"
    1.40 +  "$URL: www.lua.org $\n";
    1.41 +
    1.42 +
    1.43 +
    1.44 +#define api_checknelems(L, n)	api_check(L, (n) <= (L->top - L->base))
    1.45 +
    1.46 +#define api_checkvalidindex(L, i)	api_check(L, (i) != luaO_nilobject)
    1.47 +
    1.48 +#define api_incr_top(L)   {api_check(L, L->top < L->ci->top); L->top++;}
    1.49 +
    1.50 +
    1.51 +
    1.52 +static TValue *index2adr (lua_State *L, int idx) {
    1.53 +  if (idx > 0) {
    1.54 +    TValue *o = L->base + (idx - 1);
    1.55 +    api_check(L, idx <= L->ci->top - L->base);
    1.56 +    if (o >= L->top) return cast(TValue *, luaO_nilobject);
    1.57 +    else return o;
    1.58 +  }
    1.59 +  else if (idx > LUA_REGISTRYINDEX) {
    1.60 +    api_check(L, idx != 0 && -idx <= L->top - L->base);
    1.61 +    return L->top + idx;
    1.62 +  }
    1.63 +  else switch (idx) {  /* pseudo-indices */
    1.64 +    case LUA_REGISTRYINDEX: return registry(L);
    1.65 +    case LUA_ENVIRONINDEX: {
    1.66 +      Closure *func = curr_func(L);
    1.67 +      sethvalue(L, &L->env, func->c.env);
    1.68 +      return &L->env;
    1.69 +    }
    1.70 +    case LUA_GLOBALSINDEX: return gt(L);
    1.71 +    default: {
    1.72 +      Closure *func = curr_func(L);
    1.73 +      idx = LUA_GLOBALSINDEX - idx;
    1.74 +      return (idx <= func->c.nupvalues)
    1.75 +                ? &func->c.upvalue[idx-1]
    1.76 +                : cast(TValue *, luaO_nilobject);
    1.77 +    }
    1.78 +  }
    1.79 +}
    1.80 +
    1.81 +
    1.82 +static Table *getcurrenv (lua_State *L) {
    1.83 +  if (L->ci == L->base_ci)  /* no enclosing function? */
    1.84 +    return hvalue(gt(L));  /* use global table as environment */
    1.85 +  else {
    1.86 +    Closure *func = curr_func(L);
    1.87 +    return func->c.env;
    1.88 +  }
    1.89 +}
    1.90 +
    1.91 +
    1.92 +void luaA_pushobject (lua_State *L, const TValue *o) {
    1.93 +  setobj2s(L, L->top, o);
    1.94 +  api_incr_top(L);
    1.95 +}
    1.96 +
    1.97 +
    1.98 +LUA_API int lua_checkstack (lua_State *L, int size) {
    1.99 +  int res = 1;
   1.100 +  lua_lock(L);
   1.101 +  if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK)
   1.102 +    res = 0;  /* stack overflow */
   1.103 +  else if (size > 0) {
   1.104 +    luaD_checkstack(L, size);
   1.105 +    if (L->ci->top < L->top + size)
   1.106 +      L->ci->top = L->top + size;
   1.107 +  }
   1.108 +  lua_unlock(L);
   1.109 +  return res;
   1.110 +}
   1.111 +
   1.112 +
   1.113 +LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
   1.114 +  int i;
   1.115 +  if (from == to) return;
   1.116 +  lua_lock(to);
   1.117 +  api_checknelems(from, n);
   1.118 +  api_check(from, G(from) == G(to));
   1.119 +  api_check(from, to->ci->top - to->top >= n);
   1.120 +  from->top -= n;
   1.121 +  for (i = 0; i < n; i++) {
   1.122 +    setobj2s(to, to->top++, from->top + i);
   1.123 +  }
   1.124 +  lua_unlock(to);
   1.125 +}
   1.126 +
   1.127 +
   1.128 +LUA_API void lua_setlevel (lua_State *from, lua_State *to) {
   1.129 +  to->nCcalls = from->nCcalls;
   1.130 +}
   1.131 +
   1.132 +
   1.133 +LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
   1.134 +  lua_CFunction old;
   1.135 +  lua_lock(L);
   1.136 +  old = G(L)->panic;
   1.137 +  G(L)->panic = panicf;
   1.138 +  lua_unlock(L);
   1.139 +  return old;
   1.140 +}
   1.141 +
   1.142 +
   1.143 +LUA_API lua_State *lua_newthread (lua_State *L) {
   1.144 +  lua_State *L1;
   1.145 +  lua_lock(L);
   1.146 +  luaC_checkGC(L);
   1.147 +  L1 = luaE_newthread(L);
   1.148 +  setthvalue(L, L->top, L1);
   1.149 +  api_incr_top(L);
   1.150 +  lua_unlock(L);
   1.151 +  luai_userstatethread(L, L1);
   1.152 +  return L1;
   1.153 +}
   1.154 +
   1.155 +
   1.156 +
   1.157 +/*
   1.158 +** basic stack manipulation
   1.159 +*/
   1.160 +
   1.161 +
   1.162 +LUA_API int lua_gettop (lua_State *L) {
   1.163 +  return cast_int(L->top - L->base);
   1.164 +}
   1.165 +
   1.166 +
   1.167 +LUA_API void lua_settop (lua_State *L, int idx) {
   1.168 +  lua_lock(L);
   1.169 +  if (idx >= 0) {
   1.170 +    api_check(L, idx <= L->stack_last - L->base);
   1.171 +    while (L->top < L->base + idx)
   1.172 +      setnilvalue(L->top++);
   1.173 +    L->top = L->base + idx;
   1.174 +  }
   1.175 +  else {
   1.176 +    api_check(L, -(idx+1) <= (L->top - L->base));
   1.177 +    L->top += idx+1;  /* `subtract' index (index is negative) */
   1.178 +  }
   1.179 +  lua_unlock(L);
   1.180 +}
   1.181 +
   1.182 +
   1.183 +LUA_API void lua_remove (lua_State *L, int idx) {
   1.184 +  StkId p;
   1.185 +  lua_lock(L);
   1.186 +  p = index2adr(L, idx);
   1.187 +  api_checkvalidindex(L, p);
   1.188 +  while (++p < L->top) setobjs2s(L, p-1, p);
   1.189 +  L->top--;
   1.190 +  lua_unlock(L);
   1.191 +}
   1.192 +
   1.193 +
   1.194 +LUA_API void lua_insert (lua_State *L, int idx) {
   1.195 +  StkId p;
   1.196 +  StkId q;
   1.197 +  lua_lock(L);
   1.198 +  p = index2adr(L, idx);
   1.199 +  api_checkvalidindex(L, p);
   1.200 +  for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
   1.201 +  setobjs2s(L, p, L->top);
   1.202 +  lua_unlock(L);
   1.203 +}
   1.204 +
   1.205 +
   1.206 +LUA_API void lua_replace (lua_State *L, int idx) {
   1.207 +  StkId o;
   1.208 +  lua_lock(L);
   1.209 +  /* explicit test for incompatible code */
   1.210 +  if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci)
   1.211 +    luaG_runerror(L, "no calling environment");
   1.212 +  api_checknelems(L, 1);
   1.213 +  o = index2adr(L, idx);
   1.214 +  api_checkvalidindex(L, o);
   1.215 +  if (idx == LUA_ENVIRONINDEX) {
   1.216 +    Closure *func = curr_func(L);
   1.217 +    api_check(L, ttistable(L->top - 1)); 
   1.218 +    func->c.env = hvalue(L->top - 1);
   1.219 +    luaC_barrier(L, func, L->top - 1);
   1.220 +  }
   1.221 +  else {
   1.222 +    setobj(L, o, L->top - 1);
   1.223 +    if (idx < LUA_GLOBALSINDEX)  /* function upvalue? */
   1.224 +      luaC_barrier(L, curr_func(L), L->top - 1);
   1.225 +  }
   1.226 +  L->top--;
   1.227 +  lua_unlock(L);
   1.228 +}
   1.229 +
   1.230 +
   1.231 +LUA_API void lua_pushvalue (lua_State *L, int idx) {
   1.232 +  lua_lock(L);
   1.233 +  setobj2s(L, L->top, index2adr(L, idx));
   1.234 +  api_incr_top(L);
   1.235 +  lua_unlock(L);
   1.236 +}
   1.237 +
   1.238 +
   1.239 +
   1.240 +/*
   1.241 +** access functions (stack -> C)
   1.242 +*/
   1.243 +
   1.244 +
   1.245 +LUA_API int lua_type (lua_State *L, int idx) {
   1.246 +  StkId o = index2adr(L, idx);
   1.247 +  return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
   1.248 +}
   1.249 +
   1.250 +
   1.251 +LUA_API const char *lua_typename (lua_State *L, int t) {
   1.252 +  UNUSED(L);
   1.253 +  return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
   1.254 +}
   1.255 +
   1.256 +
   1.257 +LUA_API int lua_iscfunction (lua_State *L, int idx) {
   1.258 +  StkId o = index2adr(L, idx);
   1.259 +  return iscfunction(o);
   1.260 +}
   1.261 +
   1.262 +
   1.263 +LUA_API int lua_isnumber (lua_State *L, int idx) {
   1.264 +  TValue n;
   1.265 +  const TValue *o = index2adr(L, idx);
   1.266 +  return tonumber(o, &n);
   1.267 +}
   1.268 +
   1.269 +
   1.270 +LUA_API int lua_isstring (lua_State *L, int idx) {
   1.271 +  int t = lua_type(L, idx);
   1.272 +  return (t == LUA_TSTRING || t == LUA_TNUMBER);
   1.273 +}
   1.274 +
   1.275 +
   1.276 +LUA_API int lua_isuserdata (lua_State *L, int idx) {
   1.277 +  const TValue *o = index2adr(L, idx);
   1.278 +  return (ttisuserdata(o) || ttislightuserdata(o));
   1.279 +}
   1.280 +
   1.281 +
   1.282 +LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
   1.283 +  StkId o1 = index2adr(L, index1);
   1.284 +  StkId o2 = index2adr(L, index2);
   1.285 +  return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
   1.286 +         : luaO_rawequalObj(o1, o2);
   1.287 +}
   1.288 +
   1.289 +
   1.290 +LUA_API int lua_equal (lua_State *L, int index1, int index2) {
   1.291 +  StkId o1, o2;
   1.292 +  int i;
   1.293 +  lua_lock(L);  /* may call tag method */
   1.294 +  o1 = index2adr(L, index1);
   1.295 +  o2 = index2adr(L, index2);
   1.296 +  i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2);
   1.297 +  lua_unlock(L);
   1.298 +  return i;
   1.299 +}
   1.300 +
   1.301 +
   1.302 +LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
   1.303 +  StkId o1, o2;
   1.304 +  int i;
   1.305 +  lua_lock(L);  /* may call tag method */
   1.306 +  o1 = index2adr(L, index1);
   1.307 +  o2 = index2adr(L, index2);
   1.308 +  i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
   1.309 +       : luaV_lessthan(L, o1, o2);
   1.310 +  lua_unlock(L);
   1.311 +  return i;
   1.312 +}
   1.313 +
   1.314 +
   1.315 +
   1.316 +LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
   1.317 +  TValue n;
   1.318 +  const TValue *o = index2adr(L, idx);
   1.319 +  if (tonumber(o, &n))
   1.320 +    return nvalue(o);
   1.321 +  else
   1.322 +    return 0;
   1.323 +}
   1.324 +
   1.325 +
   1.326 +LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
   1.327 +  TValue n;
   1.328 +  const TValue *o = index2adr(L, idx);
   1.329 +  if (tonumber(o, &n)) {
   1.330 +    lua_Integer res;
   1.331 +    lua_Number num = nvalue(o);
   1.332 +    lua_number2integer(res, num);
   1.333 +    return res;
   1.334 +  }
   1.335 +  else
   1.336 +    return 0;
   1.337 +}
   1.338 +
   1.339 +
   1.340 +LUA_API int lua_toboolean (lua_State *L, int idx) {
   1.341 +  const TValue *o = index2adr(L, idx);
   1.342 +  return !l_isfalse(o);
   1.343 +}
   1.344 +
   1.345 +
   1.346 +LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
   1.347 +  StkId o = index2adr(L, idx);
   1.348 +  if (!ttisstring(o)) {
   1.349 +    lua_lock(L);  /* `luaV_tostring' may create a new string */
   1.350 +    if (!luaV_tostring(L, o)) {  /* conversion failed? */
   1.351 +      if (len != NULL) *len = 0;
   1.352 +      lua_unlock(L);
   1.353 +      return NULL;
   1.354 +    }
   1.355 +    luaC_checkGC(L);
   1.356 +    o = index2adr(L, idx);  /* previous call may reallocate the stack */
   1.357 +    lua_unlock(L);
   1.358 +  }
   1.359 +  if (len != NULL) *len = tsvalue(o)->len;
   1.360 +  return svalue(o);
   1.361 +}
   1.362 +
   1.363 +
   1.364 +LUA_API size_t lua_objlen (lua_State *L, int idx) {
   1.365 +  StkId o = index2adr(L, idx);
   1.366 +  switch (ttype(o)) {
   1.367 +    case LUA_TSTRING: return tsvalue(o)->len;
   1.368 +    case LUA_TUSERDATA: return uvalue(o)->len;
   1.369 +    case LUA_TTABLE: return luaH_getn(hvalue(o));
   1.370 +    case LUA_TNUMBER: {
   1.371 +      size_t l;
   1.372 +      lua_lock(L);  /* `luaV_tostring' may create a new string */
   1.373 +      l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
   1.374 +      lua_unlock(L);
   1.375 +      return l;
   1.376 +    }
   1.377 +    default: return 0;
   1.378 +  }
   1.379 +}
   1.380 +
   1.381 +
   1.382 +LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
   1.383 +  StkId o = index2adr(L, idx);
   1.384 +  return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;
   1.385 +}
   1.386 +
   1.387 +
   1.388 +LUA_API void *lua_touserdata (lua_State *L, int idx) {
   1.389 +  StkId o = index2adr(L, idx);
   1.390 +  switch (ttype(o)) {
   1.391 +    case LUA_TUSERDATA: return (rawuvalue(o) + 1);
   1.392 +    case LUA_TLIGHTUSERDATA: return pvalue(o);
   1.393 +    default: return NULL;
   1.394 +  }
   1.395 +}
   1.396 +
   1.397 +
   1.398 +LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
   1.399 +  StkId o = index2adr(L, idx);
   1.400 +  return (!ttisthread(o)) ? NULL : thvalue(o);
   1.401 +}
   1.402 +
   1.403 +
   1.404 +LUA_API const void *lua_topointer (lua_State *L, int idx) {
   1.405 +  StkId o = index2adr(L, idx);
   1.406 +  switch (ttype(o)) {
   1.407 +    case LUA_TTABLE: return hvalue(o);
   1.408 +    case LUA_TFUNCTION: return clvalue(o);
   1.409 +    case LUA_TTHREAD: return thvalue(o);
   1.410 +    case LUA_TUSERDATA:
   1.411 +    case LUA_TLIGHTUSERDATA:
   1.412 +      return lua_touserdata(L, idx);
   1.413 +    default: return NULL;
   1.414 +  }
   1.415 +}
   1.416 +
   1.417 +
   1.418 +
   1.419 +/*
   1.420 +** push functions (C -> stack)
   1.421 +*/
   1.422 +
   1.423 +
   1.424 +LUA_API void lua_pushnil (lua_State *L) {
   1.425 +  lua_lock(L);
   1.426 +  setnilvalue(L->top);
   1.427 +  api_incr_top(L);
   1.428 +  lua_unlock(L);
   1.429 +}
   1.430 +
   1.431 +
   1.432 +LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
   1.433 +  lua_lock(L);
   1.434 +  setnvalue(L->top, n);
   1.435 +  api_incr_top(L);
   1.436 +  lua_unlock(L);
   1.437 +}
   1.438 +
   1.439 +
   1.440 +LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
   1.441 +  lua_lock(L);
   1.442 +  setnvalue(L->top, cast_num(n));
   1.443 +  api_incr_top(L);
   1.444 +  lua_unlock(L);
   1.445 +}
   1.446 +
   1.447 +
   1.448 +LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
   1.449 +  lua_lock(L);
   1.450 +  luaC_checkGC(L);
   1.451 +  setsvalue2s(L, L->top, luaS_newlstr(L, s, len));
   1.452 +  api_incr_top(L);
   1.453 +  lua_unlock(L);
   1.454 +}
   1.455 +
   1.456 +
   1.457 +LUA_API void lua_pushstring (lua_State *L, const char *s) {
   1.458 +  if (s == NULL)
   1.459 +    lua_pushnil(L);
   1.460 +  else
   1.461 +    lua_pushlstring(L, s, strlen(s));
   1.462 +}
   1.463 +
   1.464 +
   1.465 +LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
   1.466 +                                      va_list argp) {
   1.467 +  const char *ret;
   1.468 +  lua_lock(L);
   1.469 +  luaC_checkGC(L);
   1.470 +  ret = luaO_pushvfstring(L, fmt, argp);
   1.471 +  lua_unlock(L);
   1.472 +  return ret;
   1.473 +}
   1.474 +
   1.475 +
   1.476 +LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
   1.477 +  const char *ret;
   1.478 +  va_list argp;
   1.479 +  lua_lock(L);
   1.480 +  luaC_checkGC(L);
   1.481 +  va_start(argp, fmt);
   1.482 +  ret = luaO_pushvfstring(L, fmt, argp);
   1.483 +  va_end(argp);
   1.484 +  lua_unlock(L);
   1.485 +  return ret;
   1.486 +}
   1.487 +
   1.488 +
   1.489 +LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
   1.490 +  Closure *cl;
   1.491 +  lua_lock(L);
   1.492 +  luaC_checkGC(L);
   1.493 +  api_checknelems(L, n);
   1.494 +  cl = luaF_newCclosure(L, n, getcurrenv(L));
   1.495 +  cl->c.f = fn;
   1.496 +  L->top -= n;
   1.497 +  while (n--)
   1.498 +    setobj2n(L, &cl->c.upvalue[n], L->top+n);
   1.499 +  setclvalue(L, L->top, cl);
   1.500 +  lua_assert(iswhite(obj2gco(cl)));
   1.501 +  api_incr_top(L);
   1.502 +  lua_unlock(L);
   1.503 +}
   1.504 +
   1.505 +
   1.506 +LUA_API void lua_pushboolean (lua_State *L, int b) {
   1.507 +  lua_lock(L);
   1.508 +  setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
   1.509 +  api_incr_top(L);
   1.510 +  lua_unlock(L);
   1.511 +}
   1.512 +
   1.513 +
   1.514 +LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
   1.515 +  lua_lock(L);
   1.516 +  setpvalue(L->top, p);
   1.517 +  api_incr_top(L);
   1.518 +  lua_unlock(L);
   1.519 +}
   1.520 +
   1.521 +
   1.522 +LUA_API int lua_pushthread (lua_State *L) {
   1.523 +  lua_lock(L);
   1.524 +  setthvalue(L, L->top, L);
   1.525 +  api_incr_top(L);
   1.526 +  lua_unlock(L);
   1.527 +  return (G(L)->mainthread == L);
   1.528 +}
   1.529 +
   1.530 +
   1.531 +
   1.532 +/*
   1.533 +** get functions (Lua -> stack)
   1.534 +*/
   1.535 +
   1.536 +
   1.537 +LUA_API void lua_gettable (lua_State *L, int idx) {
   1.538 +  StkId t;
   1.539 +  lua_lock(L);
   1.540 +  t = index2adr(L, idx);
   1.541 +  api_checkvalidindex(L, t);
   1.542 +  luaV_gettable(L, t, L->top - 1, L->top - 1);
   1.543 +  lua_unlock(L);
   1.544 +}
   1.545 +
   1.546 +
   1.547 +LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
   1.548 +  StkId t;
   1.549 +  TValue key;
   1.550 +  lua_lock(L);
   1.551 +  t = index2adr(L, idx);
   1.552 +  api_checkvalidindex(L, t);
   1.553 +  setsvalue(L, &key, luaS_new(L, k));
   1.554 +  luaV_gettable(L, t, &key, L->top);
   1.555 +  api_incr_top(L);
   1.556 +  lua_unlock(L);
   1.557 +}
   1.558 +
   1.559 +
   1.560 +LUA_API void lua_rawget (lua_State *L, int idx) {
   1.561 +  StkId t;
   1.562 +  lua_lock(L);
   1.563 +  t = index2adr(L, idx);
   1.564 +  api_check(L, ttistable(t));
   1.565 +  setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
   1.566 +  lua_unlock(L);
   1.567 +}
   1.568 +
   1.569 +
   1.570 +LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
   1.571 +  StkId o;
   1.572 +  lua_lock(L);
   1.573 +  o = index2adr(L, idx);
   1.574 +  api_check(L, ttistable(o));
   1.575 +  setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
   1.576 +  api_incr_top(L);
   1.577 +  lua_unlock(L);
   1.578 +}
   1.579 +
   1.580 +
   1.581 +LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
   1.582 +  lua_lock(L);
   1.583 +  luaC_checkGC(L);
   1.584 +  sethvalue(L, L->top, luaH_new(L, narray, nrec));
   1.585 +  api_incr_top(L);
   1.586 +  lua_unlock(L);
   1.587 +}
   1.588 +
   1.589 +
   1.590 +LUA_API int lua_getmetatable (lua_State *L, int objindex) {
   1.591 +  const TValue *obj;
   1.592 +  Table *mt = NULL;
   1.593 +  int res;
   1.594 +  lua_lock(L);
   1.595 +  obj = index2adr(L, objindex);
   1.596 +  switch (ttype(obj)) {
   1.597 +    case LUA_TTABLE:
   1.598 +      mt = hvalue(obj)->metatable;
   1.599 +      break;
   1.600 +    case LUA_TUSERDATA:
   1.601 +      mt = uvalue(obj)->metatable;
   1.602 +      break;
   1.603 +    default:
   1.604 +      mt = G(L)->mt[ttype(obj)];
   1.605 +      break;
   1.606 +  }
   1.607 +  if (mt == NULL)
   1.608 +    res = 0;
   1.609 +  else {
   1.610 +    sethvalue(L, L->top, mt);
   1.611 +    api_incr_top(L);
   1.612 +    res = 1;
   1.613 +  }
   1.614 +  lua_unlock(L);
   1.615 +  return res;
   1.616 +}
   1.617 +
   1.618 +
   1.619 +LUA_API void lua_getfenv (lua_State *L, int idx) {
   1.620 +  StkId o;
   1.621 +  lua_lock(L);
   1.622 +  o = index2adr(L, idx);
   1.623 +  api_checkvalidindex(L, o);
   1.624 +  switch (ttype(o)) {
   1.625 +    case LUA_TFUNCTION:
   1.626 +      sethvalue(L, L->top, clvalue(o)->c.env);
   1.627 +      break;
   1.628 +    case LUA_TUSERDATA:
   1.629 +      sethvalue(L, L->top, uvalue(o)->env);
   1.630 +      break;
   1.631 +    case LUA_TTHREAD:
   1.632 +      setobj2s(L, L->top,  gt(thvalue(o)));
   1.633 +      break;
   1.634 +    default:
   1.635 +      setnilvalue(L->top);
   1.636 +      break;
   1.637 +  }
   1.638 +  api_incr_top(L);
   1.639 +  lua_unlock(L);
   1.640 +}
   1.641 +
   1.642 +
   1.643 +/*
   1.644 +** set functions (stack -> Lua)
   1.645 +*/
   1.646 +
   1.647 +
   1.648 +LUA_API void lua_settable (lua_State *L, int idx) {
   1.649 +  StkId t;
   1.650 +  lua_lock(L);
   1.651 +  api_checknelems(L, 2);
   1.652 +  t = index2adr(L, idx);
   1.653 +  api_checkvalidindex(L, t);
   1.654 +  luaV_settable(L, t, L->top - 2, L->top - 1);
   1.655 +  L->top -= 2;  /* pop index and value */
   1.656 +  lua_unlock(L);
   1.657 +}
   1.658 +
   1.659 +
   1.660 +LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
   1.661 +  StkId t;
   1.662 +  TValue key;
   1.663 +  lua_lock(L);
   1.664 +  api_checknelems(L, 1);
   1.665 +  t = index2adr(L, idx);
   1.666 +  api_checkvalidindex(L, t);
   1.667 +  setsvalue(L, &key, luaS_new(L, k));
   1.668 +  luaV_settable(L, t, &key, L->top - 1);
   1.669 +  L->top--;  /* pop value */
   1.670 +  lua_unlock(L);
   1.671 +}
   1.672 +
   1.673 +
   1.674 +LUA_API void lua_rawset (lua_State *L, int idx) {
   1.675 +  StkId t;
   1.676 +  lua_lock(L);
   1.677 +  api_checknelems(L, 2);
   1.678 +  t = index2adr(L, idx);
   1.679 +  api_check(L, ttistable(t));
   1.680 +  setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
   1.681 +  luaC_barriert(L, hvalue(t), L->top-1);
   1.682 +  L->top -= 2;
   1.683 +  lua_unlock(L);
   1.684 +}
   1.685 +
   1.686 +
   1.687 +LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
   1.688 +  StkId o;
   1.689 +  lua_lock(L);
   1.690 +  api_checknelems(L, 1);
   1.691 +  o = index2adr(L, idx);
   1.692 +  api_check(L, ttistable(o));
   1.693 +  setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
   1.694 +  luaC_barriert(L, hvalue(o), L->top-1);
   1.695 +  L->top--;
   1.696 +  lua_unlock(L);
   1.697 +}
   1.698 +
   1.699 +
   1.700 +LUA_API int lua_setmetatable (lua_State *L, int objindex) {
   1.701 +  TValue *obj;
   1.702 +  Table *mt;
   1.703 +  lua_lock(L);
   1.704 +  api_checknelems(L, 1);
   1.705 +  obj = index2adr(L, objindex);
   1.706 +  api_checkvalidindex(L, obj);
   1.707 +  if (ttisnil(L->top - 1))
   1.708 +    mt = NULL;
   1.709 +  else {
   1.710 +    api_check(L, ttistable(L->top - 1));
   1.711 +    mt = hvalue(L->top - 1);
   1.712 +  }
   1.713 +  switch (ttype(obj)) {
   1.714 +    case LUA_TTABLE: {
   1.715 +      hvalue(obj)->metatable = mt;
   1.716 +      if (mt)
   1.717 +        luaC_objbarriert(L, hvalue(obj), mt);
   1.718 +      break;
   1.719 +    }
   1.720 +    case LUA_TUSERDATA: {
   1.721 +      uvalue(obj)->metatable = mt;
   1.722 +      if (mt)
   1.723 +        luaC_objbarrier(L, rawuvalue(obj), mt);
   1.724 +      break;
   1.725 +    }
   1.726 +    default: {
   1.727 +      G(L)->mt[ttype(obj)] = mt;
   1.728 +      break;
   1.729 +    }
   1.730 +  }
   1.731 +  L->top--;
   1.732 +  lua_unlock(L);
   1.733 +  return 1;
   1.734 +}
   1.735 +
   1.736 +
   1.737 +LUA_API int lua_setfenv (lua_State *L, int idx) {
   1.738 +  StkId o;
   1.739 +  int res = 1;
   1.740 +  lua_lock(L);
   1.741 +  api_checknelems(L, 1);
   1.742 +  o = index2adr(L, idx);
   1.743 +  api_checkvalidindex(L, o);
   1.744 +  api_check(L, ttistable(L->top - 1));
   1.745 +  switch (ttype(o)) {
   1.746 +    case LUA_TFUNCTION:
   1.747 +      clvalue(o)->c.env = hvalue(L->top - 1);
   1.748 +      break;
   1.749 +    case LUA_TUSERDATA:
   1.750 +      uvalue(o)->env = hvalue(L->top - 1);
   1.751 +      break;
   1.752 +    case LUA_TTHREAD:
   1.753 +      sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1));
   1.754 +      break;
   1.755 +    default:
   1.756 +      res = 0;
   1.757 +      break;
   1.758 +  }
   1.759 +  if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
   1.760 +  L->top--;
   1.761 +  lua_unlock(L);
   1.762 +  return res;
   1.763 +}
   1.764 +
   1.765 +
   1.766 +/*
   1.767 +** `load' and `call' functions (run Lua code)
   1.768 +*/
   1.769 +
   1.770 +
   1.771 +#define adjustresults(L,nres) \
   1.772 +    { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; }
   1.773 +
   1.774 +
   1.775 +#define checkresults(L,na,nr) \
   1.776 +     api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
   1.777 +	
   1.778 +
   1.779 +LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
   1.780 +  StkId func;
   1.781 +  lua_lock(L);
   1.782 +  api_checknelems(L, nargs+1);
   1.783 +  checkresults(L, nargs, nresults);
   1.784 +  func = L->top - (nargs+1);
   1.785 +  luaD_call(L, func, nresults);
   1.786 +  adjustresults(L, nresults);
   1.787 +  lua_unlock(L);
   1.788 +}
   1.789 +
   1.790 +
   1.791 +
   1.792 +/*
   1.793 +** Execute a protected call.
   1.794 +*/
   1.795 +struct CallS {  /* data to `f_call' */
   1.796 +  StkId func;
   1.797 +  int nresults;
   1.798 +};
   1.799 +
   1.800 +
   1.801 +static void f_call (lua_State *L, void *ud) {
   1.802 +  struct CallS *c = cast(struct CallS *, ud);
   1.803 +  luaD_call(L, c->func, c->nresults);
   1.804 +}
   1.805 +
   1.806 +
   1.807 +
   1.808 +LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
   1.809 +  struct CallS c;
   1.810 +  int status;
   1.811 +  ptrdiff_t func;
   1.812 +  lua_lock(L);
   1.813 +  api_checknelems(L, nargs+1);
   1.814 +  checkresults(L, nargs, nresults);
   1.815 +  if (errfunc == 0)
   1.816 +    func = 0;
   1.817 +  else {
   1.818 +    StkId o = index2adr(L, errfunc);
   1.819 +    api_checkvalidindex(L, o);
   1.820 +    func = savestack(L, o);
   1.821 +  }
   1.822 +  c.func = L->top - (nargs+1);  /* function to be called */
   1.823 +  c.nresults = nresults;
   1.824 +  status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
   1.825 +  adjustresults(L, nresults);
   1.826 +  lua_unlock(L);
   1.827 +  return status;
   1.828 +}
   1.829 +
   1.830 +
   1.831 +/*
   1.832 +** Execute a protected C call.
   1.833 +*/
   1.834 +struct CCallS {  /* data to `f_Ccall' */
   1.835 +  lua_CFunction func;
   1.836 +  void *ud;
   1.837 +};
   1.838 +
   1.839 +
   1.840 +static void f_Ccall (lua_State *L, void *ud) {
   1.841 +  struct CCallS *c = cast(struct CCallS *, ud);
   1.842 +  Closure *cl;
   1.843 +  cl = luaF_newCclosure(L, 0, getcurrenv(L));
   1.844 +  cl->c.f = c->func;
   1.845 +  setclvalue(L, L->top, cl);  /* push function */
   1.846 +  api_incr_top(L);
   1.847 +  setpvalue(L->top, c->ud);  /* push only argument */
   1.848 +  api_incr_top(L);
   1.849 +  luaD_call(L, L->top - 2, 0);
   1.850 +}
   1.851 +
   1.852 +
   1.853 +LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
   1.854 +  struct CCallS c;
   1.855 +  int status;
   1.856 +  lua_lock(L);
   1.857 +  c.func = func;
   1.858 +  c.ud = ud;
   1.859 +  status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
   1.860 +  lua_unlock(L);
   1.861 +  return status;
   1.862 +}
   1.863 +
   1.864 +
   1.865 +LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
   1.866 +                      const char *chunkname) {
   1.867 +  ZIO z;
   1.868 +  int status;
   1.869 +  lua_lock(L);
   1.870 +  if (!chunkname) chunkname = "?";
   1.871 +  luaZ_init(L, &z, reader, data);
   1.872 +  status = luaD_protectedparser(L, &z, chunkname);
   1.873 +  lua_unlock(L);
   1.874 +  return status;
   1.875 +}
   1.876 +
   1.877 +
   1.878 +LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
   1.879 +  int status;
   1.880 +  TValue *o;
   1.881 +  lua_lock(L);
   1.882 +  api_checknelems(L, 1);
   1.883 +  o = L->top - 1;
   1.884 +  if (isLfunction(o))
   1.885 +    status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
   1.886 +  else
   1.887 +    status = 1;
   1.888 +  lua_unlock(L);
   1.889 +  return status;
   1.890 +}
   1.891 +
   1.892 +
   1.893 +LUA_API int  lua_status (lua_State *L) {
   1.894 +  return L->status;
   1.895 +}
   1.896 +
   1.897 +
   1.898 +/*
   1.899 +** Garbage-collection function
   1.900 +*/
   1.901 +
   1.902 +LUA_API int lua_gc (lua_State *L, int what, int data) {
   1.903 +  int res = 0;
   1.904 +  global_State *g;
   1.905 +  lua_lock(L);
   1.906 +  g = G(L);
   1.907 +  switch (what) {
   1.908 +    case LUA_GCSTOP: {
   1.909 +      g->GCthreshold = MAX_LUMEM;
   1.910 +      break;
   1.911 +    }
   1.912 +    case LUA_GCRESTART: {
   1.913 +      g->GCthreshold = g->totalbytes;
   1.914 +      break;
   1.915 +    }
   1.916 +    case LUA_GCCOLLECT: {
   1.917 +      luaC_fullgc(L);
   1.918 +      break;
   1.919 +    }
   1.920 +    case LUA_GCCOUNT: {
   1.921 +      /* GC values are expressed in Kbytes: #bytes/2^10 */
   1.922 +      res = cast_int(g->totalbytes >> 10);
   1.923 +      break;
   1.924 +    }
   1.925 +    case LUA_GCCOUNTB: {
   1.926 +      res = cast_int(g->totalbytes & 0x3ff);
   1.927 +      break;
   1.928 +    }
   1.929 +    case LUA_GCSTEP: {
   1.930 +      lu_mem a = (cast(lu_mem, data) << 10);
   1.931 +      if (a <= g->totalbytes)
   1.932 +        g->GCthreshold = g->totalbytes - a;
   1.933 +      else
   1.934 +        g->GCthreshold = 0;
   1.935 +      while (g->GCthreshold <= g->totalbytes) {
   1.936 +        luaC_step(L);
   1.937 +        if (g->gcstate == GCSpause) {  /* end of cycle? */
   1.938 +          res = 1;  /* signal it */
   1.939 +          break;
   1.940 +        }
   1.941 +      }
   1.942 +      break;
   1.943 +    }
   1.944 +    case LUA_GCSETPAUSE: {
   1.945 +      res = g->gcpause;
   1.946 +      g->gcpause = data;
   1.947 +      break;
   1.948 +    }
   1.949 +    case LUA_GCSETSTEPMUL: {
   1.950 +      res = g->gcstepmul;
   1.951 +      g->gcstepmul = data;
   1.952 +      break;
   1.953 +    }
   1.954 +    default: res = -1;  /* invalid option */
   1.955 +  }
   1.956 +  lua_unlock(L);
   1.957 +  return res;
   1.958 +}
   1.959 +
   1.960 +
   1.961 +
   1.962 +/*
   1.963 +** miscellaneous functions
   1.964 +*/
   1.965 +
   1.966 +
   1.967 +LUA_API int lua_error (lua_State *L) {
   1.968 +  lua_lock(L);
   1.969 +  api_checknelems(L, 1);
   1.970 +  luaG_errormsg(L);
   1.971 +  lua_unlock(L);
   1.972 +  return 0;  /* to avoid warnings */
   1.973 +}
   1.974 +
   1.975 +
   1.976 +LUA_API int lua_next (lua_State *L, int idx) {
   1.977 +  StkId t;
   1.978 +  int more;
   1.979 +  lua_lock(L);
   1.980 +  t = index2adr(L, idx);
   1.981 +  api_check(L, ttistable(t));
   1.982 +  more = luaH_next(L, hvalue(t), L->top - 1);
   1.983 +  if (more) {
   1.984 +    api_incr_top(L);
   1.985 +  }
   1.986 +  else  /* no more elements */
   1.987 +    L->top -= 1;  /* remove key */
   1.988 +  lua_unlock(L);
   1.989 +  return more;
   1.990 +}
   1.991 +
   1.992 +
   1.993 +LUA_API void lua_concat (lua_State *L, int n) {
   1.994 +  lua_lock(L);
   1.995 +  api_checknelems(L, n);
   1.996 +  if (n >= 2) {
   1.997 +    luaC_checkGC(L);
   1.998 +    luaV_concat(L, n, cast_int(L->top - L->base) - 1);
   1.999 +    L->top -= (n-1);
  1.1000 +  }
  1.1001 +  else if (n == 0) {  /* push empty string */
  1.1002 +    setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
  1.1003 +    api_incr_top(L);
  1.1004 +  }
  1.1005 +  /* else n == 1; nothing to do */
  1.1006 +  lua_unlock(L);
  1.1007 +}
  1.1008 +
  1.1009 +
  1.1010 +LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
  1.1011 +  lua_Alloc f;
  1.1012 +  lua_lock(L);
  1.1013 +  if (ud) *ud = G(L)->ud;
  1.1014 +  f = G(L)->frealloc;
  1.1015 +  lua_unlock(L);
  1.1016 +  return f;
  1.1017 +}
  1.1018 +
  1.1019 +
  1.1020 +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
  1.1021 +  lua_lock(L);
  1.1022 +  G(L)->ud = ud;
  1.1023 +  G(L)->frealloc = f;
  1.1024 +  lua_unlock(L);
  1.1025 +}
  1.1026 +
  1.1027 +
  1.1028 +LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
  1.1029 +  Udata *u;
  1.1030 +  lua_lock(L);
  1.1031 +  luaC_checkGC(L);
  1.1032 +  u = luaS_newudata(L, size, getcurrenv(L));
  1.1033 +  setuvalue(L, L->top, u);
  1.1034 +  api_incr_top(L);
  1.1035 +  lua_unlock(L);
  1.1036 +  return u + 1;
  1.1037 +}
  1.1038 +
  1.1039 +
  1.1040 +
  1.1041 +
  1.1042 +static const char *aux_upvalue (StkId fi, int n, TValue **val) {
  1.1043 +  Closure *f;
  1.1044 +  if (!ttisfunction(fi)) return NULL;
  1.1045 +  f = clvalue(fi);
  1.1046 +  if (f->c.isC) {
  1.1047 +    if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
  1.1048 +    *val = &f->c.upvalue[n-1];
  1.1049 +    return "";
  1.1050 +  }
  1.1051 +  else {
  1.1052 +    Proto *p = f->l.p;
  1.1053 +    if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
  1.1054 +    *val = f->l.upvals[n-1]->v;
  1.1055 +    return getstr(p->upvalues[n-1]);
  1.1056 +  }
  1.1057 +}
  1.1058 +
  1.1059 +
  1.1060 +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
  1.1061 +  const char *name;
  1.1062 +  TValue *val;
  1.1063 +  lua_lock(L);
  1.1064 +  name = aux_upvalue(index2adr(L, funcindex), n, &val);
  1.1065 +  if (name) {
  1.1066 +    setobj2s(L, L->top, val);
  1.1067 +    api_incr_top(L);
  1.1068 +  }
  1.1069 +  lua_unlock(L);
  1.1070 +  return name;
  1.1071 +}
  1.1072 +
  1.1073 +
  1.1074 +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
  1.1075 +  const char *name;
  1.1076 +  TValue *val;
  1.1077 +  StkId fi;
  1.1078 +  lua_lock(L);
  1.1079 +  fi = index2adr(L, funcindex);
  1.1080 +  api_checknelems(L, 1);
  1.1081 +  name = aux_upvalue(fi, n, &val);
  1.1082 +  if (name) {
  1.1083 +    L->top--;
  1.1084 +    setobj(L, val, L->top);
  1.1085 +    luaC_barrier(L, clvalue(fi), L->top);
  1.1086 +  }
  1.1087 +  lua_unlock(L);
  1.1088 +  return name;
  1.1089 +}
  1.1090 +