~ilya-yanok/ubuntu/oneiric/grub2/fix-for-948716

« back to all changes in this revision

Viewing changes to debian/grub-extras/lua/lapi.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2011-04-01 17:35:59 UTC
  • mfrom: (17.3.49 sid)
  • Revision ID: james.westby@ubuntu.com-20110401173559-774t7k0suhw04nzh
Tags: 1.99~rc1-8ubuntu1
* Resynchronise with Debian.  Remaining changes:
  - Adjust for default Ubuntu boot options ("quiet splash").
  - Default to hiding the menu; holding down Shift at boot will show it.
  - Set a monochromatic theme and an aubergine background for Ubuntu.
  - Apply Ubuntu GRUB Legacy changes to legacy update-grub script: title,
    recovery mode, quiet option, tweak how memtest86+ is displayed, and
    use UUIDs where appropriate.
  - Fix backslash-escaping in merge_debconf_into_conf.
  - Remove "GNU/Linux" from default distributor string.
  - Add crashkernel option.
  - Bypass menu unless other OSes are installed or Shift is pressed.
  - Allow Shift to interrupt 'sleep --interruptible'.
  - Reduce visual clutter in normal mode.
  - Remove verbose messages printed before reading configuration.
  - Suppress kernel/initrd progress messages, except in recovery mode.
  - Handle filesystems loop-mounted on file images.
  - Ignore devices loop-mounted from files in Linux grub.d scripts.
  - Show the boot menu if the previous boot failed.
  - Don't generate device.map during grub-install or grub-mkconfig.
  - Adjust upgrade version checks for Ubuntu.
  - Suppress "GRUB loading" message unless Shift is held down.
  - Adjust versions of grub-doc and grub-legacy-doc conflicts.
  - Fix LVM/RAID probing in the absence of /boot/grub/device.map.
  - Look for .mo files in /usr/share/locale-langpack first.
  - Build-depend on qemu-kvm rather than qemu-system for grub-pc tests.
  - Add a grub-rescue-efi-amd64 package.
  - On Wubi, don't ask for an install device, but just update wubildr
    using the diverted grub-install.
  - Check hardware support before using gfxpayload=keep.
  - Build part_msdos and vfat into EFI boot images.
  - Put second and subsequent Linux menu entries in a submenu.
  - Preferred resolution detection for VBE.
  - Set vt.handoff=7 for smooth handoff to kernel graphical mode.
* Drop patch to use qemu rather than qemu-system-i386, now that qemu-kvm
  ships a symlink.
* Rewrite hwmatch.lua in C.  Drop lua grub-extras module.
* Update ubuntu_vbe_autodetect.patch, bringing GRUB_GFXMODE documentation
  up to date.
* Fix use of freed memory when replacing existing loopback device
  (LP: #742967).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $
3
 
** Lua API
4
 
** See Copyright Notice in lua.h
5
 
*/
6
 
 
7
 
#if 0
8
 
#include <assert.h>
9
 
#include <math.h>
10
 
#include <stdarg.h>
11
 
#include <string.h>
12
 
#endif
13
 
 
14
 
#define lapi_c
15
 
#define LUA_CORE
16
 
 
17
 
#include "lua.h"
18
 
 
19
 
#include "lapi.h"
20
 
#include "ldebug.h"
21
 
#include "ldo.h"
22
 
#include "lfunc.h"
23
 
#include "lgc.h"
24
 
#include "lmem.h"
25
 
#include "lobject.h"
26
 
#include "lstate.h"
27
 
#include "lstring.h"
28
 
#include "ltable.h"
29
 
#include "ltm.h"
30
 
#include "lundump.h"
31
 
#include "lvm.h"
32
 
 
33
 
 
34
 
 
35
 
const char lua_ident[] =
36
 
  "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n"
37
 
  "$Authors: " LUA_AUTHORS " $\n"
38
 
  "$URL: www.lua.org $\n";
39
 
 
40
 
 
41
 
 
42
 
#define api_checknelems(L, n)   api_check(L, (n) <= (L->top - L->base))
43
 
 
44
 
#define api_checkvalidindex(L, i)       api_check(L, (i) != luaO_nilobject)
45
 
 
46
 
#define api_incr_top(L)   {api_check(L, L->top < L->ci->top); L->top++;}
47
 
 
48
 
 
49
 
 
50
 
static TValue *index2adr (lua_State *L, int idx) {
51
 
  if (idx > 0) {
52
 
    TValue *o = L->base + (idx - 1);
53
 
    api_check(L, idx <= L->ci->top - L->base);
54
 
    if (o >= L->top) return cast(TValue *, luaO_nilobject);
55
 
    else return o;
56
 
  }
57
 
  else if (idx > LUA_REGISTRYINDEX) {
58
 
    api_check(L, idx != 0 && -idx <= L->top - L->base);
59
 
    return L->top + idx;
60
 
  }
61
 
  else switch (idx) {  /* pseudo-indices */
62
 
    case LUA_REGISTRYINDEX: return registry(L);
63
 
    case LUA_ENVIRONINDEX: {
64
 
      Closure *func = curr_func(L);
65
 
      sethvalue(L, &L->env, func->c.env);
66
 
      return &L->env;
67
 
    }
68
 
    case LUA_GLOBALSINDEX: return gt(L);
69
 
    default: {
70
 
      Closure *func = curr_func(L);
71
 
      idx = LUA_GLOBALSINDEX - idx;
72
 
      return (idx <= func->c.nupvalues)
73
 
                ? &func->c.upvalue[idx-1]
74
 
                : cast(TValue *, luaO_nilobject);
75
 
    }
76
 
  }
77
 
}
78
 
 
79
 
 
80
 
static Table *getcurrenv (lua_State *L) {
81
 
  if (L->ci == L->base_ci)  /* no enclosing function? */
82
 
    return hvalue(gt(L));  /* use global table as environment */
83
 
  else {
84
 
    Closure *func = curr_func(L);
85
 
    return func->c.env;
86
 
  }
87
 
}
88
 
 
89
 
 
90
 
void luaA_pushobject (lua_State *L, const TValue *o) {
91
 
  setobj2s(L, L->top, o);
92
 
  api_incr_top(L);
93
 
}
94
 
 
95
 
 
96
 
LUA_API int lua_checkstack (lua_State *L, int size) {
97
 
  int res = 1;
98
 
  lua_lock(L);
99
 
  if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK)
100
 
    res = 0;  /* stack overflow */
101
 
  else if (size > 0) {
102
 
    luaD_checkstack(L, size);
103
 
    if (L->ci->top < L->top + size)
104
 
      L->ci->top = L->top + size;
105
 
  }
106
 
  lua_unlock(L);
107
 
  return res;
108
 
}
109
 
 
110
 
 
111
 
LUA_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
 
 
126
 
LUA_API void lua_setlevel (lua_State *from, lua_State *to) {
127
 
  to->nCcalls = from->nCcalls;
128
 
}
129
 
 
130
 
 
131
 
LUA_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
 
 
141
 
LUA_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
 
 
160
 
LUA_API int lua_gettop (lua_State *L) {
161
 
  return cast_int(L->top - L->base);
162
 
}
163
 
 
164
 
 
165
 
LUA_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
 
 
181
 
LUA_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
 
 
192
 
LUA_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
 
 
204
 
LUA_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
 
 
229
 
LUA_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
 
 
243
 
LUA_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
 
 
249
 
LUA_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
 
 
255
 
LUA_API int lua_iscfunction (lua_State *L, int idx) {
256
 
  StkId o = index2adr(L, idx);
257
 
  return iscfunction(o);
258
 
}
259
 
 
260
 
 
261
 
LUA_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
 
 
268
 
LUA_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
 
 
274
 
LUA_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
 
 
280
 
LUA_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
 
 
288
 
LUA_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
 
 
300
 
LUA_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
 
 
314
 
LUA_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
 
 
324
 
LUA_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
 
 
338
 
LUA_API int lua_toboolean (lua_State *L, int idx) {
339
 
  const TValue *o = index2adr(L, idx);
340
 
  return !l_isfalse(o);
341
 
}
342
 
 
343
 
 
344
 
LUA_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
 
 
362
 
LUA_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
 
 
380
 
LUA_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
 
 
386
 
LUA_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
 
 
396
 
LUA_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
 
 
402
 
LUA_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
 
 
422
 
LUA_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
 
 
430
 
LUA_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
 
 
438
 
LUA_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
 
 
446
 
LUA_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
 
 
455
 
LUA_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
 
 
463
 
LUA_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
 
 
474
 
LUA_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
 
 
487
 
LUA_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
 
 
504
 
LUA_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
 
 
512
 
LUA_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
 
 
520
 
LUA_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
 
 
535
 
LUA_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
 
 
545
 
LUA_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
 
 
558
 
LUA_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
 
 
568
 
LUA_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
 
 
579
 
LUA_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
 
 
588
 
LUA_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
 
 
617
 
LUA_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
 
 
646
 
LUA_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
 
 
658
 
LUA_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
 
 
672
 
LUA_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
 
 
685
 
LUA_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
 
 
698
 
LUA_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
 
 
735
 
LUA_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
 
 
777
 
LUA_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
 
*/
793
 
struct CallS {  /* data to `f_call' */
794
 
  StkId func;
795
 
  int nresults;
796
 
};
797
 
 
798
 
 
799
 
static 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
 
 
806
 
LUA_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
 
*/
832
 
struct CCallS {  /* data to `f_Ccall' */
833
 
  lua_CFunction func;
834
 
  void *ud;
835
 
};
836
 
 
837
 
 
838
 
static 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
 
 
851
 
LUA_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
 
 
863
 
LUA_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
 
 
876
 
LUA_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
 
 
891
 
LUA_API int  lua_status (lua_State *L) {
892
 
  return L->status;
893
 
}
894
 
 
895
 
 
896
 
/*
897
 
** Garbage-collection function
898
 
*/
899
 
 
900
 
LUA_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
 
      }
940
 
      break;
941
 
    }
942
 
    case LUA_GCSETPAUSE: {
943
 
      res = g->gcpause;
944
 
      g->gcpause = data;
945
 
      break;
946
 
    }
947
 
    case LUA_GCSETSTEPMUL: {
948
 
      res = g->gcstepmul;
949
 
      g->gcstepmul = data;
950
 
      break;
951
 
    }
952
 
    default: res = -1;  /* invalid option */
953
 
  }
954
 
  lua_unlock(L);
955
 
  return res;
956
 
}
957
 
 
958
 
 
959
 
 
960
 
/*
961
 
** miscellaneous functions
962
 
*/
963
 
 
964
 
 
965
 
LUA_API int lua_error (lua_State *L) {
966
 
  lua_lock(L);
967
 
  api_checknelems(L, 1);
968
 
  luaG_errormsg(L);
969
 
  lua_unlock(L);
970
 
  return 0;  /* to avoid warnings */
971
 
}
972
 
 
973
 
 
974
 
LUA_API int lua_next (lua_State *L, int idx) {
975
 
  StkId t;
976
 
  int more;
977
 
  lua_lock(L);
978
 
  t = index2adr(L, idx);
979
 
  api_check(L, ttistable(t));
980
 
  more = luaH_next(L, hvalue(t), L->top - 1);
981
 
  if (more) {
982
 
    api_incr_top(L);
983
 
  }
984
 
  else  /* no more elements */
985
 
    L->top -= 1;  /* remove key */
986
 
  lua_unlock(L);
987
 
  return more;
988
 
}
989
 
 
990
 
 
991
 
LUA_API void lua_concat (lua_State *L, int n) {
992
 
  lua_lock(L);
993
 
  api_checknelems(L, n);
994
 
  if (n >= 2) {
995
 
    luaC_checkGC(L);
996
 
    luaV_concat(L, n, cast_int(L->top - L->base) - 1);
997
 
    L->top -= (n-1);
998
 
  }
999
 
  else if (n == 0) {  /* push empty string */
1000
 
    setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
1001
 
    api_incr_top(L);
1002
 
  }
1003
 
  /* else n == 1; nothing to do */
1004
 
  lua_unlock(L);
1005
 
}
1006
 
 
1007
 
 
1008
 
LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
1009
 
  lua_Alloc f;
1010
 
  lua_lock(L);
1011
 
  if (ud) *ud = G(L)->ud;
1012
 
  f = G(L)->frealloc;
1013
 
  lua_unlock(L);
1014
 
  return f;
1015
 
}
1016
 
 
1017
 
 
1018
 
LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
1019
 
  lua_lock(L);
1020
 
  G(L)->ud = ud;
1021
 
  G(L)->frealloc = f;
1022
 
  lua_unlock(L);
1023
 
}
1024
 
 
1025
 
 
1026
 
LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
1027
 
  Udata *u;
1028
 
  lua_lock(L);
1029
 
  luaC_checkGC(L);
1030
 
  u = luaS_newudata(L, size, getcurrenv(L));
1031
 
  setuvalue(L, L->top, u);
1032
 
  api_incr_top(L);
1033
 
  lua_unlock(L);
1034
 
  return u + 1;
1035
 
}
1036
 
 
1037
 
 
1038
 
 
1039
 
 
1040
 
static const char *aux_upvalue (StkId fi, int n, TValue **val) {
1041
 
  Closure *f;
1042
 
  if (!ttisfunction(fi)) return NULL;
1043
 
  f = clvalue(fi);
1044
 
  if (f->c.isC) {
1045
 
    if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
1046
 
    *val = &f->c.upvalue[n-1];
1047
 
    return "";
1048
 
  }
1049
 
  else {
1050
 
    Proto *p = f->l.p;
1051
 
    if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
1052
 
    *val = f->l.upvals[n-1]->v;
1053
 
    return getstr(p->upvalues[n-1]);
1054
 
  }
1055
 
}
1056
 
 
1057
 
 
1058
 
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
1059
 
  const char *name;
1060
 
  TValue *val;
1061
 
  lua_lock(L);
1062
 
  name = aux_upvalue(index2adr(L, funcindex), n, &val);
1063
 
  if (name) {
1064
 
    setobj2s(L, L->top, val);
1065
 
    api_incr_top(L);
1066
 
  }
1067
 
  lua_unlock(L);
1068
 
  return name;
1069
 
}
1070
 
 
1071
 
 
1072
 
LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
1073
 
  const char *name;
1074
 
  TValue *val;
1075
 
  StkId fi;
1076
 
  lua_lock(L);
1077
 
  fi = index2adr(L, funcindex);
1078
 
  api_checknelems(L, 1);
1079
 
  name = aux_upvalue(fi, n, &val);
1080
 
  if (name) {
1081
 
    L->top--;
1082
 
    setobj(L, val, L->top);
1083
 
    luaC_barrier(L, clvalue(fi), L->top);
1084
 
  }
1085
 
  lua_unlock(L);
1086
 
  return name;
1087
 
}
1088