Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ceguilua/src/lua/lapi.c @ 2071

Last change on this file since 2071 was 1806, checked in by rgrieder, 16 years ago

added single 5.1.3 directory for lua since CEGUILua 0.5 can also build against lua 5.1

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