Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5205 clevermous 1
/*
2
** $Id: lapi.c,v 2.159 2011/11/30 12:32:05 roberto Exp $
3
** Lua API
4
** See Copyright Notice in lua.h
5
*/
6
 
7
 
8
#include 
9
#include 
10
 
11
#define lapi_c
12
#define LUA_CORE
13
 
14
#include "lua.h"
15
 
16
#include "lapi.h"
17
#include "ldebug.h"
18
#include "ldo.h"
19
#include "lfunc.h"
20
#include "lgc.h"
21
#include "lmem.h"
22
#include "lobject.h"
23
#include "lstate.h"
24
#include "lstring.h"
25
#include "ltable.h"
26
#include "ltm.h"
27
#include "lundump.h"
28
#include "lvm.h"
29
 
30
 
31
 
32
const char lua_ident[] =
33
  "$LuaVersion: " LUA_COPYRIGHT " $"
34
  "$LuaAuthors: " LUA_AUTHORS " $";
35
 
36
 
37
/* value at a non-valid index */
38
#define NONVALIDVALUE		cast(TValue *, luaO_nilobject)
39
 
40
/* corresponding test */
41
#define isvalid(o)	((o) != luaO_nilobject)
42
 
43
#define api_checkvalidindex(L, i)  api_check(L, isvalid(i), "invalid index")
44
 
45
 
46
static TValue *index2addr (lua_State *L, int idx) {
47
  CallInfo *ci = L->ci;
48
  if (idx > 0) {
49
    TValue *o = ci->func + idx;
50
    api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
51
    if (o >= L->top) return NONVALIDVALUE;
52
    else return o;
53
  }
54
  else if (idx > LUA_REGISTRYINDEX) {
55
    api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
56
    return L->top + idx;
57
  }
58
  else if (idx == LUA_REGISTRYINDEX)
59
    return &G(L)->l_registry;
60
  else {  /* upvalues */
61
    idx = LUA_REGISTRYINDEX - idx;
62
    api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
63
    if (ttislcf(ci->func))  /* light C function? */
64
      return NONVALIDVALUE;  /* it has no upvalues */
65
    else {
66
      CClosure *func = clCvalue(ci->func);
67
      return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE;
68
    }
69
  }
70
}
71
 
72
 
73
/*
74
** to be called by 'lua_checkstack' in protected mode, to grow stack
75
** capturing memory errors
76
*/
77
static void growstack (lua_State *L, void *ud) {
78
  int size = *(int *)ud;
79
  luaD_growstack(L, size);
80
}
81
 
82
 
83
LUA_API int lua_checkstack (lua_State *L, int size) {
84
  int res;
85
  CallInfo *ci = L->ci;
86
  lua_lock(L);
87
  if (L->stack_last - L->top > size)  /* stack large enough? */
88
    res = 1;  /* yes; check is OK */
89
  else {  /* no; need to grow stack */
90
    int inuse = cast_int(L->top - L->stack) + EXTRA_STACK;
91
    if (inuse > LUAI_MAXSTACK - size)  /* can grow without overflow? */
92
      res = 0;  /* no */
93
    else  /* try to grow stack */
94
      res = (luaD_rawrunprotected(L, &growstack, &size) == LUA_OK);
95
  }
96
  if (res && ci->top < L->top + size)
97
    ci->top = L->top + size;  /* adjust frame top */
98
  lua_unlock(L);
99
  return res;
100
}
101
 
102
 
103
LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
104
  int i;
105
  if (from == to) return;
106
  lua_lock(to);
107
  api_checknelems(from, n);
108
  api_check(from, G(from) == G(to), "moving among independent states");
109
  api_check(from, to->ci->top - to->top >= n, "not enough elements to move");
110
  from->top -= n;
111
  for (i = 0; i < n; i++) {
112
    setobj2s(to, to->top++, from->top + i);
113
  }
114
  lua_unlock(to);
115
}
116
 
117
 
118
LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
119
  lua_CFunction old;
120
  lua_lock(L);
121
  old = G(L)->panic;
122
  G(L)->panic = panicf;
123
  lua_unlock(L);
124
  return old;
125
}
126
 
127
 
128
LUA_API const lua_Number *lua_version (lua_State *L) {
129
  static const lua_Number version = LUA_VERSION_NUM;
130
  if (L == NULL) return &version;
131
  else return G(L)->version;
132
}
133
 
134
 
135
 
136
/*
137
** basic stack manipulation
138
*/
139
 
140
 
141
/*
142
** convert an acceptable stack index into an absolute index
143
*/
144
LUA_API int lua_absindex (lua_State *L, int idx) {
145
  return (idx > 0 || idx <= LUA_REGISTRYINDEX)
146
         ? idx
147
         : cast_int(L->top - L->ci->func + idx);
148
}
149
 
150
 
151
LUA_API int lua_gettop (lua_State *L) {
152
  return cast_int(L->top - (L->ci->func + 1));
153
}
154
 
155
 
156
LUA_API void lua_settop (lua_State *L, int idx) {
157
  StkId func = L->ci->func;
158
  lua_lock(L);
159
  if (idx >= 0) {
160
    api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
161
    while (L->top < (func + 1) + idx)
162
      setnilvalue(L->top++);
163
    L->top = (func + 1) + idx;
164
  }
165
  else {
166
    api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
167
    L->top += idx+1;  /* `subtract' index (index is negative) */
168
  }
169
  lua_unlock(L);
170
}
171
 
172
 
173
LUA_API void lua_remove (lua_State *L, int idx) {
174
  StkId p;
175
  lua_lock(L);
176
  p = index2addr(L, idx);
177
  api_checkvalidindex(L, p);
178
  while (++p < L->top) setobjs2s(L, p-1, p);
179
  L->top--;
180
  lua_unlock(L);
181
}
182
 
183
 
184
LUA_API void lua_insert (lua_State *L, int idx) {
185
  StkId p;
186
  StkId q;
187
  lua_lock(L);
188
  p = index2addr(L, idx);
189
  api_checkvalidindex(L, p);
190
  for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
191
  setobjs2s(L, p, L->top);
192
  lua_unlock(L);
193
}
194
 
195
 
196
static void moveto (lua_State *L, TValue *fr, int idx) {
197
  TValue *to = index2addr(L, idx);
198
  api_checkvalidindex(L, to);
199
  setobj(L, to, fr);
200
  if (idx < LUA_REGISTRYINDEX)  /* function upvalue? */
201
    luaC_barrier(L, clCvalue(L->ci->func), fr);
202
  /* LUA_REGISTRYINDEX does not need gc barrier
203
     (collector revisits it before finishing collection) */
204
}
205
 
206
 
207
LUA_API void lua_replace (lua_State *L, int idx) {
208
  lua_lock(L);
209
  api_checknelems(L, 1);
210
  moveto(L, L->top - 1, idx);
211
  L->top--;
212
  lua_unlock(L);
213
}
214
 
215
 
216
LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
217
  TValue *fr;
218
  lua_lock(L);
219
  fr = index2addr(L, fromidx);
220
  api_checkvalidindex(L, fr);
221
  moveto(L, fr, toidx);
222
  lua_unlock(L);
223
}
224
 
225
 
226
LUA_API void lua_pushvalue (lua_State *L, int idx) {
227
  lua_lock(L);
228
  setobj2s(L, L->top, index2addr(L, idx));
229
  api_incr_top(L);
230
  lua_unlock(L);
231
}
232
 
233
 
234
 
235
/*
236
** access functions (stack -> C)
237
*/
238
 
239
 
240
LUA_API int lua_type (lua_State *L, int idx) {
241
  StkId o = index2addr(L, idx);
242
  return (isvalid(o) ? ttypenv(o) : LUA_TNONE);
243
}
244
 
245
 
246
LUA_API const char *lua_typename (lua_State *L, int t) {
247
  UNUSED(L);
248
  return ttypename(t);
249
}
250
 
251
 
252
LUA_API int lua_iscfunction (lua_State *L, int idx) {
253
  StkId o = index2addr(L, idx);
254
  return (ttislcf(o) || (ttisCclosure(o)));
255
}
256
 
257
 
258
LUA_API int lua_isnumber (lua_State *L, int idx) {
259
  TValue n;
260
  const TValue *o = index2addr(L, idx);
261
  return tonumber(o, &n);
262
}
263
 
264
 
265
LUA_API int lua_isstring (lua_State *L, int idx) {
266
  int t = lua_type(L, idx);
267
  return (t == LUA_TSTRING || t == LUA_TNUMBER);
268
}
269
 
270
 
271
LUA_API int lua_isuserdata (lua_State *L, int idx) {
272
  const TValue *o = index2addr(L, idx);
273
  return (ttisuserdata(o) || ttislightuserdata(o));
274
}
275
 
276
 
277
LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
278
  StkId o1 = index2addr(L, index1);
279
  StkId o2 = index2addr(L, index2);
280
  return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0;
281
}
282
 
283
 
284
LUA_API void  lua_arith (lua_State *L, int op) {
285
  StkId o1;  /* 1st operand */
286
  StkId o2;  /* 2nd operand */
287
  lua_lock(L);
288
  if (op != LUA_OPUNM) /* all other operations expect two operands */
289
    api_checknelems(L, 2);
290
  else {  /* for unary minus, add fake 2nd operand */
291
    api_checknelems(L, 1);
292
    setobjs2s(L, L->top, L->top - 1);
293
    L->top++;
294
  }
295
  o1 = L->top - 2;
296
  o2 = L->top - 1;
297
  if (ttisnumber(o1) && ttisnumber(o2)) {
298
    changenvalue(o1, luaO_arith(op, nvalue(o1), nvalue(o2)));
299
  }
300
  else
301
    luaV_arith(L, o1, o1, o2, cast(TMS, op - LUA_OPADD + TM_ADD));
302
  L->top--;
303
  lua_unlock(L);
304
}
305
 
306
 
307
LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
308
  StkId o1, o2;
309
  int i = 0;
310
  lua_lock(L);  /* may call tag method */
311
  o1 = index2addr(L, index1);
312
  o2 = index2addr(L, index2);
313
  if (isvalid(o1) && isvalid(o2)) {
314
    switch (op) {
315
      case LUA_OPEQ: i = equalobj(L, o1, o2); break;
316
      case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
317
      case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
318
      default: api_check(L, 0, "invalid option");
319
    }
320
  }
321
  lua_unlock(L);
322
  return i;
323
}
324
 
325
 
326
LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum) {
327
  TValue n;
328
  const TValue *o = index2addr(L, idx);
329
  if (tonumber(o, &n)) {
330
    if (isnum) *isnum = 1;
331
    return nvalue(o);
332
  }
333
  else {
334
    if (isnum) *isnum = 0;
335
    return 0;
336
  }
337
}
338
 
339
 
340
LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) {
341
  TValue n;
342
  const TValue *o = index2addr(L, idx);
343
  if (tonumber(o, &n)) {
344
    lua_Integer res;
345
    lua_Number num = nvalue(o);
346
    lua_number2integer(res, num);
347
    if (isnum) *isnum = 1;
348
    return res;
349
  }
350
  else {
351
    if (isnum) *isnum = 0;
352
    return 0;
353
  }
354
}
355
 
356
 
357
LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) {
358
  TValue n;
359
  const TValue *o = index2addr(L, idx);
360
  if (tonumber(o, &n)) {
361
    lua_Unsigned res;
362
    lua_Number num = nvalue(o);
363
    lua_number2unsigned(res, num);
364
    if (isnum) *isnum = 1;
365
    return res;
366
  }
367
  else {
368
    if (isnum) *isnum = 0;
369
    return 0;
370
  }
371
}
372
 
373
 
374
LUA_API int lua_toboolean (lua_State *L, int idx) {
375
  const TValue *o = index2addr(L, idx);
376
  return !l_isfalse(o);
377
}
378
 
379
 
380
LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
381
  StkId o = index2addr(L, idx);
382
  if (!ttisstring(o)) {
383
    lua_lock(L);  /* `luaV_tostring' may create a new string */
384
    if (!luaV_tostring(L, o)) {  /* conversion failed? */
385
      if (len != NULL) *len = 0;
386
      lua_unlock(L);
387
      return NULL;
388
    }
389
    luaC_checkGC(L);
390
    o = index2addr(L, idx);  /* previous call may reallocate the stack */
391
    lua_unlock(L);
392
  }
393
  if (len != NULL) *len = tsvalue(o)->len;
394
  return svalue(o);
395
}
396
 
397
 
398
LUA_API size_t lua_rawlen (lua_State *L, int idx) {
399
  StkId o = index2addr(L, idx);
400
  switch (ttypenv(o)) {
401
    case LUA_TSTRING: return tsvalue(o)->len;
402
    case LUA_TUSERDATA: return uvalue(o)->len;
403
    case LUA_TTABLE: return luaH_getn(hvalue(o));
404
    default: return 0;
405
  }
406
}
407
 
408
 
409
LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
410
  StkId o = index2addr(L, idx);
411
  if (ttislcf(o)) return fvalue(o);
412
  else if (ttisCclosure(o))
413
    return clCvalue(o)->f;
414
  else return NULL;  /* not a C function */
415
}
416
 
417
 
418
LUA_API void *lua_touserdata (lua_State *L, int idx) {
419
  StkId o = index2addr(L, idx);
420
  switch (ttypenv(o)) {
421
    case LUA_TUSERDATA: return (rawuvalue(o) + 1);
422
    case LUA_TLIGHTUSERDATA: return pvalue(o);
423
    default: return NULL;
424
  }
425
}
426
 
427
 
428
LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
429
  StkId o = index2addr(L, idx);
430
  return (!ttisthread(o)) ? NULL : thvalue(o);
431
}
432
 
433
 
434
LUA_API const void *lua_topointer (lua_State *L, int idx) {
435
  StkId o = index2addr(L, idx);
436
  switch (ttype(o)) {
437
    case LUA_TTABLE: return hvalue(o);
438
    case LUA_TLCL: return clLvalue(o);
439
    case LUA_TCCL: return clCvalue(o);
440
    case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
441
    case LUA_TTHREAD: return thvalue(o);
442
    case LUA_TUSERDATA:
443
    case LUA_TLIGHTUSERDATA:
444
      return lua_touserdata(L, idx);
445
    default: return NULL;
446
  }
447
}
448
 
449
 
450
 
451
/*
452
** push functions (C -> stack)
453
*/
454
 
455
 
456
LUA_API void lua_pushnil (lua_State *L) {
457
  lua_lock(L);
458
  setnilvalue(L->top);
459
  api_incr_top(L);
460
  lua_unlock(L);
461
}
462
 
463
 
464
LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
465
  lua_lock(L);
466
  setnvalue(L->top, n);
467
  luai_checknum(L, L->top,
468
    luaG_runerror(L, "C API - attempt to push a signaling NaN"));
469
  api_incr_top(L);
470
  lua_unlock(L);
471
}
472
 
473
 
474
LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
475
  lua_lock(L);
476
  setnvalue(L->top, cast_num(n));
477
  api_incr_top(L);
478
  lua_unlock(L);
479
}
480
 
481
 
482
LUA_API void lua_pushunsigned (lua_State *L, lua_Unsigned u) {
483
  lua_Number n;
484
  lua_lock(L);
485
  n = lua_unsigned2number(u);
486
  setnvalue(L->top, n);
487
  api_incr_top(L);
488
  lua_unlock(L);
489
}
490
 
491
 
492
LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
493
  TString *ts;
494
  lua_lock(L);
495
  luaC_checkGC(L);
496
  ts = luaS_newlstr(L, s, len);
497
  setsvalue2s(L, L->top, ts);
498
  api_incr_top(L);
499
  lua_unlock(L);
500
  return getstr(ts);
501
}
502
 
503
 
504
LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
505
  if (s == NULL) {
506
    lua_pushnil(L);
507
    return NULL;
508
  }
509
  else {
510
    TString *ts;
511
    lua_lock(L);
512
    luaC_checkGC(L);
513
    ts = luaS_new(L, s);
514
    setsvalue2s(L, L->top, ts);
515
    api_incr_top(L);
516
    lua_unlock(L);
517
    return getstr(ts);
518
  }
519
}
520
 
521
 
522
LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
523
                                      va_list argp) {
524
  const char *ret;
525
  lua_lock(L);
526
  luaC_checkGC(L);
527
  ret = luaO_pushvfstring(L, fmt, argp);
528
  lua_unlock(L);
529
  return ret;
530
}
531
 
532
 
533
LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
534
  const char *ret;
535
  va_list argp;
536
  lua_lock(L);
537
  luaC_checkGC(L);
538
  va_start(argp, fmt);
539
  ret = luaO_pushvfstring(L, fmt, argp);
540
  va_end(argp);
541
  lua_unlock(L);
542
  return ret;
543
}
544
 
545
 
546
LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
547
  lua_lock(L);
548
  if (n == 0) {
549
    setfvalue(L->top, fn);
550
  }
551
  else {
552
    Closure *cl;
553
    api_checknelems(L, n);
554
    api_check(L, n <= MAXUPVAL, "upvalue index too large");
555
    luaC_checkGC(L);
556
    cl = luaF_newCclosure(L, n);
557
    cl->c.f = fn;
558
    L->top -= n;
559
    while (n--)
560
      setobj2n(L, &cl->c.upvalue[n], L->top + n);
561
    setclCvalue(L, L->top, cl);
562
  }
563
  api_incr_top(L);
564
  lua_unlock(L);
565
}
566
 
567
 
568
LUA_API void lua_pushboolean (lua_State *L, int b) {
569
  lua_lock(L);
570
  setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
571
  api_incr_top(L);
572
  lua_unlock(L);
573
}
574
 
575
 
576
LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
577
  lua_lock(L);
578
  setpvalue(L->top, p);
579
  api_incr_top(L);
580
  lua_unlock(L);
581
}
582
 
583
 
584
LUA_API int lua_pushthread (lua_State *L) {
585
  lua_lock(L);
586
  setthvalue(L, L->top, L);
587
  api_incr_top(L);
588
  lua_unlock(L);
589
  return (G(L)->mainthread == L);
590
}
591
 
592
 
593
 
594
/*
595
** get functions (Lua -> stack)
596
*/
597
 
598
 
599
LUA_API void lua_getglobal (lua_State *L, const char *var) {
600
  Table *reg = hvalue(&G(L)->l_registry);
601
  const TValue *gt;  /* global table */
602
  lua_lock(L);
603
  gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
604
  setsvalue2s(L, L->top++, luaS_new(L, var));
605
  luaV_gettable(L, gt, L->top - 1, L->top - 1);
606
  lua_unlock(L);
607
}
608
 
609
 
610
LUA_API void lua_gettable (lua_State *L, int idx) {
611
  StkId t;
612
  lua_lock(L);
613
  t = index2addr(L, idx);
614
  api_checkvalidindex(L, t);
615
  luaV_gettable(L, t, L->top - 1, L->top - 1);
616
  lua_unlock(L);
617
}
618
 
619
 
620
LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
621
  StkId t;
622
  lua_lock(L);
623
  t = index2addr(L, idx);
624
  api_checkvalidindex(L, t);
625
  setsvalue2s(L, L->top, luaS_new(L, k));
626
  api_incr_top(L);
627
  luaV_gettable(L, t, L->top - 1, L->top - 1);
628
  lua_unlock(L);
629
}
630
 
631
 
632
LUA_API void lua_rawget (lua_State *L, int idx) {
633
  StkId t;
634
  lua_lock(L);
635
  t = index2addr(L, idx);
636
  api_check(L, ttistable(t), "table expected");
637
  setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
638
  lua_unlock(L);
639
}
640
 
641
 
642
LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
643
  StkId t;
644
  lua_lock(L);
645
  t = index2addr(L, idx);
646
  api_check(L, ttistable(t), "table expected");
647
  setobj2s(L, L->top, luaH_getint(hvalue(t), n));
648
  api_incr_top(L);
649
  lua_unlock(L);
650
}
651
 
652
 
653
LUA_API void lua_rawgetp (lua_State *L, int idx, const void *p) {
654
  StkId t;
655
  TValue k;
656
  lua_lock(L);
657
  t = index2addr(L, idx);
658
  api_check(L, ttistable(t), "table expected");
659
  setpvalue(&k, cast(void *, p));
660
  setobj2s(L, L->top, luaH_get(hvalue(t), &k));
661
  api_incr_top(L);
662
  lua_unlock(L);
663
}
664
 
665
 
666
LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
667
  Table *t;
668
  lua_lock(L);
669
  luaC_checkGC(L);
670
  t = luaH_new(L);
671
  sethvalue(L, L->top, t);
672
  api_incr_top(L);
673
  if (narray > 0 || nrec > 0)
674
    luaH_resize(L, t, narray, nrec);
675
  lua_unlock(L);
676
}
677
 
678
 
679
LUA_API int lua_getmetatable (lua_State *L, int objindex) {
680
  const TValue *obj;
681
  Table *mt = NULL;
682
  int res;
683
  lua_lock(L);
684
  obj = index2addr(L, objindex);
685
  switch (ttypenv(obj)) {
686
    case LUA_TTABLE:
687
      mt = hvalue(obj)->metatable;
688
      break;
689
    case LUA_TUSERDATA:
690
      mt = uvalue(obj)->metatable;
691
      break;
692
    default:
693
      mt = G(L)->mt[ttypenv(obj)];
694
      break;
695
  }
696
  if (mt == NULL)
697
    res = 0;
698
  else {
699
    sethvalue(L, L->top, mt);
700
    api_incr_top(L);
701
    res = 1;
702
  }
703
  lua_unlock(L);
704
  return res;
705
}
706
 
707
 
708
LUA_API void lua_getuservalue (lua_State *L, int idx) {
709
  StkId o;
710
  lua_lock(L);
711
  o = index2addr(L, idx);
712
  api_checkvalidindex(L, o);
713
  api_check(L, ttisuserdata(o), "userdata expected");
714
  if (uvalue(o)->env) {
715
    sethvalue(L, L->top, uvalue(o)->env);
716
  } else
717
    setnilvalue(L->top);
718
  api_incr_top(L);
719
  lua_unlock(L);
720
}
721
 
722
 
723
/*
724
** set functions (stack -> Lua)
725
*/
726
 
727
 
728
LUA_API void lua_setglobal (lua_State *L, const char *var) {
729
  Table *reg = hvalue(&G(L)->l_registry);
730
  const TValue *gt;  /* global table */
731
  lua_lock(L);
732
  api_checknelems(L, 1);
733
  gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
734
  setsvalue2s(L, L->top++, luaS_new(L, var));
735
  luaV_settable(L, gt, L->top - 1, L->top - 2);
736
  L->top -= 2;  /* pop value and key */
737
  lua_unlock(L);
738
}
739
 
740
 
741
LUA_API void lua_settable (lua_State *L, int idx) {
742
  StkId t;
743
  lua_lock(L);
744
  api_checknelems(L, 2);
745
  t = index2addr(L, idx);
746
  api_checkvalidindex(L, t);
747
  luaV_settable(L, t, L->top - 2, L->top - 1);
748
  L->top -= 2;  /* pop index and value */
749
  lua_unlock(L);
750
}
751
 
752
 
753
LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
754
  StkId t;
755
  lua_lock(L);
756
  api_checknelems(L, 1);
757
  t = index2addr(L, idx);
758
  api_checkvalidindex(L, t);
759
  setsvalue2s(L, L->top++, luaS_new(L, k));
760
  luaV_settable(L, t, L->top - 1, L->top - 2);
761
  L->top -= 2;  /* pop value and key */
762
  lua_unlock(L);
763
}
764
 
765
 
766
LUA_API void lua_rawset (lua_State *L, int idx) {
767
  StkId t;
768
  lua_lock(L);
769
  api_checknelems(L, 2);
770
  t = index2addr(L, idx);
771
  api_check(L, ttistable(t), "table expected");
772
  setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
773
  invalidateTMcache(hvalue(t));
774
  luaC_barrierback(L, gcvalue(t), L->top-1);
775
  L->top -= 2;
776
  lua_unlock(L);
777
}
778
 
779
 
780
LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
781
  StkId t;
782
  lua_lock(L);
783
  api_checknelems(L, 1);
784
  t = index2addr(L, idx);
785
  api_check(L, ttistable(t), "table expected");
786
  luaH_setint(L, hvalue(t), n, L->top - 1);
787
  luaC_barrierback(L, gcvalue(t), L->top-1);
788
  L->top--;
789
  lua_unlock(L);
790
}
791
 
792
 
793
LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
794
  StkId t;
795
  TValue k;
796
  lua_lock(L);
797
  api_checknelems(L, 1);
798
  t = index2addr(L, idx);
799
  api_check(L, ttistable(t), "table expected");
800
  setpvalue(&k, cast(void *, p));
801
  setobj2t(L, luaH_set(L, hvalue(t), &k), L->top - 1);
802
  luaC_barrierback(L, gcvalue(t), L->top - 1);
803
  L->top--;
804
  lua_unlock(L);
805
}
806
 
807
 
808
LUA_API int lua_setmetatable (lua_State *L, int objindex) {
809
  TValue *obj;
810
  Table *mt;
811
  lua_lock(L);
812
  api_checknelems(L, 1);
813
  obj = index2addr(L, objindex);
814
  api_checkvalidindex(L, obj);
815
  if (ttisnil(L->top - 1))
816
    mt = NULL;
817
  else {
818
    api_check(L, ttistable(L->top - 1), "table expected");
819
    mt = hvalue(L->top - 1);
820
  }
821
  switch (ttypenv(obj)) {
822
    case LUA_TTABLE: {
823
      hvalue(obj)->metatable = mt;
824
      if (mt)
825
        luaC_objbarrierback(L, gcvalue(obj), mt);
826
        luaC_checkfinalizer(L, gcvalue(obj), mt);
827
      break;
828
    }
829
    case LUA_TUSERDATA: {
830
      uvalue(obj)->metatable = mt;
831
      if (mt) {
832
        luaC_objbarrier(L, rawuvalue(obj), mt);
833
        luaC_checkfinalizer(L, gcvalue(obj), mt);
834
      }
835
      break;
836
    }
837
    default: {
838
      G(L)->mt[ttypenv(obj)] = mt;
839
      break;
840
    }
841
  }
842
  L->top--;
843
  lua_unlock(L);
844
  return 1;
845
}
846
 
847
 
848
LUA_API void lua_setuservalue (lua_State *L, int idx) {
849
  StkId o;
850
  lua_lock(L);
851
  api_checknelems(L, 1);
852
  o = index2addr(L, idx);
853
  api_checkvalidindex(L, o);
854
  api_check(L, ttisuserdata(o), "userdata expected");
855
  if (ttisnil(L->top - 1))
856
    uvalue(o)->env = NULL;
857
  else {
858
    api_check(L, ttistable(L->top - 1), "table expected");
859
    uvalue(o)->env = hvalue(L->top - 1);
860
    luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
861
  }
862
  L->top--;
863
  lua_unlock(L);
864
}
865
 
866
 
867
/*
868
** `load' and `call' functions (run Lua code)
869
*/
870
 
871
 
872
#define checkresults(L,na,nr) \
873
     api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
874
	"results from function overflow current stack size")
875
 
876
 
877
LUA_API int lua_getctx (lua_State *L, int *ctx) {
878
  if (L->ci->callstatus & CIST_YIELDED) {
879
    if (ctx) *ctx = L->ci->u.c.ctx;
880
    return L->ci->u.c.status;
881
  }
882
  else return LUA_OK;
883
}
884
 
885
 
886
LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx,
887
                        lua_CFunction k) {
888
  StkId func;
889
  lua_lock(L);
890
  api_check(L, k == NULL || !isLua(L->ci),
891
    "cannot use continuations inside hooks");
892
  api_checknelems(L, nargs+1);
893
  api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
894
  checkresults(L, nargs, nresults);
895
  func = L->top - (nargs+1);
896
  if (k != NULL && L->nny == 0) {  /* need to prepare continuation? */
897
    L->ci->u.c.k = k;  /* save continuation */
898
    L->ci->u.c.ctx = ctx;  /* save context */
899
    luaD_call(L, func, nresults, 1);  /* do the call */
900
  }
901
  else  /* no continuation or no yieldable */
902
    luaD_call(L, func, nresults, 0);  /* just do the call */
903
  adjustresults(L, nresults);
904
  lua_unlock(L);
905
}
906
 
907
 
908
 
909
/*
910
** Execute a protected call.
911
*/
912
struct CallS {  /* data to `f_call' */
913
  StkId func;
914
  int nresults;
915
};
916
 
917
 
918
static void f_call (lua_State *L, void *ud) {
919
  struct CallS *c = cast(struct CallS *, ud);
920
  luaD_call(L, c->func, c->nresults, 0);
921
}
922
 
923
 
924
 
925
LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
926
                        int ctx, lua_CFunction k) {
927
  struct CallS c;
928
  int status;
929
  ptrdiff_t func;
930
  lua_lock(L);
931
  api_check(L, k == NULL || !isLua(L->ci),
932
    "cannot use continuations inside hooks");
933
  api_checknelems(L, nargs+1);
934
  api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
935
  checkresults(L, nargs, nresults);
936
  if (errfunc == 0)
937
    func = 0;
938
  else {
939
    StkId o = index2addr(L, errfunc);
940
    api_checkvalidindex(L, o);
941
    func = savestack(L, o);
942
  }
943
  c.func = L->top - (nargs+1);  /* function to be called */
944
  if (k == NULL || L->nny > 0) {  /* no continuation or no yieldable? */
945
    c.nresults = nresults;  /* do a 'conventional' protected call */
946
    status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
947
  }
948
  else {  /* prepare continuation (call is already protected by 'resume') */
949
    CallInfo *ci = L->ci;
950
    ci->u.c.k = k;  /* save continuation */
951
    ci->u.c.ctx = ctx;  /* save context */
952
    /* save information for error recovery */
953
    ci->u.c.extra = savestack(L, c.func);
954
    ci->u.c.old_allowhook = L->allowhook;
955
    ci->u.c.old_errfunc = L->errfunc;
956
    L->errfunc = func;
957
    /* mark that function may do error recovery */
958
    ci->callstatus |= CIST_YPCALL;
959
    luaD_call(L, c.func, nresults, 1);  /* do the call */
960
    ci->callstatus &= ~CIST_YPCALL;
961
    L->errfunc = ci->u.c.old_errfunc;
962
    status = LUA_OK;  /* if it is here, there were no errors */
963
  }
964
  adjustresults(L, nresults);
965
  lua_unlock(L);
966
  return status;
967
}
968
 
969
 
970
LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
971
                      const char *chunkname, const char *mode) {
972
  ZIO z;
973
  int status;
974
  lua_lock(L);
975
  if (!chunkname) chunkname = "?";
976
  luaZ_init(L, &z, reader, data);
977
  status = luaD_protectedparser(L, &z, chunkname, mode);
978
  if (status == LUA_OK) {  /* no errors? */
979
    LClosure *f = clLvalue(L->top - 1);  /* get newly created function */
980
    if (f->nupvalues == 1) {  /* does it have one upvalue? */
981
      /* get global table from registry */
982
      Table *reg = hvalue(&G(L)->l_registry);
983
      const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
984
      /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
985
      setobj(L, f->upvals[0]->v, gt);
986
      luaC_barrier(L, f->upvals[0], gt);
987
    }
988
  }
989
  lua_unlock(L);
990
  return status;
991
}
992
 
993
 
994
LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
995
  int status;
996
  TValue *o;
997
  lua_lock(L);
998
  api_checknelems(L, 1);
999
  o = L->top - 1;
1000
  if (isLfunction(o))
1001
    status = luaU_dump(L, getproto(o), writer, data, 0);
1002
  else
1003
    status = 1;
1004
  lua_unlock(L);
1005
  return status;
1006
}
1007
 
1008
 
1009
LUA_API int  lua_status (lua_State *L) {
1010
  return L->status;
1011
}
1012
 
1013
 
1014
/*
1015
** Garbage-collection function
1016
*/
1017
 
1018
LUA_API int lua_gc (lua_State *L, int what, int data) {
1019
  int res = 0;
1020
  global_State *g;
1021
  lua_lock(L);
1022
  g = G(L);
1023
  switch (what) {
1024
    case LUA_GCSTOP: {
1025
      g->gcrunning = 0;
1026
      break;
1027
    }
1028
    case LUA_GCRESTART: {
1029
      luaE_setdebt(g, 0);
1030
      g->gcrunning = 1;
1031
      break;
1032
    }
1033
    case LUA_GCCOLLECT: {
1034
      luaC_fullgc(L, 0);
1035
      break;
1036
    }
1037
    case LUA_GCCOUNT: {
1038
      /* GC values are expressed in Kbytes: #bytes/2^10 */
1039
      res = cast_int(gettotalbytes(g) >> 10);
1040
      break;
1041
    }
1042
    case LUA_GCCOUNTB: {
1043
      res = cast_int(gettotalbytes(g) & 0x3ff);
1044
      break;
1045
    }
1046
    case LUA_GCSTEP: {
1047
      if (g->gckind == KGC_GEN) {  /* generational mode? */
1048
        res = (g->lastmajormem == 0);  /* 1 if will do major collection */
1049
        luaC_forcestep(L);  /* do a single step */
1050
      }
1051
      else {
1052
        while (data-- >= 0) {
1053
          luaC_forcestep(L);
1054
          if (g->gcstate == GCSpause) {  /* end of cycle? */
1055
            res = 1;  /* signal it */
1056
            break;
1057
          }
1058
        }
1059
      }
1060
      break;
1061
    }
1062
    case LUA_GCSETPAUSE: {
1063
      res = g->gcpause;
1064
      g->gcpause = data;
1065
      break;
1066
    }
1067
    case LUA_GCSETMAJORINC: {
1068
      res = g->gcmajorinc;
1069
      g->gcmajorinc = data;
1070
      break;
1071
    }
1072
    case LUA_GCSETSTEPMUL: {
1073
      res = g->gcstepmul;
1074
      g->gcstepmul = data;
1075
      break;
1076
    }
1077
    case LUA_GCISRUNNING: {
1078
      res = g->gcrunning;
1079
      break;
1080
    }
1081
    case LUA_GCGEN: {  /* change collector to generational mode */
1082
      luaC_changemode(L, KGC_GEN);
1083
      break;
1084
    }
1085
    case LUA_GCINC: {  /* change collector to incremental mode */
1086
      luaC_changemode(L, KGC_NORMAL);
1087
      break;
1088
    }
1089
    default: res = -1;  /* invalid option */
1090
  }
1091
  lua_unlock(L);
1092
  return res;
1093
}
1094
 
1095
 
1096
 
1097
/*
1098
** miscellaneous functions
1099
*/
1100
 
1101
 
1102
LUA_API int lua_error (lua_State *L) {
1103
  lua_lock(L);
1104
  api_checknelems(L, 1);
1105
  luaG_errormsg(L);
1106
  lua_unlock(L);
1107
  return 0;  /* to avoid warnings */
1108
}
1109
 
1110
 
1111
LUA_API int lua_next (lua_State *L, int idx) {
1112
  StkId t;
1113
  int more;
1114
  lua_lock(L);
1115
  t = index2addr(L, idx);
1116
  api_check(L, ttistable(t), "table expected");
1117
  more = luaH_next(L, hvalue(t), L->top - 1);
1118
  if (more) {
1119
    api_incr_top(L);
1120
  }
1121
  else  /* no more elements */
1122
    L->top -= 1;  /* remove key */
1123
  lua_unlock(L);
1124
  return more;
1125
}
1126
 
1127
 
1128
LUA_API void lua_concat (lua_State *L, int n) {
1129
  lua_lock(L);
1130
  api_checknelems(L, n);
1131
  if (n >= 2) {
1132
    luaC_checkGC(L);
1133
    luaV_concat(L, n);
1134
  }
1135
  else if (n == 0) {  /* push empty string */
1136
    setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
1137
    api_incr_top(L);
1138
  }
1139
  /* else n == 1; nothing to do */
1140
  lua_unlock(L);
1141
}
1142
 
1143
 
1144
LUA_API void lua_len (lua_State *L, int idx) {
1145
  StkId t;
1146
  lua_lock(L);
1147
  t = index2addr(L, idx);
1148
  luaV_objlen(L, L->top, t);
1149
  api_incr_top(L);
1150
  lua_unlock(L);
1151
}
1152
 
1153
 
1154
LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
1155
  lua_Alloc f;
1156
  lua_lock(L);
1157
  if (ud) *ud = G(L)->ud;
1158
  f = G(L)->frealloc;
1159
  lua_unlock(L);
1160
  return f;
1161
}
1162
 
1163
 
1164
LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
1165
  lua_lock(L);
1166
  G(L)->ud = ud;
1167
  G(L)->frealloc = f;
1168
  lua_unlock(L);
1169
}
1170
 
1171
 
1172
LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
1173
  Udata *u;
1174
  lua_lock(L);
1175
  luaC_checkGC(L);
1176
  u = luaS_newudata(L, size, NULL);
1177
  setuvalue(L, L->top, u);
1178
  api_incr_top(L);
1179
  lua_unlock(L);
1180
  return u + 1;
1181
}
1182
 
1183
 
1184
 
1185
static const char *aux_upvalue (StkId fi, int n, TValue **val,
1186
                                GCObject **owner) {
1187
  switch (ttype(fi)) {
1188
    case LUA_TCCL: {  /* C closure */
1189
      CClosure *f = clCvalue(fi);
1190
      if (!(1 <= n && n <= f->nupvalues)) return NULL;
1191
      *val = &f->upvalue[n-1];
1192
      if (owner) *owner = obj2gco(f);
1193
      return "";
1194
    }
1195
    case LUA_TLCL: {  /* Lua closure */
1196
      LClosure *f = clLvalue(fi);
1197
      TString *name;
1198
      Proto *p = f->p;
1199
      if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
1200
      *val = f->upvals[n-1]->v;
1201
      if (owner) *owner = obj2gco(f->upvals[n - 1]);
1202
      name = p->upvalues[n-1].name;
1203
      return (name == NULL) ? "" : getstr(name);
1204
    }
1205
    default: return NULL;  /* not a closure */
1206
  }
1207
}
1208
 
1209
 
1210
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
1211
  const char *name;
1212
  TValue *val = NULL;  /* to avoid warnings */
1213
  lua_lock(L);
1214
  name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL);
1215
  if (name) {
1216
    setobj2s(L, L->top, val);
1217
    api_incr_top(L);
1218
  }
1219
  lua_unlock(L);
1220
  return name;
1221
}
1222
 
1223
 
1224
LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
1225
  const char *name;
1226
  TValue *val = NULL;  /* to avoid warnings */
1227
  GCObject *owner = NULL;  /* to avoid warnings */
1228
  StkId fi;
1229
  lua_lock(L);
1230
  fi = index2addr(L, funcindex);
1231
  api_checknelems(L, 1);
1232
  name = aux_upvalue(fi, n, &val, &owner);
1233
  if (name) {
1234
    L->top--;
1235
    setobj(L, val, L->top);
1236
    luaC_barrier(L, owner, L->top);
1237
  }
1238
  lua_unlock(L);
1239
  return name;
1240
}
1241
 
1242
 
1243
static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
1244
  LClosure *f;
1245
  StkId fi = index2addr(L, fidx);
1246
  api_check(L, ttisLclosure(fi), "Lua function expected");
1247
  f = clLvalue(fi);
1248
  api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
1249
  if (pf) *pf = f;
1250
  return &f->upvals[n - 1];  /* get its upvalue pointer */
1251
}
1252
 
1253
 
1254
LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
1255
  StkId fi = index2addr(L, fidx);
1256
  switch (ttype(fi)) {
1257
    case LUA_TLCL: {  /* lua closure */
1258
      return *getupvalref(L, fidx, n, NULL);
1259
    }
1260
    case LUA_TCCL: {  /* C closure */
1261
      CClosure *f = clCvalue(fi);
1262
      api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index");
1263
      return &f->upvalue[n - 1];
1264
    }
1265
    default: {
1266
      api_check(L, 0, "closure expected");
1267
      return NULL;
1268
    }
1269
  }
1270
}
1271
 
1272
 
1273
LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
1274
                                            int fidx2, int n2) {
1275
  LClosure *f1;
1276
  UpVal **up1 = getupvalref(L, fidx1, n1, &f1);
1277
  UpVal **up2 = getupvalref(L, fidx2, n2, NULL);
1278
  *up1 = *up2;
1279
  luaC_objbarrier(L, f1, *up2);
1280
}
1281