Mercurial > vba-clojure
diff src/lua/lapi.c @ 11:27763b933818
raise lua sources up one level
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 11:07:39 -0600 |
parents | src/lua/src/lapi.c@f9f4f1b99eed |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/lua/lapi.c Sat Mar 03 11:07:39 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 +