Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ceguilua/src/lua-5.0.3/lua/lapi.c @ 1808

Last change on this file since 1808 was 1803, checked in by rgrieder, 16 years ago

added files for lua 5.1.3, lua 5.0.3, CEGUILua-0.6.1 and CEGUILua-0.5.0b

  • Property svn:eol-style set to native
File size: 18.6 KB
Line 
1/*
2** $Id: lapi.c,v 1.235a 2003/04/07 14:36:08 roberto Exp $
3** Lua API
4** See Copyright Notice in lua.h
5*/
6
7
8#include <assert.h>
9#include <string.h>
10
11#define lapi_c
12
13#include "lua.h"
14
15#include "lapi.h"
16#include "ldebug.h"
17#include "ldo.h"
18#include "lfunc.h"
19#include "lgc.h"
20#include "lmem.h"
21#include "lobject.h"
22#include "lstate.h"
23#include "lstring.h"
24#include "ltable.h"
25#include "ltm.h"
26#include "lundump.h"
27#include "lvm.h"
28
29
30const char lua_ident[] =
31  "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
32  "$Authors: " LUA_AUTHORS " $\n"
33  "$URL: www.lua.org $\n";
34
35
36
37#ifndef api_check
38#define api_check(L, o)         /*{ assert(o); }*/
39#endif
40
41#define api_checknelems(L, n)   api_check(L, (n) <= (L->top - L->base))
42
43#define api_incr_top(L)   {api_check(L, L->top < L->ci->top); L->top++;}
44
45
46
47
48static TObject *negindex (lua_State *L, int idx) {
49  if (idx > LUA_REGISTRYINDEX) {
50    api_check(L, idx != 0 && -idx <= L->top - L->base);
51    return L->top+idx;
52  }
53  else switch (idx) {  /* pseudo-indices */
54    case LUA_REGISTRYINDEX: return registry(L);
55    case LUA_GLOBALSINDEX: return gt(L);
56    default: {
57      TObject *func = (L->base - 1);
58      idx = LUA_GLOBALSINDEX - idx;
59      lua_assert(iscfunction(func));
60      return (idx <= clvalue(func)->c.nupvalues)
61                ? &clvalue(func)->c.upvalue[idx-1]
62                : NULL;
63    }
64  }
65}
66
67
68static TObject *luaA_index (lua_State *L, int idx) {
69  if (idx > 0) {
70    api_check(L, idx <= L->top - L->base);
71    return L->base + idx - 1;
72  }
73  else {
74    TObject *o = negindex(L, idx);
75    api_check(L, o != NULL);
76    return o;
77  }
78}
79
80
81static TObject *luaA_indexAcceptable (lua_State *L, int idx) {
82  if (idx > 0) {
83    TObject *o = L->base+(idx-1);
84    api_check(L, idx <= L->stack_last - L->base);
85    if (o >= L->top) return NULL;
86    else return o;
87  }
88  else
89    return negindex(L, idx);
90}
91
92
93void luaA_pushobject (lua_State *L, const TObject *o) {
94  setobj2s(L->top, o);
95  incr_top(L);
96}
97
98
99LUA_API int lua_checkstack (lua_State *L, int size) {
100  int res;
101  lua_lock(L);
102  if ((L->top - L->base + size) > LUA_MAXCSTACK)
103    res = 0;  /* stack overflow */
104  else {
105    luaD_checkstack(L, size);
106    if (L->ci->top < L->top + size)
107      L->ci->top = L->top + size;
108    res = 1;
109  }
110  lua_unlock(L);
111  return res;
112}
113
114
115LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
116  int i;
117  lua_lock(to);
118  api_checknelems(from, n);
119  from->top -= n;
120  for (i = 0; i < n; i++) {
121    setobj2s(to->top, from->top + i);
122    api_incr_top(to);
123  }
124  lua_unlock(to);
125}
126
127
128LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
129  lua_CFunction old;
130  lua_lock(L);
131  old = G(L)->panic;
132  G(L)->panic = panicf;
133  lua_unlock(L);
134  return old;
135}
136
137
138LUA_API lua_State *lua_newthread (lua_State *L) {
139  lua_State *L1;
140  lua_lock(L);
141  luaC_checkGC(L);
142  L1 = luaE_newthread(L);
143  setthvalue(L->top, L1);
144  api_incr_top(L);
145  lua_unlock(L);
146  lua_userstateopen(L1);
147  return L1;
148}
149
150
151
152/*
153** basic stack manipulation
154*/
155
156
157LUA_API int lua_gettop (lua_State *L) {
158  return (L->top - L->base);
159}
160
161
162LUA_API void lua_settop (lua_State *L, int idx) {
163  lua_lock(L);
164  if (idx >= 0) {
165    api_check(L, idx <= L->stack_last - L->base);
166    while (L->top < L->base + idx)
167      setnilvalue(L->top++);
168    L->top = L->base + idx;
169  }
170  else {
171    api_check(L, -(idx+1) <= (L->top - L->base));
172    L->top += idx+1;  /* `subtract' index (index is negative) */
173  }
174  lua_unlock(L);
175}
176
177
178LUA_API void lua_remove (lua_State *L, int idx) {
179  StkId p;
180  lua_lock(L);
181  p = luaA_index(L, idx);
182  while (++p < L->top) setobjs2s(p-1, p);
183  L->top--;
184  lua_unlock(L);
185}
186
187
188LUA_API void lua_insert (lua_State *L, int idx) {
189  StkId p;
190  StkId q;
191  lua_lock(L);
192  p = luaA_index(L, idx);
193  for (q = L->top; q>p; q--) setobjs2s(q, q-1);
194  setobjs2s(p, L->top);
195  lua_unlock(L);
196}
197
198
199LUA_API void lua_replace (lua_State *L, int idx) {
200  lua_lock(L);
201  api_checknelems(L, 1);
202  setobj(luaA_index(L, idx), L->top - 1);  /* write barrier */
203  L->top--;
204  lua_unlock(L);
205}
206
207
208LUA_API void lua_pushvalue (lua_State *L, int idx) {
209  lua_lock(L);
210  setobj2s(L->top, luaA_index(L, idx));
211  api_incr_top(L);
212  lua_unlock(L);
213}
214
215
216
217/*
218** access functions (stack -> C)
219*/
220
221
222LUA_API int lua_type (lua_State *L, int idx) {
223  StkId o = luaA_indexAcceptable(L, idx);
224  return (o == NULL) ? LUA_TNONE : ttype(o);
225}
226
227
228LUA_API const char *lua_typename (lua_State *L, int t) {
229  UNUSED(L);
230  return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
231}
232
233
234LUA_API int lua_iscfunction (lua_State *L, int idx) {
235  StkId o = luaA_indexAcceptable(L, idx);
236  return (o == NULL) ? 0 : iscfunction(o);
237}
238
239
240LUA_API int lua_isnumber (lua_State *L, int idx) {
241  TObject n;
242  const TObject *o = luaA_indexAcceptable(L, idx);
243  return (o != NULL && tonumber(o, &n));
244}
245
246
247LUA_API int lua_isstring (lua_State *L, int idx) {
248  int t = lua_type(L, idx);
249  return (t == LUA_TSTRING || t == LUA_TNUMBER);
250}
251
252
253LUA_API int lua_isuserdata (lua_State *L, int idx) {
254  const TObject *o = luaA_indexAcceptable(L, idx);
255  return (o != NULL && (ttisuserdata(o) || ttislightuserdata(o)));
256}
257
258
259LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
260  StkId o1 = luaA_indexAcceptable(L, index1);
261  StkId o2 = luaA_indexAcceptable(L, index2);
262  return (o1 == NULL || o2 == NULL) ? 0  /* index out of range */
263                                    : luaO_rawequalObj(o1, o2);
264}
265
266
267LUA_API int lua_equal (lua_State *L, int index1, int index2) {
268  StkId o1, o2;
269  int i;
270  lua_lock(L);  /* may call tag method */
271  o1 = luaA_indexAcceptable(L, index1);
272  o2 = luaA_indexAcceptable(L, index2);
273  i = (o1 == NULL || o2 == NULL) ? 0  /* index out of range */
274                                 : equalobj(L, o1, o2);
275  lua_unlock(L);
276  return i;
277}
278
279
280LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
281  StkId o1, o2;
282  int i;
283  lua_lock(L);  /* may call tag method */
284  o1 = luaA_indexAcceptable(L, index1);
285  o2 = luaA_indexAcceptable(L, index2);
286  i = (o1 == NULL || o2 == NULL) ? 0  /* index out-of-range */
287                                 : luaV_lessthan(L, o1, o2);
288  lua_unlock(L);
289  return i;
290}
291
292
293
294LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
295  TObject n;
296  const TObject *o = luaA_indexAcceptable(L, idx);
297  if (o != NULL && tonumber(o, &n))
298    return nvalue(o);
299  else
300    return 0;
301}
302
303
304LUA_API int lua_toboolean (lua_State *L, int idx) {
305  const TObject *o = luaA_indexAcceptable(L, idx);
306  return (o != NULL) && !l_isfalse(o);
307}
308
309
310LUA_API const char *lua_tostring (lua_State *L, int idx) {
311  StkId o = luaA_indexAcceptable(L, idx);
312  if (o == NULL)
313    return NULL;
314  else if (ttisstring(o))
315    return svalue(o);
316  else {
317    const char *s;
318    lua_lock(L);  /* `luaV_tostring' may create a new string */
319    s = (luaV_tostring(L, o) ? svalue(o) : NULL);
320    luaC_checkGC(L);
321    lua_unlock(L);
322    return s;
323  }
324}
325
326
327LUA_API size_t lua_strlen (lua_State *L, int idx) {
328  StkId o = luaA_indexAcceptable(L, idx);
329  if (o == NULL)
330    return 0;
331  else if (ttisstring(o))
332    return tsvalue(o)->tsv.len;
333  else {
334    size_t l;
335    lua_lock(L);  /* `luaV_tostring' may create a new string */
336    l = (luaV_tostring(L, o) ? tsvalue(o)->tsv.len : 0);
337    lua_unlock(L);
338    return l;
339  }
340}
341
342
343LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
344  StkId o = luaA_indexAcceptable(L, idx);
345  return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->c.f;
346}
347
348
349LUA_API void *lua_touserdata (lua_State *L, int idx) {
350  StkId o = luaA_indexAcceptable(L, idx);
351  if (o == NULL) return NULL;
352  switch (ttype(o)) {
353    case LUA_TUSERDATA: return (uvalue(o) + 1);
354    case LUA_TLIGHTUSERDATA: return pvalue(o);
355    default: return NULL;
356  }
357}
358
359
360LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
361  StkId o = luaA_indexAcceptable(L, idx);
362  return (o == NULL || !ttisthread(o)) ? NULL : thvalue(o);
363}
364
365
366LUA_API const void *lua_topointer (lua_State *L, int idx) {
367  StkId o = luaA_indexAcceptable(L, idx);
368  if (o == NULL) return NULL;
369  else {
370    switch (ttype(o)) {
371      case LUA_TTABLE: return hvalue(o);
372      case LUA_TFUNCTION: return clvalue(o);
373      case LUA_TTHREAD: return thvalue(o);
374      case LUA_TUSERDATA:
375      case LUA_TLIGHTUSERDATA:
376        return lua_touserdata(L, idx);
377      default: return NULL;
378    }
379  }
380}
381
382
383
384/*
385** push functions (C -> stack)
386*/
387
388
389LUA_API void lua_pushnil (lua_State *L) {
390  lua_lock(L);
391  setnilvalue(L->top);
392  api_incr_top(L);
393  lua_unlock(L);
394}
395
396
397LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
398  lua_lock(L);
399  setnvalue(L->top, n);
400  api_incr_top(L);
401  lua_unlock(L);
402}
403
404
405LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
406  lua_lock(L);
407  luaC_checkGC(L);
408  setsvalue2s(L->top, luaS_newlstr(L, s, len));
409  api_incr_top(L);
410  lua_unlock(L);
411}
412
413
414LUA_API void lua_pushstring (lua_State *L, const char *s) {
415  if (s == NULL)
416    lua_pushnil(L);
417  else
418    lua_pushlstring(L, s, strlen(s));
419}
420
421
422LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
423                                      va_list argp) {
424  const char *ret;
425  lua_lock(L);
426  luaC_checkGC(L);
427  ret = luaO_pushvfstring(L, fmt, argp);
428  lua_unlock(L);
429  return ret;
430}
431
432
433LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
434  const char *ret;
435  va_list argp;
436  lua_lock(L);
437  luaC_checkGC(L);
438  va_start(argp, fmt);
439  ret = luaO_pushvfstring(L, fmt, argp);
440  va_end(argp);
441  lua_unlock(L);
442  return ret;
443}
444
445
446LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
447  Closure *cl;
448  lua_lock(L);
449  luaC_checkGC(L);
450  api_checknelems(L, n);
451  cl = luaF_newCclosure(L, n);
452  cl->c.f = fn;
453  L->top -= n;
454  while (n--)
455    setobj2n(&cl->c.upvalue[n], L->top+n);
456  setclvalue(L->top, cl);
457  api_incr_top(L);
458  lua_unlock(L);
459}
460
461
462LUA_API void lua_pushboolean (lua_State *L, int b) {
463  lua_lock(L);
464  setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
465  api_incr_top(L);
466  lua_unlock(L);
467}
468
469
470LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
471  lua_lock(L);
472  setpvalue(L->top, p);
473  api_incr_top(L);
474  lua_unlock(L);
475}
476
477
478
479/*
480** get functions (Lua -> stack)
481*/
482
483
484LUA_API void lua_gettable (lua_State *L, int idx) {
485  StkId t;
486  lua_lock(L);
487  t = luaA_index(L, idx);
488  setobj2s(L->top - 1, luaV_gettable(L, t, L->top - 1, 0));
489  lua_unlock(L);
490}
491
492
493LUA_API void lua_rawget (lua_State *L, int idx) {
494  StkId t;
495  lua_lock(L);
496  t = luaA_index(L, idx);
497  api_check(L, ttistable(t));
498  setobj2s(L->top - 1, luaH_get(hvalue(t), L->top - 1));
499  lua_unlock(L);
500}
501
502
503LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
504  StkId o;
505  lua_lock(L);
506  o = luaA_index(L, idx);
507  api_check(L, ttistable(o));
508  setobj2s(L->top, luaH_getnum(hvalue(o), n));
509  api_incr_top(L);
510  lua_unlock(L);
511}
512
513
514LUA_API void lua_newtable (lua_State *L) {
515  lua_lock(L);
516  luaC_checkGC(L);
517  sethvalue(L->top, luaH_new(L, 0, 0));
518  api_incr_top(L);
519  lua_unlock(L);
520}
521
522
523LUA_API int lua_getmetatable (lua_State *L, int objindex) {
524  const TObject *obj;
525  Table *mt = NULL;
526  int res;
527  lua_lock(L);
528  obj = luaA_indexAcceptable(L, objindex);
529  if (obj != NULL) {
530    switch (ttype(obj)) {
531      case LUA_TTABLE:
532        mt = hvalue(obj)->metatable;
533        break;
534      case LUA_TUSERDATA:
535        mt = uvalue(obj)->uv.metatable;
536        break;
537    }
538  }
539  if (mt == NULL || mt == hvalue(defaultmeta(L)))
540    res = 0;
541  else {
542    sethvalue(L->top, mt);
543    api_incr_top(L);
544    res = 1;
545  }
546  lua_unlock(L);
547  return res;
548}
549
550
551LUA_API void lua_getfenv (lua_State *L, int idx) {
552  StkId o;
553  lua_lock(L);
554  o = luaA_index(L, idx);
555  setobj2s(L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L));
556  api_incr_top(L);
557  lua_unlock(L);
558}
559
560
561/*
562** set functions (stack -> Lua)
563*/
564
565
566LUA_API void lua_settable (lua_State *L, int idx) {
567  StkId t;
568  lua_lock(L);
569  api_checknelems(L, 2);
570  t = luaA_index(L, idx);
571  luaV_settable(L, t, L->top - 2, L->top - 1);
572  L->top -= 2;  /* pop index and value */
573  lua_unlock(L);
574}
575
576
577LUA_API void lua_rawset (lua_State *L, int idx) {
578  StkId t;
579  lua_lock(L);
580  api_checknelems(L, 2);
581  t = luaA_index(L, idx);
582  api_check(L, ttistable(t));
583  setobj2t(luaH_set(L, hvalue(t), L->top-2), L->top-1);  /* write barrier */
584  L->top -= 2;
585  lua_unlock(L);
586}
587
588
589LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
590  StkId o;
591  lua_lock(L);
592  api_checknelems(L, 1);
593  o = luaA_index(L, idx);
594  api_check(L, ttistable(o));
595  setobj2t(luaH_setnum(L, hvalue(o), n), L->top-1);  /* write barrier */
596  L->top--;
597  lua_unlock(L);
598}
599
600
601LUA_API int lua_setmetatable (lua_State *L, int objindex) {
602  TObject *obj, *mt;
603  int res = 1;
604  lua_lock(L);
605  api_checknelems(L, 1);
606  obj = luaA_index(L, objindex);
607  mt = (!ttisnil(L->top - 1)) ? L->top - 1 : defaultmeta(L);
608  api_check(L, ttistable(mt));
609  switch (ttype(obj)) {
610    case LUA_TTABLE: {
611      hvalue(obj)->metatable = hvalue(mt);  /* write barrier */
612      break;
613    }
614    case LUA_TUSERDATA: {
615      uvalue(obj)->uv.metatable = hvalue(mt);  /* write barrier */
616      break;
617    }
618    default: {
619      res = 0;  /* cannot set */
620      break;
621    }
622  }
623  L->top--;
624  lua_unlock(L);
625  return res;
626}
627
628
629LUA_API int lua_setfenv (lua_State *L, int idx) {
630  StkId o;
631  int res = 0;
632  lua_lock(L);
633  api_checknelems(L, 1);
634  o = luaA_index(L, idx);
635  L->top--;
636  api_check(L, ttistable(L->top));
637  if (isLfunction(o)) {
638    res = 1;
639    clvalue(o)->l.g = *(L->top);
640  }
641  lua_unlock(L);
642  return res;
643}
644
645
646/*
647** `load' and `call' functions (run Lua code)
648*/
649
650LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
651  StkId func;
652  lua_lock(L);
653  api_checknelems(L, nargs+1);
654  func = L->top - (nargs+1);
655  luaD_call(L, func, nresults);
656  lua_unlock(L);
657}
658
659
660
661/*
662** Execute a protected call.
663*/
664struct CallS {  /* data to `f_call' */
665  StkId func;
666  int nresults;
667};
668
669
670static void f_call (lua_State *L, void *ud) {
671  struct CallS *c = cast(struct CallS *, ud);
672  luaD_call(L, c->func, c->nresults);
673}
674
675
676
677LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
678  struct CallS c;
679  int status;
680  ptrdiff_t func;
681  lua_lock(L);
682  func = (errfunc == 0) ? 0 : savestack(L, luaA_index(L, errfunc));
683  c.func = L->top - (nargs+1);  /* function to be called */
684  c.nresults = nresults;
685  status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
686  lua_unlock(L);
687  return status;
688}
689
690
691/*
692** Execute a protected C call.
693*/
694struct CCallS {  /* data to `f_Ccall' */
695  lua_CFunction func;
696  void *ud;
697};
698
699
700static void f_Ccall (lua_State *L, void *ud) {
701  struct CCallS *c = cast(struct CCallS *, ud);
702  Closure *cl;
703  cl = luaF_newCclosure(L, 0);
704  cl->c.f = c->func;
705  setclvalue(L->top, cl);  /* push function */
706  incr_top(L);
707  setpvalue(L->top, c->ud);  /* push only argument */
708  incr_top(L);
709  luaD_call(L, L->top - 2, 0);
710}
711
712
713LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
714  struct CCallS c;
715  int status;
716  lua_lock(L);
717  c.func = func;
718  c.ud = ud;
719  status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
720  lua_unlock(L);
721  return status;
722}
723
724
725LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data,
726                      const char *chunkname) {
727  ZIO z;
728  int status;
729  int c;
730  lua_lock(L);
731  if (!chunkname) chunkname = "?";
732  luaZ_init(&z, reader, data, chunkname);
733  c = luaZ_lookahead(&z);
734  status = luaD_protectedparser(L, &z, (c == LUA_SIGNATURE[0]));
735  lua_unlock(L);
736  return status;
737}
738
739
740LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data) {
741  int status;
742  TObject *o;
743  lua_lock(L);
744  api_checknelems(L, 1);
745  o = L->top - 1;
746  if (isLfunction(o) && clvalue(o)->l.nupvalues == 0) {
747    luaU_dump(L, clvalue(o)->l.p, writer, data);
748    status = 1;
749  }
750  else
751    status = 0;
752  lua_unlock(L);
753  return status;
754}
755
756
757/*
758** Garbage-collection functions
759*/
760
761/* GC values are expressed in Kbytes: #bytes/2^10 */
762#define GCscalel(x)             ((x)>>10)
763#define GCscale(x)              (cast(int, GCscalel(x)))
764#define GCunscale(x)            (cast(lu_mem, x)<<10)
765
766LUA_API int lua_getgcthreshold (lua_State *L) {
767  int threshold;
768  lua_lock(L);
769  threshold = GCscale(G(L)->GCthreshold);
770  lua_unlock(L);
771  return threshold;
772}
773
774LUA_API int lua_getgccount (lua_State *L) {
775  int count;
776  lua_lock(L);
777  count = GCscale(G(L)->nblocks);
778  lua_unlock(L);
779  return count;
780}
781
782LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
783  lua_lock(L);
784  if (cast(lu_mem, newthreshold) > GCscalel(MAX_LUMEM))
785    G(L)->GCthreshold = MAX_LUMEM;
786  else
787    G(L)->GCthreshold = GCunscale(newthreshold);
788  luaC_checkGC(L);
789  lua_unlock(L);
790}
791
792
793/*
794** miscellaneous functions
795*/
796
797
798LUA_API const char *lua_version (void) {
799  return LUA_VERSION;
800}
801
802
803LUA_API int lua_error (lua_State *L) {
804  lua_lock(L);
805  api_checknelems(L, 1);
806  luaG_errormsg(L);
807  lua_unlock(L);
808  return 0;  /* to avoid warnings */
809}
810
811
812LUA_API int lua_next (lua_State *L, int idx) {
813  StkId t;
814  int more;
815  lua_lock(L);
816  t = luaA_index(L, idx);
817  api_check(L, ttistable(t));
818  more = luaH_next(L, hvalue(t), L->top - 1);
819  if (more) {
820    api_incr_top(L);
821  }
822  else  /* no more elements */
823    L->top -= 1;  /* remove key */
824  lua_unlock(L);
825  return more;
826}
827
828
829LUA_API void lua_concat (lua_State *L, int n) {
830  lua_lock(L);
831  luaC_checkGC(L);
832  api_checknelems(L, n);
833  if (n >= 2) {
834    luaV_concat(L, n, L->top - L->base - 1);
835    L->top -= (n-1);
836  }
837  else if (n == 0) {  /* push empty string */
838    setsvalue2s(L->top, luaS_newlstr(L, NULL, 0));
839    api_incr_top(L);
840  }
841  /* else n == 1; nothing to do */
842  lua_unlock(L);
843}
844
845
846LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
847  Udata *u;
848  lua_lock(L);
849  luaC_checkGC(L);
850  u = luaS_newudata(L, size);
851  setuvalue(L->top, u);
852  api_incr_top(L);
853  lua_unlock(L);
854  return u + 1;
855}
856
857
858LUA_API int lua_pushupvalues (lua_State *L) {
859  Closure *func;
860  int n, i;
861  lua_lock(L);
862  api_check(L, iscfunction(L->base - 1));
863  func = clvalue(L->base - 1);
864  n = func->c.nupvalues;
865  luaD_checkstack(L, n + LUA_MINSTACK);
866  for (i=0; i<n; i++) {
867    setobj2s(L->top, &func->c.upvalue[i]);
868    L->top++;
869  }
870  lua_unlock(L);
871  return n;
872}
873
874
875static const char *aux_upvalue (lua_State *L, int funcindex, int n,
876                                TObject **val) {
877  Closure *f;
878  StkId fi = luaA_index(L, funcindex);
879  if (!ttisfunction(fi)) return NULL;
880  f = clvalue(fi);
881  if (f->c.isC) {
882    if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
883    *val = &f->c.upvalue[n-1];
884    return "";
885  }
886  else {
887    Proto *p = f->l.p;
888    if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
889    *val = f->l.upvals[n-1]->v;
890    return getstr(p->upvalues[n-1]);
891  }
892}
893
894
895LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
896  const char *name;
897  TObject *val;
898  lua_lock(L);
899  name = aux_upvalue(L, funcindex, n, &val);
900  if (name) {
901    setobj2s(L->top, val);
902    api_incr_top(L);
903  }
904  lua_unlock(L);
905  return name;
906}
907
908
909LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
910  const char *name;
911  TObject *val;
912  lua_lock(L);
913  api_checknelems(L, 1);
914  name = aux_upvalue(L, funcindex, n, &val);
915  if (name) {
916    L->top--;
917    setobj(val, L->top);  /* write barrier */
918  }
919  lua_unlock(L);
920  return name;
921}
922
Note: See TracBrowser for help on using the repository browser.