Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/lua/lapi.c @ 2365

Last change on this file since 2365 was 1810, checked in by rgrieder, 16 years ago

merged ceguilua branch back to trunk

  • 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.