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