~hamo/ubuntu/precise/grub2/grub2.hi_res

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Evan Broder, Mario Limonciello
  • Date: 2010-11-24 13:59:55 UTC
  • mfrom: (1.17.6 upstream) (17.6.15 experimental)
  • Revision ID: james.westby@ubuntu.com-20101124135955-r6ii5sepayr7jt53
Tags: 1.99~20101124-1ubuntu1
[ Colin Watson ]
* Resynchronise with Debian experimental.  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 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= options if kdump and makedumpfile are available.
  - If other operating systems are installed, then automatically unhide
    the menu.  Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus
    if available to check whether Shift is pressed.  If it is, show the
    menu, otherwise boot immediately.  If keystatus is not available, then
    fall back to a short delay interruptible with Escape.
  - Allow Shift to interrupt 'sleep --interruptible'.
  - Don't display introductory message about line editing unless we're
    actually offering a shell prompt.  Don't clear the screen just before
    booting if we never drew the menu in the first place.
  - Remove some verbose messages printed before reading the configuration
    file.
  - Suppress progress messages as the kernel and initrd load for
    non-recovery kernel menu entries.
  - Change prepare_grub_to_access_device to handle filesystems
    loop-mounted on file images.
  - Ignore devices loop-mounted from files in 10_linux.
  - Show the boot menu if the previous boot failed, that is if it failed
    to get to the end of one of the normal runlevels.
  - Don't generate /boot/grub/device.map during grub-install or
    grub-mkconfig by default.
  - Adjust upgrade version checks for Ubuntu.
  - Don't display "GRUB loading" unless Shift is held down.
  - Adjust versions of grub-doc and grub-legacy-doc conflicts to tolerate
    our backport of the grub-doc split.
  - Fix LVM/RAID probing in the absence of /boot/grub/device.map.
  - Look for .mo files in /usr/share/locale-langpack as well, in
    preference.
  - Make sure GRUB_TIMEOUT isn't quoted unnecessarily.
  - Probe all devices in 'grub-probe --target=drive' if
    /boot/grub/device.map is missing.
  - Build-depend on qemu-kvm rather than qemu-system for grub-pc tests.
  - Use qemu rather than qemu-system-i386.
  - Program vesafb on BIOS systems rather than efifb.
  - Add a grub-rescue-efi-amd64 package containing a rescue CD-ROM image
    for EFI-AMD64.
  - On Wubi, don't ask for an install device, but just update wubildr
    using the diverted grub-install.
  - When embedding the core image in a post-MBR gap, check for and avoid
    sectors matching any of a list of known signatures.
  - Disable video_bochs and video_cirrus on PC BIOS systems, as probing
    PCI space seems to break on some systems.
* Downgrade "ACPI shutdown failed" error to a debug message, since it can
  cause spurious test failures.

[ Evan Broder ]
* Enable lua from grub-extras.
* Incorporate the bitop library into lua.
* Add enum_pci function to grub module in lua.
* Switch back to gfxpayload=keep by default, unless the video hardware
  is known to not support it.

[ Mario Limonciello ]
* Built part_msdos and vfat into bootx64.efi (LP: #677758)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $
 
3
** Stack and Call structure of Lua
 
4
** See Copyright Notice in lua.h
 
5
*/
 
6
 
 
7
#if 0
 
8
#include <setjmp.h>
 
9
#include <stdlib.h>
 
10
#include <string.h>
 
11
#endif
 
12
 
 
13
#define ldo_c
 
14
#define LUA_CORE
 
15
 
 
16
#include "lua.h"
 
17
 
 
18
#include "ldebug.h"
 
19
#include "ldo.h"
 
20
#include "lfunc.h"
 
21
#include "lgc.h"
 
22
#include "lmem.h"
 
23
#include "lobject.h"
 
24
#include "lopcodes.h"
 
25
#include "lparser.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
#include "lzio.h"
 
33
 
 
34
 
 
35
 
 
36
 
 
37
/*
 
38
** {======================================================
 
39
** Error-recovery functions
 
40
** =======================================================
 
41
*/
 
42
 
 
43
 
 
44
/* chain list of long jump buffers */
 
45
struct lua_longjmp {
 
46
  struct lua_longjmp *previous;
 
47
  luai_jmpbuf b;
 
48
  volatile int status;  /* error code */
 
49
};
 
50
 
 
51
 
 
52
void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
 
53
  switch (errcode) {
 
54
    case LUA_ERRMEM: {
 
55
      setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG));
 
56
      break;
 
57
    }
 
58
    case LUA_ERRERR: {
 
59
      setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
 
60
      break;
 
61
    }
 
62
    case LUA_ERRSYNTAX:
 
63
    case LUA_ERRRUN: {
 
64
      setobjs2s(L, oldtop, L->top - 1);  /* error message on current top */
 
65
      break;
 
66
    }
 
67
  }
 
68
  L->top = oldtop + 1;
 
69
}
 
70
 
 
71
 
 
72
static void restore_stack_limit (lua_State *L) {
 
73
  lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
 
74
  if (L->size_ci > LUAI_MAXCALLS) {  /* there was an overflow? */
 
75
    int inuse = cast_int(L->ci - L->base_ci);
 
76
    if (inuse + 1 < LUAI_MAXCALLS)  /* can `undo' overflow? */
 
77
      luaD_reallocCI(L, LUAI_MAXCALLS);
 
78
  }
 
79
}
 
80
 
 
81
 
 
82
static void resetstack (lua_State *L, int status) {
 
83
  L->ci = L->base_ci;
 
84
  L->base = L->ci->base;
 
85
  luaF_close(L, L->base);  /* close eventual pending closures */
 
86
  luaD_seterrorobj(L, status, L->base);
 
87
  L->nCcalls = L->baseCcalls;
 
88
  L->allowhook = 1;
 
89
  restore_stack_limit(L);
 
90
  L->errfunc = 0;
 
91
  L->errorJmp = NULL;
 
92
}
 
93
 
 
94
 
 
95
void luaD_throw (lua_State *L, int errcode) {
 
96
  if (L->errorJmp) {
 
97
    L->errorJmp->status = errcode;
 
98
    LUAI_THROW(L, L->errorJmp);
 
99
  }
 
100
  else {
 
101
    L->status = cast_byte(errcode);
 
102
    if (G(L)->panic) {
 
103
      resetstack(L, errcode);
 
104
      lua_unlock(L);
 
105
      G(L)->panic(L);
 
106
    }
 
107
    exit(EXIT_FAILURE);
 
108
  }
 
109
}
 
110
 
 
111
 
 
112
int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
 
113
  struct lua_longjmp lj;
 
114
  lj.status = 0;
 
115
  lj.previous = L->errorJmp;  /* chain new error handler */
 
116
  L->errorJmp = &lj;
 
117
  LUAI_TRY(L, &lj,
 
118
    (*f)(L, ud);
 
119
  );
 
120
  L->errorJmp = lj.previous;  /* restore old error handler */
 
121
  return lj.status;
 
122
}
 
123
 
 
124
/* }====================================================== */
 
125
 
 
126
 
 
127
static void correctstack (lua_State *L, TValue *oldstack) {
 
128
  CallInfo *ci;
 
129
  GCObject *up;
 
130
  L->top = (L->top - oldstack) + L->stack;
 
131
  for (up = L->openupval; up != NULL; up = up->gch.next)
 
132
    gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
 
133
  for (ci = L->base_ci; ci <= L->ci; ci++) {
 
134
    ci->top = (ci->top - oldstack) + L->stack;
 
135
    ci->base = (ci->base - oldstack) + L->stack;
 
136
    ci->func = (ci->func - oldstack) + L->stack;
 
137
  }
 
138
  L->base = (L->base - oldstack) + L->stack;
 
139
}
 
140
 
 
141
 
 
142
void luaD_reallocstack (lua_State *L, int newsize) {
 
143
  TValue *oldstack = L->stack;
 
144
  int realsize = newsize + 1 + EXTRA_STACK;
 
145
  lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
 
146
  luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
 
147
  L->stacksize = realsize;
 
148
  L->stack_last = L->stack+newsize;
 
149
  correctstack(L, oldstack);
 
150
}
 
151
 
 
152
 
 
153
void luaD_reallocCI (lua_State *L, int newsize) {
 
154
  CallInfo *oldci = L->base_ci;
 
155
  luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
 
156
  L->size_ci = newsize;
 
157
  L->ci = (L->ci - oldci) + L->base_ci;
 
158
  L->end_ci = L->base_ci + L->size_ci - 1;
 
159
}
 
160
 
 
161
 
 
162
void luaD_growstack (lua_State *L, int n) {
 
163
  if (n <= L->stacksize)  /* double size is enough? */
 
164
    luaD_reallocstack(L, 2*L->stacksize);
 
165
  else
 
166
    luaD_reallocstack(L, L->stacksize + n);
 
167
}
 
168
 
 
169
 
 
170
static CallInfo *growCI (lua_State *L) {
 
171
  if (L->size_ci > LUAI_MAXCALLS)  /* overflow while handling overflow? */
 
172
    luaD_throw(L, LUA_ERRERR);
 
173
  else {
 
174
    luaD_reallocCI(L, 2*L->size_ci);
 
175
    if (L->size_ci > LUAI_MAXCALLS)
 
176
      luaG_runerror(L, "stack overflow");
 
177
  }
 
178
  return ++L->ci;
 
179
}
 
180
 
 
181
 
 
182
void luaD_callhook (lua_State *L, int event, int line) {
 
183
  lua_Hook hook = L->hook;
 
184
  if (hook && L->allowhook) {
 
185
    ptrdiff_t top = savestack(L, L->top);
 
186
    ptrdiff_t ci_top = savestack(L, L->ci->top);
 
187
    lua_Debug ar;
 
188
    ar.event = event;
 
189
    ar.currentline = line;
 
190
    if (event == LUA_HOOKTAILRET)
 
191
      ar.i_ci = 0;  /* tail call; no debug information about it */
 
192
    else
 
193
      ar.i_ci = cast_int(L->ci - L->base_ci);
 
194
    luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
 
195
    L->ci->top = L->top + LUA_MINSTACK;
 
196
    lua_assert(L->ci->top <= L->stack_last);
 
197
    L->allowhook = 0;  /* cannot call hooks inside a hook */
 
198
    lua_unlock(L);
 
199
    (*hook)(L, &ar);
 
200
    lua_lock(L);
 
201
    lua_assert(!L->allowhook);
 
202
    L->allowhook = 1;
 
203
    L->ci->top = restorestack(L, ci_top);
 
204
    L->top = restorestack(L, top);
 
205
  }
 
206
}
 
207
 
 
208
 
 
209
static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
 
210
  int i;
 
211
  int nfixargs = p->numparams;
 
212
  Table *htab = NULL;
 
213
  StkId base, fixed;
 
214
  for (; actual < nfixargs; ++actual)
 
215
    setnilvalue(L->top++);
 
216
#if defined(LUA_COMPAT_VARARG)
 
217
  if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */
 
218
    int nvar = actual - nfixargs;  /* number of extra arguments */
 
219
    lua_assert(p->is_vararg & VARARG_HASARG);
 
220
    luaC_checkGC(L);
 
221
    htab = luaH_new(L, nvar, 1);  /* create `arg' table */
 
222
    for (i=0; i<nvar; i++)  /* put extra arguments into `arg' table */
 
223
      setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i);
 
224
    /* store counter in field `n' */
 
225
    setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar));
 
226
  }
 
227
#endif
 
228
  /* move fixed parameters to final position */
 
229
  fixed = L->top - actual;  /* first fixed argument */
 
230
  base = L->top;  /* final position of first argument */
 
231
  for (i=0; i<nfixargs; i++) {
 
232
    setobjs2s(L, L->top++, fixed+i);
 
233
    setnilvalue(fixed+i);
 
234
  }
 
235
  /* add `arg' parameter */
 
236
  if (htab) {
 
237
    sethvalue(L, L->top++, htab);
 
238
    lua_assert(iswhite(obj2gco(htab)));
 
239
  }
 
240
  return base;
 
241
}
 
242
 
 
243
 
 
244
static StkId tryfuncTM (lua_State *L, StkId func) {
 
245
  const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
 
246
  StkId p;
 
247
  ptrdiff_t funcr = savestack(L, func);
 
248
  if (!ttisfunction(tm))
 
249
    luaG_typeerror(L, func, "call");
 
250
  /* Open a hole inside the stack at `func' */
 
251
  for (p = L->top; p > func; p--) setobjs2s(L, p, p-1);
 
252
  incr_top(L);
 
253
  func = restorestack(L, funcr);  /* previous call may change stack */
 
254
  setobj2s(L, func, tm);  /* tag method is the new function to be called */
 
255
  return func;
 
256
}
 
257
 
 
258
 
 
259
 
 
260
#define inc_ci(L) \
 
261
  ((L->ci == L->end_ci) ? growCI(L) : \
 
262
   (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci))
 
263
 
 
264
 
 
265
int luaD_precall (lua_State *L, StkId func, int nresults) {
 
266
  LClosure *cl;
 
267
  ptrdiff_t funcr;
 
268
  if (!ttisfunction(func)) /* `func' is not a function? */
 
269
    func = tryfuncTM(L, func);  /* check the `function' tag method */
 
270
  funcr = savestack(L, func);
 
271
  cl = &clvalue(func)->l;
 
272
  L->ci->savedpc = L->savedpc;
 
273
  if (!cl->isC) {  /* Lua function? prepare its call */
 
274
    CallInfo *ci;
 
275
    StkId st, base;
 
276
    Proto *p = cl->p;
 
277
    luaD_checkstack(L, p->maxstacksize);
 
278
    func = restorestack(L, funcr);
 
279
    if (!p->is_vararg) {  /* no varargs? */
 
280
      base = func + 1;
 
281
      if (L->top > base + p->numparams)
 
282
        L->top = base + p->numparams;
 
283
    }
 
284
    else {  /* vararg function */
 
285
      int nargs = cast_int(L->top - func) - 1;
 
286
      base = adjust_varargs(L, p, nargs);
 
287
      func = restorestack(L, funcr);  /* previous call may change the stack */
 
288
    }
 
289
    ci = inc_ci(L);  /* now `enter' new function */
 
290
    ci->func = func;
 
291
    L->base = ci->base = base;
 
292
    ci->top = L->base + p->maxstacksize;
 
293
    lua_assert(ci->top <= L->stack_last);
 
294
    L->savedpc = p->code;  /* starting point */
 
295
    ci->tailcalls = 0;
 
296
    ci->nresults = nresults;
 
297
    for (st = L->top; st < ci->top; st++)
 
298
      setnilvalue(st);
 
299
    L->top = ci->top;
 
300
    if (L->hookmask & LUA_MASKCALL) {
 
301
      L->savedpc++;  /* hooks assume 'pc' is already incremented */
 
302
      luaD_callhook(L, LUA_HOOKCALL, -1);
 
303
      L->savedpc--;  /* correct 'pc' */
 
304
    }
 
305
    return PCRLUA;
 
306
  }
 
307
  else {  /* if is a C function, call it */
 
308
    CallInfo *ci;
 
309
    int n;
 
310
    luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
 
311
    ci = inc_ci(L);  /* now `enter' new function */
 
312
    ci->func = restorestack(L, funcr);
 
313
    L->base = ci->base = ci->func + 1;
 
314
    ci->top = L->top + LUA_MINSTACK;
 
315
    lua_assert(ci->top <= L->stack_last);
 
316
    ci->nresults = nresults;
 
317
    if (L->hookmask & LUA_MASKCALL)
 
318
      luaD_callhook(L, LUA_HOOKCALL, -1);
 
319
    lua_unlock(L);
 
320
    n = (*curr_func(L)->c.f)(L);  /* do the actual call */
 
321
    lua_lock(L);
 
322
    if (n < 0)  /* yielding? */
 
323
      return PCRYIELD;
 
324
    else {
 
325
      luaD_poscall(L, L->top - n);
 
326
      return PCRC;
 
327
    }
 
328
  }
 
329
}
 
330
 
 
331
 
 
332
static StkId callrethooks (lua_State *L, StkId firstResult) {
 
333
  ptrdiff_t fr = savestack(L, firstResult);  /* next call may change stack */
 
334
  luaD_callhook(L, LUA_HOOKRET, -1);
 
335
  if (f_isLua(L->ci)) {  /* Lua function? */
 
336
    while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */
 
337
      luaD_callhook(L, LUA_HOOKTAILRET, -1);
 
338
  }
 
339
  return restorestack(L, fr);
 
340
}
 
341
 
 
342
 
 
343
int luaD_poscall (lua_State *L, StkId firstResult) {
 
344
  StkId res;
 
345
  int wanted, i;
 
346
  CallInfo *ci;
 
347
  if (L->hookmask & LUA_MASKRET)
 
348
    firstResult = callrethooks(L, firstResult);
 
349
  ci = L->ci--;
 
350
  res = ci->func;  /* res == final position of 1st result */
 
351
  wanted = ci->nresults;
 
352
  L->base = (ci - 1)->base;  /* restore base */
 
353
  L->savedpc = (ci - 1)->savedpc;  /* restore savedpc */
 
354
  /* move results to correct place */
 
355
  for (i = wanted; i != 0 && firstResult < L->top; i--)
 
356
    setobjs2s(L, res++, firstResult++);
 
357
  while (i-- > 0)
 
358
    setnilvalue(res++);
 
359
  L->top = res;
 
360
  return (wanted - LUA_MULTRET);  /* 0 iff wanted == LUA_MULTRET */
 
361
}
 
362
 
 
363
 
 
364
/*
 
365
** Call a function (C or Lua). The function to be called is at *func.
 
366
** The arguments are on the stack, right after the function.
 
367
** When returns, all the results are on the stack, starting at the original
 
368
** function position.
 
369
*/
 
370
void luaD_call (lua_State *L, StkId func, int nResults) {
 
371
  if (++L->nCcalls >= LUAI_MAXCCALLS) {
 
372
    if (L->nCcalls == LUAI_MAXCCALLS)
 
373
      luaG_runerror(L, "C stack overflow");
 
374
    else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
 
375
      luaD_throw(L, LUA_ERRERR);  /* error while handing stack error */
 
376
  }
 
377
  if (luaD_precall(L, func, nResults) == PCRLUA)  /* is a Lua function? */
 
378
    luaV_execute(L, 1);  /* call it */
 
379
  L->nCcalls--;
 
380
  luaC_checkGC(L);
 
381
}
 
382
 
 
383
 
 
384
static void resume (lua_State *L, void *ud) {
 
385
  StkId firstArg = cast(StkId, ud);
 
386
  CallInfo *ci = L->ci;
 
387
  if (L->status == 0) {  /* start coroutine? */
 
388
    lua_assert(ci == L->base_ci && firstArg > L->base);
 
389
    if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA)
 
390
      return;
 
391
  }
 
392
  else {  /* resuming from previous yield */
 
393
    lua_assert(L->status == LUA_YIELD);
 
394
    L->status = 0;
 
395
    if (!f_isLua(ci)) {  /* `common' yield? */
 
396
      /* finish interrupted execution of `OP_CALL' */
 
397
      lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
 
398
                 GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL);
 
399
      if (luaD_poscall(L, firstArg))  /* complete it... */
 
400
        L->top = L->ci->top;  /* and correct top if not multiple results */
 
401
    }
 
402
    else  /* yielded inside a hook: just continue its execution */
 
403
      L->base = L->ci->base;
 
404
  }
 
405
  luaV_execute(L, cast_int(L->ci - L->base_ci));
 
406
}
 
407
 
 
408
 
 
409
static int resume_error (lua_State *L, const char *msg) {
 
410
  L->top = L->ci->base;
 
411
  setsvalue2s(L, L->top, luaS_new(L, msg));
 
412
  incr_top(L);
 
413
  lua_unlock(L);
 
414
  return LUA_ERRRUN;
 
415
}
 
416
 
 
417
 
 
418
LUA_API int lua_resume (lua_State *L, int nargs) {
 
419
  int status;
 
420
  lua_lock(L);
 
421
  if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci))
 
422
      return resume_error(L, "cannot resume non-suspended coroutine");
 
423
  if (L->nCcalls >= LUAI_MAXCCALLS)
 
424
    return resume_error(L, "C stack overflow");
 
425
  luai_userstateresume(L, nargs);
 
426
  lua_assert(L->errfunc == 0);
 
427
  L->baseCcalls = ++L->nCcalls;
 
428
  status = luaD_rawrunprotected(L, resume, L->top - nargs);
 
429
  if (status != 0) {  /* error? */
 
430
    L->status = cast_byte(status);  /* mark thread as `dead' */
 
431
    luaD_seterrorobj(L, status, L->top);
 
432
    L->ci->top = L->top;
 
433
  }
 
434
  else {
 
435
    lua_assert(L->nCcalls == L->baseCcalls);
 
436
    status = L->status;
 
437
  }
 
438
  --L->nCcalls;
 
439
  lua_unlock(L);
 
440
  return status;
 
441
}
 
442
 
 
443
 
 
444
LUA_API int lua_yield (lua_State *L, int nresults) {
 
445
  luai_userstateyield(L, nresults);
 
446
  lua_lock(L);
 
447
  if (L->nCcalls > L->baseCcalls)
 
448
    luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
 
449
  L->base = L->top - nresults;  /* protect stack slots below */
 
450
  L->status = LUA_YIELD;
 
451
  lua_unlock(L);
 
452
  return -1;
 
453
}
 
454
 
 
455
 
 
456
int luaD_pcall (lua_State *L, Pfunc func, void *u,
 
457
                ptrdiff_t old_top, ptrdiff_t ef) {
 
458
  int status;
 
459
  unsigned short oldnCcalls = L->nCcalls;
 
460
  ptrdiff_t old_ci = saveci(L, L->ci);
 
461
  lu_byte old_allowhooks = L->allowhook;
 
462
  ptrdiff_t old_errfunc = L->errfunc;
 
463
  L->errfunc = ef;
 
464
  status = luaD_rawrunprotected(L, func, u);
 
465
  if (status != 0) {  /* an error occurred? */
 
466
    StkId oldtop = restorestack(L, old_top);
 
467
    luaF_close(L, oldtop);  /* close eventual pending closures */
 
468
    luaD_seterrorobj(L, status, oldtop);
 
469
    L->nCcalls = oldnCcalls;
 
470
    L->ci = restoreci(L, old_ci);
 
471
    L->base = L->ci->base;
 
472
    L->savedpc = L->ci->savedpc;
 
473
    L->allowhook = old_allowhooks;
 
474
    restore_stack_limit(L);
 
475
  }
 
476
  L->errfunc = old_errfunc;
 
477
  return status;
 
478
}
 
479
 
 
480
 
 
481
 
 
482
/*
 
483
** Execute a protected parser.
 
484
*/
 
485
struct SParser {  /* data to `f_parser' */
 
486
  ZIO *z;
 
487
  Mbuffer buff;  /* buffer to be used by the scanner */
 
488
  const char *name;
 
489
};
 
490
 
 
491
static void f_parser (lua_State *L, void *ud) {
 
492
  int i;
 
493
  Proto *tf;
 
494
  Closure *cl;
 
495
  struct SParser *p = cast(struct SParser *, ud);
 
496
  int c = luaZ_lookahead(p->z);
 
497
  luaC_checkGC(L);
 
498
  tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z,
 
499
                                                             &p->buff, p->name);
 
500
  cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L)));
 
501
  cl->l.p = tf;
 
502
  for (i = 0; i < tf->nups; i++)  /* initialize eventual upvalues */
 
503
    cl->l.upvals[i] = luaF_newupval(L);
 
504
  setclvalue(L, L->top, cl);
 
505
  incr_top(L);
 
506
}
 
507
 
 
508
 
 
509
int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) {
 
510
  struct SParser p;
 
511
  int status;
 
512
  p.z = z; p.name = name;
 
513
  luaZ_initbuffer(L, &p.buff);
 
514
  status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
 
515
  luaZ_freebuffer(L, &p.buff);
 
516
  return status;
 
517
}
 
518
 
 
519