Previous 199869 Revisions Next

r22721 Thursday 9th May, 2013 at 13:57:44 UTC by Miodrag Milanović
LUA 5.2.2 added to libraries, did basic hookup of LUA VM into running machine [Miodrag Milanovic]
added -script (or -autoboot_script) command to execute LUA script after driver startup
[/trunk]makefile
[src/emu]emu.h emu.mak emuopts.c emuopts.h luaengine.c* luaengine.h* machine.c machine.h
[src/lib]lib.mak
[src/lib/lua]Makefile* lapi.c* lapi.h* lauxlib.c* lauxlib.h* lbaselib.c* lbitlib.c* lcode.c* lcode.h* lcorolib.c* lctype.c* lctype.h* ldblib.c* ldebug.c* ldebug.h* ldo.c* ldo.h* ldump.c* lfunc.c* lfunc.h* lgc.c* lgc.h* linit.c* liolib.c* llex.c* llex.h* llimits.h* lmathlib.c* lmem.c* lmem.h* loadlib.c* lobject.c* lobject.h* lopcodes.c* lopcodes.h* loslib.c* lparser.c* lparser.h* lstate.c* lstate.h* lstring.c* lstring.h* lstrlib.c* ltable.c* ltable.h* ltablib.c* ltm.c* ltm.h* lua.c* lua.h* lua.hpp* luac.c* luaconf.h* lualib.h* lundump.c* lundump.h* lvm.c* lvm.h* lzio.c* lzio.h*

trunk/makefile
r22720r22721
690690# add formats emulation library
691691FORMATS_LIB = $(OBJ)/libformats.a
692692
693# add LUA library
694LUA_LIB = $(OBJ)/liblua.a
695
693696# add PortMidi MIDI library
694697ifeq ($(BUILD_MIDILIB),1)
695698INCPATH += -I$(SRC)/lib/portmidi
r22720r22721
809812
810813ifndef EXECUTABLE_DEFINED
811814
812$(EMULATOR): $(EMUINFOOBJ) $(DRIVLISTOBJ) $(DRVLIBS) $(LIBOSD) $(LIBCPU) $(LIBEMU) $(LIBDASM) $(LIBSOUND) $(LIBUTIL) $(EXPAT) $(SOFTFLOAT) $(JPEG_LIB) $(FLAC_LIB) $(7Z_LIB) $(FORMATS_LIB) $(ZLIB) $(LIBOCORE) $(MIDI_LIB) $(RESFILE)
815$(EMULATOR): $(EMUINFOOBJ) $(DRIVLISTOBJ) $(DRVLIBS) $(LIBOSD) $(LIBCPU) $(LIBEMU) $(LIBDASM) $(LIBSOUND) $(LIBUTIL) $(EXPAT) $(SOFTFLOAT) $(JPEG_LIB) $(FLAC_LIB) $(7Z_LIB) $(FORMATS_LIB) $(LUA_LIB) $(ZLIB) $(LIBOCORE) $(MIDI_LIB) $(RESFILE)
813816   $(CC) $(CDEFS) $(CFLAGS) -c $(SRC)/version.c -o $(VERSIONOBJ)
814817   @echo Linking $@...
815818   $(LD) $(LDFLAGS) $(LDFLAGSEMULATOR) $(VERSIONOBJ) $^ $(LIBS) -o $@
trunk/src/lib/lua/lmem.h
r0r22721
1/*
2** $Id: lmem.h,v 1.40 2013/02/20 14:08:21 roberto Exp $
3** Interface to Memory Manager
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lmem_h
8#define lmem_h
9
10
11#include <stddef.h>
12
13#include "llimits.h"
14#include "lua.h"
15
16
17/*
18** This macro avoids the runtime division MAX_SIZET/(e), as 'e' is
19** always constant.
20** The macro is somewhat complex to avoid warnings:
21** +1 avoids warnings of "comparison has constant result";
22** cast to 'void' avoids warnings of "value unused".
23*/
24#define luaM_reallocv(L,b,on,n,e) \
25  (cast(void, \
26     (cast(size_t, (n)+1) > MAX_SIZET/(e)) ? (luaM_toobig(L), 0) : 0), \
27   luaM_realloc_(L, (b), (on)*(e), (n)*(e)))
28
29#define luaM_freemem(L, b, s)   luaM_realloc_(L, (b), (s), 0)
30#define luaM_free(L, b)      luaM_realloc_(L, (b), sizeof(*(b)), 0)
31#define luaM_freearray(L, b, n)   luaM_reallocv(L, (b), n, 0, sizeof((b)[0]))
32
33#define luaM_malloc(L,s)   luaM_realloc_(L, NULL, 0, (s))
34#define luaM_new(L,t)      cast(t *, luaM_malloc(L, sizeof(t)))
35#define luaM_newvector(L,n,t) \
36      cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
37
38#define luaM_newobject(L,tag,s)   luaM_realloc_(L, NULL, tag, (s))
39
40#define luaM_growvector(L,v,nelems,size,t,limit,e) \
41          if ((nelems)+1 > (size)) \
42            ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
43
44#define luaM_reallocvector(L, v,oldn,n,t) \
45   ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
46
47LUAI_FUNC l_noret luaM_toobig (lua_State *L);
48
49/* not to be called directly */
50LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
51                                                          size_t size);
52LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
53                               size_t size_elem, int limit,
54                               const char *what);
55
56#endif
57
Property changes on: trunk/src/lib/lua/lmem.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/lctype.c
r0r22721
1/*
2** $Id: lctype.c,v 1.11 2011/10/03 16:19:23 roberto Exp $
3** 'ctype' functions for Lua
4** See Copyright Notice in lua.h
5*/
6
7#define lctype_c
8#define LUA_CORE
9
10#include "lctype.h"
11
12#if !LUA_USE_CTYPE   /* { */
13
14#include <limits.h>
15
16LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = {
17  0x00,  /* EOZ */
18  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,   /* 0. */
19  0x00,  0x08,  0x08,  0x08,  0x08,  0x08,  0x00,  0x00,
20  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,   /* 1. */
21  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
22  0x0c,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,   /* 2. */
23  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,
24  0x16,  0x16,  0x16,  0x16,  0x16,  0x16,  0x16,  0x16,   /* 3. */
25  0x16,  0x16,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,
26  0x04,  0x15,  0x15,  0x15,  0x15,  0x15,  0x15,  0x05,   /* 4. */
27  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,
28  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,   /* 5. */
29  0x05,  0x05,  0x05,  0x04,  0x04,  0x04,  0x04,  0x05,
30  0x04,  0x15,  0x15,  0x15,  0x15,  0x15,  0x15,  0x05,   /* 6. */
31  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,
32  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,   /* 7. */
33  0x05,  0x05,  0x05,  0x04,  0x04,  0x04,  0x04,  0x00,
34  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,   /* 8. */
35  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
36  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,   /* 9. */
37  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
38  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,   /* a. */
39  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
40  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,   /* b. */
41  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
42  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,   /* c. */
43  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
44  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,   /* d. */
45  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
46  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,   /* e. */
47  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
48  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,   /* f. */
49  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
50};
51
52#endif         /* } */
Property changes on: trunk/src/lib/lua/lctype.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/lauxlib.c
r0r22721
1/*
2** $Id: lauxlib.c,v 1.248 2013/03/21 13:54:57 roberto Exp $
3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h
5*/
6
7
8#include <errno.h>
9#include <stdarg.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14
15/* This file uses only the official API of Lua.
16** Any function declared here could be written as an application function.
17*/
18
19#define lauxlib_c
20#define LUA_LIB
21
22#include "lua.h"
23
24#include "lauxlib.h"
25
26
27/*
28** {======================================================
29** Traceback
30** =======================================================
31*/
32
33
34#define LEVELS1   12   /* size of the first part of the stack */
35#define LEVELS2   10   /* size of the second part of the stack */
36
37
38
39/*
40** search for 'objidx' in table at index -1.
41** return 1 + string at top if find a good name.
42*/
43static int findfield (lua_State *L, int objidx, int level) {
44  if (level == 0 || !lua_istable(L, -1))
45    return 0;  /* not found */
46  lua_pushnil(L);  /* start 'next' loop */
47  while (lua_next(L, -2)) {  /* for each pair in table */
48    if (lua_type(L, -2) == LUA_TSTRING) {  /* ignore non-string keys */
49      if (lua_rawequal(L, objidx, -1)) {  /* found object? */
50        lua_pop(L, 1);  /* remove value (but keep name) */
51        return 1;
52      }
53      else if (findfield(L, objidx, level - 1)) {  /* try recursively */
54        lua_remove(L, -2);  /* remove table (but keep name) */
55        lua_pushliteral(L, ".");
56        lua_insert(L, -2);  /* place '.' between the two names */
57        lua_concat(L, 3);
58        return 1;
59      }
60    }
61    lua_pop(L, 1);  /* remove value */
62  }
63  return 0;  /* not found */
64}
65
66
67static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
68  int top = lua_gettop(L);
69  lua_getinfo(L, "f", ar);  /* push function */
70  lua_pushglobaltable(L);
71  if (findfield(L, top + 1, 2)) {
72    lua_copy(L, -1, top + 1);  /* move name to proper place */
73    lua_pop(L, 2);  /* remove pushed values */
74    return 1;
75  }
76  else {
77    lua_settop(L, top);  /* remove function and global table */
78    return 0;
79  }
80}
81
82
83static void pushfuncname (lua_State *L, lua_Debug *ar) {
84  if (*ar->namewhat != '\0')  /* is there a name? */
85    lua_pushfstring(L, "function " LUA_QS, ar->name);
86  else if (*ar->what == 'm')  /* main? */
87      lua_pushliteral(L, "main chunk");
88  else if (*ar->what == 'C') {
89    if (pushglobalfuncname(L, ar)) {
90      lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
91      lua_remove(L, -2);  /* remove name */
92    }
93    else
94      lua_pushliteral(L, "?");
95  }
96  else
97    lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
98}
99
100
101static int countlevels (lua_State *L) {
102  lua_Debug ar;
103  int li = 1, le = 1;
104  /* find an upper bound */
105  while (lua_getstack(L, le, &ar)) { li = le; le *= 2; }
106  /* do a binary search */
107  while (li < le) {
108    int m = (li + le)/2;
109    if (lua_getstack(L, m, &ar)) li = m + 1;
110    else le = m;
111  }
112  return le - 1;
113}
114
115
116LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1,
117                                const char *msg, int level) {
118  lua_Debug ar;
119  int top = lua_gettop(L);
120  int numlevels = countlevels(L1);
121  int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0;
122  if (msg) lua_pushfstring(L, "%s\n", msg);
123  lua_pushliteral(L, "stack traceback:");
124  while (lua_getstack(L1, level++, &ar)) {
125    if (level == mark) {  /* too many levels? */
126      lua_pushliteral(L, "\n\t...");  /* add a '...' */
127      level = numlevels - LEVELS2;  /* and skip to last ones */
128    }
129    else {
130      lua_getinfo(L1, "Slnt", &ar);
131      lua_pushfstring(L, "\n\t%s:", ar.short_src);
132      if (ar.currentline > 0)
133        lua_pushfstring(L, "%d:", ar.currentline);
134      lua_pushliteral(L, " in ");
135      pushfuncname(L, &ar);
136      if (ar.istailcall)
137        lua_pushliteral(L, "\n\t(...tail calls...)");
138      lua_concat(L, lua_gettop(L) - top);
139    }
140  }
141  lua_concat(L, lua_gettop(L) - top);
142}
143
144/* }====================================================== */
145
146
147/*
148** {======================================================
149** Error-report functions
150** =======================================================
151*/
152
153LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
154  lua_Debug ar;
155  if (!lua_getstack(L, 0, &ar))  /* no stack frame? */
156    return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);
157  lua_getinfo(L, "n", &ar);
158  if (strcmp(ar.namewhat, "method") == 0) {
159    narg--;  /* do not count `self' */
160    if (narg == 0)  /* error is in the self argument itself? */
161      return luaL_error(L, "calling " LUA_QS " on bad self (%s)",
162                           ar.name, extramsg);
163  }
164  if (ar.name == NULL)
165    ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?";
166  return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
167                        narg, ar.name, extramsg);
168}
169
170
171static int typeerror (lua_State *L, int narg, const char *tname) {
172  const char *msg = lua_pushfstring(L, "%s expected, got %s",
173                                    tname, luaL_typename(L, narg));
174  return luaL_argerror(L, narg, msg);
175}
176
177
178static void tag_error (lua_State *L, int narg, int tag) {
179  typeerror(L, narg, lua_typename(L, tag));
180}
181
182
183LUALIB_API void luaL_where (lua_State *L, int level) {
184  lua_Debug ar;
185  if (lua_getstack(L, level, &ar)) {  /* check function at level */
186    lua_getinfo(L, "Sl", &ar);  /* get info about it */
187    if (ar.currentline > 0) {  /* is there info? */
188      lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
189      return;
190    }
191  }
192  lua_pushliteral(L, "");  /* else, no information available... */
193}
194
195
196LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
197  va_list argp;
198  va_start(argp, fmt);
199  luaL_where(L, 1);
200  lua_pushvfstring(L, fmt, argp);
201  va_end(argp);
202  lua_concat(L, 2);
203  return lua_error(L);
204}
205
206
207LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
208  int en = errno;  /* calls to Lua API may change this value */
209  if (stat) {
210    lua_pushboolean(L, 1);
211    return 1;
212  }
213  else {
214    lua_pushnil(L);
215    if (fname)
216      lua_pushfstring(L, "%s: %s", fname, strerror(en));
217    else
218      lua_pushstring(L, strerror(en));
219    lua_pushinteger(L, en);
220    return 3;
221  }
222}
223
224
225#if !defined(inspectstat)   /* { */
226
227#if defined(LUA_USE_POSIX)
228
229#include <sys/wait.h>
230
231/*
232** use appropriate macros to interpret 'pclose' return status
233*/
234#define inspectstat(stat,what)  \
235   if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \
236   else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; }
237
238#else
239
240#define inspectstat(stat,what)  /* no op */
241
242#endif
243
244#endif            /* } */
245
246
247LUALIB_API int luaL_execresult (lua_State *L, int stat) {
248  const char *what = "exit";  /* type of termination */
249  if (stat == -1)  /* error? */
250    return luaL_fileresult(L, 0, NULL);
251  else {
252    inspectstat(stat, what);  /* interpret result */
253    if (*what == 'e' && stat == 0)  /* successful termination? */
254      lua_pushboolean(L, 1);
255    else
256      lua_pushnil(L);
257    lua_pushstring(L, what);
258    lua_pushinteger(L, stat);
259    return 3;  /* return true/nil,what,code */
260  }
261}
262
263/* }====================================================== */
264
265
266/*
267** {======================================================
268** Userdata's metatable manipulation
269** =======================================================
270*/
271
272LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
273  luaL_getmetatable(L, tname);  /* try to get metatable */
274  if (!lua_isnil(L, -1))  /* name already in use? */
275    return 0;  /* leave previous value on top, but return 0 */
276  lua_pop(L, 1);
277  lua_newtable(L);  /* create metatable */
278  lua_pushvalue(L, -1);
279  lua_setfield(L, LUA_REGISTRYINDEX, tname);  /* registry.name = metatable */
280  return 1;
281}
282
283
284LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) {
285  luaL_getmetatable(L, tname);
286  lua_setmetatable(L, -2);
287}
288
289
290LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
291  void *p = lua_touserdata(L, ud);
292  if (p != NULL) {  /* value is a userdata? */
293    if (lua_getmetatable(L, ud)) {  /* does it have a metatable? */
294      luaL_getmetatable(L, tname);  /* get correct metatable */
295      if (!lua_rawequal(L, -1, -2))  /* not the same? */
296        p = NULL;  /* value is a userdata with wrong metatable */
297      lua_pop(L, 2);  /* remove both metatables */
298      return p;
299    }
300  }
301  return NULL;  /* value is not a userdata with a metatable */
302}
303
304
305LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
306  void *p = luaL_testudata(L, ud, tname);
307  if (p == NULL) typeerror(L, ud, tname);
308  return p;
309}
310
311/* }====================================================== */
312
313
314/*
315** {======================================================
316** Argument check functions
317** =======================================================
318*/
319
320LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
321                                 const char *const lst[]) {
322  const char *name = (def) ? luaL_optstring(L, narg, def) :
323                             luaL_checkstring(L, narg);
324  int i;
325  for (i=0; lst[i]; i++)
326    if (strcmp(lst[i], name) == 0)
327      return i;
328  return luaL_argerror(L, narg,
329                       lua_pushfstring(L, "invalid option " LUA_QS, name));
330}
331
332
333LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
334  /* keep some extra space to run error routines, if needed */
335  const int extra = LUA_MINSTACK;
336  if (!lua_checkstack(L, space + extra)) {
337    if (msg)
338      luaL_error(L, "stack overflow (%s)", msg);
339    else
340      luaL_error(L, "stack overflow");
341  }
342}
343
344
345LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
346  if (lua_type(L, narg) != t)
347    tag_error(L, narg, t);
348}
349
350
351LUALIB_API void luaL_checkany (lua_State *L, int narg) {
352  if (lua_type(L, narg) == LUA_TNONE)
353    luaL_argerror(L, narg, "value expected");
354}
355
356
357LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
358  const char *s = lua_tolstring(L, narg, len);
359  if (!s) tag_error(L, narg, LUA_TSTRING);
360  return s;
361}
362
363
364LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
365                                        const char *def, size_t *len) {
366  if (lua_isnoneornil(L, narg)) {
367    if (len)
368      *len = (def ? strlen(def) : 0);
369    return def;
370  }
371  else return luaL_checklstring(L, narg, len);
372}
373
374
375LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
376  int isnum;
377  lua_Number d = lua_tonumberx(L, narg, &isnum);
378  if (!isnum)
379    tag_error(L, narg, LUA_TNUMBER);
380  return d;
381}
382
383
384LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
385  return luaL_opt(L, luaL_checknumber, narg, def);
386}
387
388
389LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
390  int isnum;
391  lua_Integer d = lua_tointegerx(L, narg, &isnum);
392  if (!isnum)
393    tag_error(L, narg, LUA_TNUMBER);
394  return d;
395}
396
397
398LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int narg) {
399  int isnum;
400  lua_Unsigned d = lua_tounsignedx(L, narg, &isnum);
401  if (!isnum)
402    tag_error(L, narg, LUA_TNUMBER);
403  return d;
404}
405
406
407LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
408                                                      lua_Integer def) {
409  return luaL_opt(L, luaL_checkinteger, narg, def);
410}
411
412
413LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int narg,
414                                                        lua_Unsigned def) {
415  return luaL_opt(L, luaL_checkunsigned, narg, def);
416}
417
418/* }====================================================== */
419
420
421/*
422** {======================================================
423** Generic Buffer manipulation
424** =======================================================
425*/
426
427/*
428** check whether buffer is using a userdata on the stack as a temporary
429** buffer
430*/
431#define buffonstack(B)   ((B)->b != (B)->initb)
432
433
434/*
435** returns a pointer to a free area with at least 'sz' bytes
436*/
437LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
438  lua_State *L = B->L;
439  if (B->size - B->n < sz) {  /* not enough space? */
440    char *newbuff;
441    size_t newsize = B->size * 2;  /* double buffer size */
442    if (newsize - B->n < sz)  /* not big enough? */
443      newsize = B->n + sz;
444    if (newsize < B->n || newsize - B->n < sz)
445      luaL_error(L, "buffer too large");
446    /* create larger buffer */
447    newbuff = (char *)lua_newuserdata(L, newsize * sizeof(char));
448    /* move content to new buffer */
449    memcpy(newbuff, B->b, B->n * sizeof(char));
450    if (buffonstack(B))
451      lua_remove(L, -2);  /* remove old buffer */
452    B->b = newbuff;
453    B->size = newsize;
454  }
455  return &B->b[B->n];
456}
457
458
459LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
460  char *b = luaL_prepbuffsize(B, l);
461  memcpy(b, s, l * sizeof(char));
462  luaL_addsize(B, l);
463}
464
465
466LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
467  luaL_addlstring(B, s, strlen(s));
468}
469
470
471LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
472  lua_State *L = B->L;
473  lua_pushlstring(L, B->b, B->n);
474  if (buffonstack(B))
475    lua_remove(L, -2);  /* remove old buffer */
476}
477
478
479LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) {
480  luaL_addsize(B, sz);
481  luaL_pushresult(B);
482}
483
484
485LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
486  lua_State *L = B->L;
487  size_t l;
488  const char *s = lua_tolstring(L, -1, &l);
489  if (buffonstack(B))
490    lua_insert(L, -2);  /* put value below buffer */
491  luaL_addlstring(B, s, l);
492  lua_remove(L, (buffonstack(B)) ? -2 : -1);  /* remove value */
493}
494
495
496LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
497  B->L = L;
498  B->b = B->initb;
499  B->n = 0;
500  B->size = LUAL_BUFFERSIZE;
501}
502
503
504LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
505  luaL_buffinit(L, B);
506  return luaL_prepbuffsize(B, sz);
507}
508
509/* }====================================================== */
510
511
512/*
513** {======================================================
514** Reference system
515** =======================================================
516*/
517
518/* index of free-list header */
519#define freelist   0
520
521
522LUALIB_API int luaL_ref (lua_State *L, int t) {
523  int ref;
524  if (lua_isnil(L, -1)) {
525    lua_pop(L, 1);  /* remove from stack */
526    return LUA_REFNIL;  /* `nil' has a unique fixed reference */
527  }
528  t = lua_absindex(L, t);
529  lua_rawgeti(L, t, freelist);  /* get first free element */
530  ref = (int)lua_tointeger(L, -1);  /* ref = t[freelist] */
531  lua_pop(L, 1);  /* remove it from stack */
532  if (ref != 0) {  /* any free element? */
533    lua_rawgeti(L, t, ref);  /* remove it from list */
534    lua_rawseti(L, t, freelist);  /* (t[freelist] = t[ref]) */
535  }
536  else  /* no free elements */
537    ref = (int)lua_rawlen(L, t) + 1;  /* get a new reference */
538  lua_rawseti(L, t, ref);
539  return ref;
540}
541
542
543LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
544  if (ref >= 0) {
545    t = lua_absindex(L, t);
546    lua_rawgeti(L, t, freelist);
547    lua_rawseti(L, t, ref);  /* t[ref] = t[freelist] */
548    lua_pushinteger(L, ref);
549    lua_rawseti(L, t, freelist);  /* t[freelist] = ref */
550  }
551}
552
553/* }====================================================== */
554
555
556/*
557** {======================================================
558** Load functions
559** =======================================================
560*/
561
562typedef struct LoadF {
563  int n;  /* number of pre-read characters */
564  FILE *f;  /* file being read */
565  char buff[LUAL_BUFFERSIZE];  /* area for reading file */
566} LoadF;
567
568
569static const char *getF (lua_State *L, void *ud, size_t *size) {
570  LoadF *lf = (LoadF *)ud;
571  (void)L;  /* not used */
572  if (lf->n > 0) {  /* are there pre-read characters to be read? */
573    *size = lf->n;  /* return them (chars already in buffer) */
574    lf->n = 0;  /* no more pre-read characters */
575  }
576  else {  /* read a block from file */
577    /* 'fread' can return > 0 *and* set the EOF flag. If next call to
578       'getF' called 'fread', it might still wait for user input.
579       The next check avoids this problem. */
580    if (feof(lf->f)) return NULL;
581    *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);  /* read block */
582  }
583  return lf->buff;
584}
585
586
587static int errfile (lua_State *L, const char *what, int fnameindex) {
588  const char *serr = strerror(errno);
589  const char *filename = lua_tostring(L, fnameindex) + 1;
590  lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
591  lua_remove(L, fnameindex);
592  return LUA_ERRFILE;
593}
594
595
596static int skipBOM (LoadF *lf) {
597  const char *p = "\xEF\xBB\xBF";  /* Utf8 BOM mark */
598  int c;
599  lf->n = 0;
600  do {
601    c = getc(lf->f);
602    if (c == EOF || c != *(const unsigned char *)p++) return c;
603    lf->buff[lf->n++] = c;  /* to be read by the parser */
604  } while (*p != '\0');
605  lf->n = 0;  /* prefix matched; discard it */
606  return getc(lf->f);  /* return next character */
607}
608
609
610/*
611** reads the first character of file 'f' and skips an optional BOM mark
612** in its beginning plus its first line if it starts with '#'. Returns
613** true if it skipped the first line.  In any case, '*cp' has the
614** first "valid" character of the file (after the optional BOM and
615** a first-line comment).
616*/
617static int skipcomment (LoadF *lf, int *cp) {
618  int c = *cp = skipBOM(lf);
619  if (c == '#') {  /* first line is a comment (Unix exec. file)? */
620    do {  /* skip first line */
621      c = getc(lf->f);
622    } while (c != EOF && c != '\n') ;
623    *cp = getc(lf->f);  /* skip end-of-line, if present */
624    return 1;  /* there was a comment */
625  }
626  else return 0;  /* no comment */
627}
628
629
630LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
631                                             const char *mode) {
632  LoadF lf;
633  int status, readstatus;
634  int c;
635  int fnameindex = lua_gettop(L) + 1;  /* index of filename on the stack */
636  if (filename == NULL) {
637    lua_pushliteral(L, "=stdin");
638    lf.f = stdin;
639  }
640  else {
641    lua_pushfstring(L, "@%s", filename);
642    lf.f = fopen(filename, "r");
643    if (lf.f == NULL) return errfile(L, "open", fnameindex);
644  }
645  if (skipcomment(&lf, &c))  /* read initial portion */
646    lf.buff[lf.n++] = '\n';  /* add line to correct line numbers */
647  if (c == LUA_SIGNATURE[0] && filename) {  /* binary file? */
648    lf.f = freopen(filename, "rb", lf.f);  /* reopen in binary mode */
649    if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
650    skipcomment(&lf, &c);  /* re-read initial portion */
651  }
652  if (c != EOF)
653    lf.buff[lf.n++] = c;  /* 'c' is the first character of the stream */
654  status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
655  readstatus = ferror(lf.f);
656  if (filename) fclose(lf.f);  /* close file (even in case of errors) */
657  if (readstatus) {
658    lua_settop(L, fnameindex);  /* ignore results from `lua_load' */
659    return errfile(L, "read", fnameindex);
660  }
661  lua_remove(L, fnameindex);
662  return status;
663}
664
665
666typedef struct LoadS {
667  const char *s;
668  size_t size;
669} LoadS;
670
671
672static const char *getS (lua_State *L, void *ud, size_t *size) {
673  LoadS *ls = (LoadS *)ud;
674  (void)L;  /* not used */
675  if (ls->size == 0) return NULL;
676  *size = ls->size;
677  ls->size = 0;
678  return ls->s;
679}
680
681
682LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size,
683                                 const char *name, const char *mode) {
684  LoadS ls;
685  ls.s = buff;
686  ls.size = size;
687  return lua_load(L, getS, &ls, name, mode);
688}
689
690
691LUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
692  return luaL_loadbuffer(L, s, strlen(s), s);
693}
694
695/* }====================================================== */
696
697
698
699LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
700  if (!lua_getmetatable(L, obj))  /* no metatable? */
701    return 0;
702  lua_pushstring(L, event);
703  lua_rawget(L, -2);
704  if (lua_isnil(L, -1)) {
705    lua_pop(L, 2);  /* remove metatable and metafield */
706    return 0;
707  }
708  else {
709    lua_remove(L, -2);  /* remove only metatable */
710    return 1;
711  }
712}
713
714
715LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
716  obj = lua_absindex(L, obj);
717  if (!luaL_getmetafield(L, obj, event))  /* no metafield? */
718    return 0;
719  lua_pushvalue(L, obj);
720  lua_call(L, 1, 1);
721  return 1;
722}
723
724
725LUALIB_API int luaL_len (lua_State *L, int idx) {
726  int l;
727  int isnum;
728  lua_len(L, idx);
729  l = (int)lua_tointegerx(L, -1, &isnum);
730  if (!isnum)
731    luaL_error(L, "object length is not a number");
732  lua_pop(L, 1);  /* remove object */
733  return l;
734}
735
736
737LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
738  if (!luaL_callmeta(L, idx, "__tostring")) {  /* no metafield? */
739    switch (lua_type(L, idx)) {
740      case LUA_TNUMBER:
741      case LUA_TSTRING:
742        lua_pushvalue(L, idx);
743        break;
744      case LUA_TBOOLEAN:
745        lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false"));
746        break;
747      case LUA_TNIL:
748        lua_pushliteral(L, "nil");
749        break;
750      default:
751        lua_pushfstring(L, "%s: %p", luaL_typename(L, idx),
752                                            lua_topointer(L, idx));
753        break;
754    }
755  }
756  return lua_tolstring(L, -1, len);
757}
758
759
760/*
761** {======================================================
762** Compatibility with 5.1 module functions
763** =======================================================
764*/
765#if defined(LUA_COMPAT_MODULE)
766
767static const char *luaL_findtable (lua_State *L, int idx,
768                                   const char *fname, int szhint) {
769  const char *e;
770  if (idx) lua_pushvalue(L, idx);
771  do {
772    e = strchr(fname, '.');
773    if (e == NULL) e = fname + strlen(fname);
774    lua_pushlstring(L, fname, e - fname);
775    lua_rawget(L, -2);
776    if (lua_isnil(L, -1)) {  /* no such field? */
777      lua_pop(L, 1);  /* remove this nil */
778      lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
779      lua_pushlstring(L, fname, e - fname);
780      lua_pushvalue(L, -2);
781      lua_settable(L, -4);  /* set new table into field */
782    }
783    else if (!lua_istable(L, -1)) {  /* field has a non-table value? */
784      lua_pop(L, 2);  /* remove table and value */
785      return fname;  /* return problematic part of the name */
786    }
787    lua_remove(L, -2);  /* remove previous table */
788    fname = e + 1;
789  } while (*e == '.');
790  return NULL;
791}
792
793
794/*
795** Count number of elements in a luaL_Reg list.
796*/
797static int libsize (const luaL_Reg *l) {
798  int size = 0;
799  for (; l && l->name; l++) size++;
800  return size;
801}
802
803
804/*
805** Find or create a module table with a given name. The function
806** first looks at the _LOADED table and, if that fails, try a
807** global variable with that name. In any case, leaves on the stack
808** the module table.
809*/
810LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
811                                 int sizehint) {
812  luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);  /* get _LOADED table */
813  lua_getfield(L, -1, modname);  /* get _LOADED[modname] */
814  if (!lua_istable(L, -1)) {  /* not found? */
815    lua_pop(L, 1);  /* remove previous result */
816    /* try global variable (and create one if it does not exist) */
817    lua_pushglobaltable(L);
818    if (luaL_findtable(L, 0, modname, sizehint) != NULL)
819      luaL_error(L, "name conflict for module " LUA_QS, modname);
820    lua_pushvalue(L, -1);
821    lua_setfield(L, -3, modname);  /* _LOADED[modname] = new table */
822  }
823  lua_remove(L, -2);  /* remove _LOADED table */
824}
825
826
827LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
828                               const luaL_Reg *l, int nup) {
829  luaL_checkversion(L);
830  if (libname) {
831    luaL_pushmodule(L, libname, libsize(l));  /* get/create library table */
832    lua_insert(L, -(nup + 1));  /* move library table to below upvalues */
833  }
834  if (l)
835    luaL_setfuncs(L, l, nup);
836  else
837    lua_pop(L, nup);  /* remove upvalues */
838}
839
840#endif
841/* }====================================================== */
842
843/*
844** set functions from list 'l' into table at top - 'nup'; each
845** function gets the 'nup' elements at the top as upvalues.
846** Returns with only the table at the stack.
847*/
848LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
849  luaL_checkversion(L);
850  luaL_checkstack(L, nup, "too many upvalues");
851  for (; l->name != NULL; l++) {  /* fill the table with given functions */
852    int i;
853    for (i = 0; i < nup; i++)  /* copy upvalues to the top */
854      lua_pushvalue(L, -nup);
855    lua_pushcclosure(L, l->func, nup);  /* closure with those upvalues */
856    lua_setfield(L, -(nup + 2), l->name);
857  }
858  lua_pop(L, nup);  /* remove upvalues */
859}
860
861
862/*
863** ensure that stack[idx][fname] has a table and push that table
864** into the stack
865*/
866LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) {
867  lua_getfield(L, idx, fname);
868  if (lua_istable(L, -1)) return 1;  /* table already there */
869  else {
870    lua_pop(L, 1);  /* remove previous result */
871    idx = lua_absindex(L, idx);
872    lua_newtable(L);
873    lua_pushvalue(L, -1);  /* copy to be left at top */
874    lua_setfield(L, idx, fname);  /* assign new table to field */
875    return 0;  /* false, because did not find table there */
876  }
877}
878
879
880/*
881** stripped-down 'require'. Calls 'openf' to open a module,
882** registers the result in 'package.loaded' table and, if 'glb'
883** is true, also registers the result in the global table.
884** Leaves resulting module on the top.
885*/
886LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
887                               lua_CFunction openf, int glb) {
888  lua_pushcfunction(L, openf);
889  lua_pushstring(L, modname);  /* argument to open function */
890  lua_call(L, 1, 1);  /* open module */
891  luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
892  lua_pushvalue(L, -2);  /* make copy of module (call result) */
893  lua_setfield(L, -2, modname);  /* _LOADED[modname] = module */
894  lua_pop(L, 1);  /* remove _LOADED table */
895  if (glb) {
896    lua_pushvalue(L, -1);  /* copy of 'mod' */
897    lua_setglobal(L, modname);  /* _G[modname] = module */
898  }
899}
900
901
902LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
903                                                               const char *r) {
904  const char *wild;
905  size_t l = strlen(p);
906  luaL_Buffer b;
907  luaL_buffinit(L, &b);
908  while ((wild = strstr(s, p)) != NULL) {
909    luaL_addlstring(&b, s, wild - s);  /* push prefix */
910    luaL_addstring(&b, r);  /* push replacement in place of pattern */
911    s = wild + l;  /* continue after `p' */
912  }
913  luaL_addstring(&b, s);  /* push last suffix */
914  luaL_pushresult(&b);
915  return lua_tostring(L, -1);
916}
917
918
919static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
920  (void)ud; (void)osize;  /* not used */
921  if (nsize == 0) {
922    free(ptr);
923    return NULL;
924  }
925  else
926    return realloc(ptr, nsize);
927}
928
929
930static int panic (lua_State *L) {
931  luai_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
932                   lua_tostring(L, -1));
933  return 0;  /* return to Lua to abort */
934}
935
936
937LUALIB_API lua_State *luaL_newstate (void) {
938  lua_State *L = lua_newstate(l_alloc, NULL);
939  if (L) lua_atpanic(L, &panic);
940  return L;
941}
942
943
944LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver) {
945  const lua_Number *v = lua_version(L);
946  if (v != lua_version(NULL))
947    luaL_error(L, "multiple Lua VMs detected");
948  else if (*v != ver)
949    luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
950                  ver, *v);
951  /* check conversions number -> integer types */
952  lua_pushnumber(L, -(lua_Number)0x1234);
953  if (lua_tointeger(L, -1) != -0x1234 ||
954      lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234)
955    luaL_error(L, "bad conversion number->int;"
956                  " must recompile Lua with proper settings");
957  lua_pop(L, 1);
958}
959
Property changes on: trunk/src/lib/lua/lauxlib.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/lstate.h
r0r22721
1/*
2** $Id: lstate.h,v 2.82 2012/07/02 13:37:04 roberto Exp $
3** Global State
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lstate_h
8#define lstate_h
9
10#include "lua.h"
11
12#include "lobject.h"
13#include "ltm.h"
14#include "lzio.h"
15
16
17/*
18
19** Some notes about garbage-collected objects:  All objects in Lua must
20** be kept somehow accessible until being freed.
21**
22** Lua keeps most objects linked in list g->allgc. The link uses field
23** 'next' of the CommonHeader.
24**
25** Strings are kept in several lists headed by the array g->strt.hash.
26**
27** Open upvalues are not subject to independent garbage collection. They
28** are collected together with their respective threads. Lua keeps a
29** double-linked list with all open upvalues (g->uvhead) so that it can
30** mark objects referred by them. (They are always gray, so they must
31** be remarked in the atomic step. Usually their contents would be marked
32** when traversing the respective threads, but the thread may already be
33** dead, while the upvalue is still accessible through closures.)
34**
35** Objects with finalizers are kept in the list g->finobj.
36**
37** The list g->tobefnz links all objects being finalized.
38
39*/
40
41
42struct lua_longjmp;  /* defined in ldo.c */
43
44
45
46/* extra stack space to handle TM calls and some other extras */
47#define EXTRA_STACK   5
48
49
50#define BASIC_STACK_SIZE        (2*LUA_MINSTACK)
51
52
53/* kinds of Garbage Collection */
54#define KGC_NORMAL   0
55#define KGC_EMERGENCY   1   /* gc was forced by an allocation failure */
56#define KGC_GEN      2   /* generational collection */
57
58
59typedef struct stringtable {
60  GCObject **hash;
61  lu_int32 nuse;  /* number of elements */
62  int size;
63} stringtable;
64
65
66/*
67** information about a call
68*/
69typedef struct CallInfo {
70  StkId func;  /* function index in the stack */
71  StkId   top;  /* top for this function */
72  struct CallInfo *previous, *next;  /* dynamic call link */
73  short nresults;  /* expected number of results from this function */
74  lu_byte callstatus;
75  ptrdiff_t extra;
76  union {
77    struct {  /* only for Lua functions */
78      StkId base;  /* base for this function */
79      const Instruction *savedpc;
80    } l;
81    struct {  /* only for C functions */
82      int ctx;  /* context info. in case of yields */
83      lua_CFunction k;  /* continuation in case of yields */
84      ptrdiff_t old_errfunc;
85      lu_byte old_allowhook;
86      lu_byte status;
87    } c;
88  } u;
89} CallInfo;
90
91
92/*
93** Bits in CallInfo status
94*/
95#define CIST_LUA   (1<<0)   /* call is running a Lua function */
96#define CIST_HOOKED   (1<<1)   /* call is running a debug hook */
97#define CIST_REENTRY   (1<<2)   /* call is running on same invocation of
98                                   luaV_execute of previous call */
99#define CIST_YIELDED   (1<<3)   /* call reentered after suspension */
100#define CIST_YPCALL   (1<<4)   /* call is a yieldable protected call */
101#define CIST_STAT   (1<<5)   /* call has an error status (pcall) */
102#define CIST_TAIL   (1<<6)   /* call was tail called */
103#define CIST_HOOKYIELD   (1<<7)   /* last hook called yielded */
104
105
106#define isLua(ci)   ((ci)->callstatus & CIST_LUA)
107
108
109/*
110** `global state', shared by all threads of this state
111*/
112typedef struct global_State {
113  lua_Alloc frealloc;  /* function to reallocate memory */
114  void *ud;         /* auxiliary data to `frealloc' */
115  lu_mem totalbytes;  /* number of bytes currently allocated - GCdebt */
116  l_mem GCdebt;  /* bytes allocated not yet compensated by the collector */
117  lu_mem GCmemtrav;  /* memory traversed by the GC */
118  lu_mem GCestimate;  /* an estimate of the non-garbage memory in use */
119  stringtable strt;  /* hash table for strings */
120  TValue l_registry;
121  unsigned int seed;  /* randomized seed for hashes */
122  lu_byte currentwhite;
123  lu_byte gcstate;  /* state of garbage collector */
124  lu_byte gckind;  /* kind of GC running */
125  lu_byte gcrunning;  /* true if GC is running */
126  int sweepstrgc;  /* position of sweep in `strt' */
127  GCObject *allgc;  /* list of all collectable objects */
128  GCObject *finobj;  /* list of collectable objects with finalizers */
129  GCObject **sweepgc;  /* current position of sweep in list 'allgc' */
130  GCObject **sweepfin;  /* current position of sweep in list 'finobj' */
131  GCObject *gray;  /* list of gray objects */
132  GCObject *grayagain;  /* list of objects to be traversed atomically */
133  GCObject *weak;  /* list of tables with weak values */
134  GCObject *ephemeron;  /* list of ephemeron tables (weak keys) */
135  GCObject *allweak;  /* list of all-weak tables */
136  GCObject *tobefnz;  /* list of userdata to be GC */
137  UpVal uvhead;  /* head of double-linked list of all open upvalues */
138  Mbuffer buff;  /* temporary buffer for string concatenation */
139  int gcpause;  /* size of pause between successive GCs */
140  int gcmajorinc;  /* pause between major collections (only in gen. mode) */
141  int gcstepmul;  /* GC `granularity' */
142  lua_CFunction panic;  /* to be called in unprotected errors */
143  struct lua_State *mainthread;
144  const lua_Number *version;  /* pointer to version number */
145  TString *memerrmsg;  /* memory-error message */
146  TString *tmname[TM_N];  /* array with tag-method names */
147  struct Table *mt[LUA_NUMTAGS];  /* metatables for basic types */
148} global_State;
149
150
151/*
152** `per thread' state
153*/
154struct lua_State {
155  CommonHeader;
156  lu_byte status;
157  StkId top;  /* first free slot in the stack */
158  global_State *l_G;
159  CallInfo *ci;  /* call info for current function */
160  const Instruction *oldpc;  /* last pc traced */
161  StkId stack_last;  /* last free slot in the stack */
162  StkId stack;  /* stack base */
163  int stacksize;
164  unsigned short nny;  /* number of non-yieldable calls in stack */
165  unsigned short nCcalls;  /* number of nested C calls */
166  lu_byte hookmask;
167  lu_byte allowhook;
168  int basehookcount;
169  int hookcount;
170  lua_Hook hook;
171  GCObject *openupval;  /* list of open upvalues in this stack */
172  GCObject *gclist;
173  struct lua_longjmp *errorJmp;  /* current error recover point */
174  ptrdiff_t errfunc;  /* current error handling function (stack index) */
175  CallInfo base_ci;  /* CallInfo for first level (C calling Lua) */
176};
177
178
179#define G(L)   (L->l_G)
180
181
182/*
183** Union of all collectable objects
184*/
185union GCObject {
186  GCheader gch;  /* common header */
187  union TString ts;
188  union Udata u;
189  union Closure cl;
190  struct Table h;
191  struct Proto p;
192  struct UpVal uv;
193  struct lua_State th;  /* thread */
194};
195
196
197#define gch(o)      (&(o)->gch)
198
199/* macros to convert a GCObject into a specific value */
200#define rawgco2ts(o)  \
201   check_exp(novariant((o)->gch.tt) == LUA_TSTRING, &((o)->ts))
202#define gco2ts(o)   (&rawgco2ts(o)->tsv)
203#define rawgco2u(o)   check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
204#define gco2u(o)   (&rawgco2u(o)->uv)
205#define gco2lcl(o)   check_exp((o)->gch.tt == LUA_TLCL, &((o)->cl.l))
206#define gco2ccl(o)   check_exp((o)->gch.tt == LUA_TCCL, &((o)->cl.c))
207#define gco2cl(o)  \
208   check_exp(novariant((o)->gch.tt) == LUA_TFUNCTION, &((o)->cl))
209#define gco2t(o)   check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
210#define gco2p(o)   check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
211#define gco2uv(o)   check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
212#define gco2th(o)   check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
213
214/* macro to convert any Lua object into a GCObject */
215#define obj2gco(v)   (cast(GCObject *, (v)))
216
217
218/* actual number of total bytes allocated */
219#define gettotalbytes(g)   ((g)->totalbytes + (g)->GCdebt)
220
221LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt);
222LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
223LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
224LUAI_FUNC void luaE_freeCI (lua_State *L);
225
226
227#endif
228
Property changes on: trunk/src/lib/lua/lstate.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/ltable.c
r0r22721
1/*
2** $Id: ltable.c,v 2.72 2012/09/11 19:37:16 roberto Exp $
3** Lua tables (hash)
4** See Copyright Notice in lua.h
5*/
6
7
8/*
9** Implementation of tables (aka arrays, objects, or hash tables).
10** Tables keep its elements in two parts: an array part and a hash part.
11** Non-negative integer keys are all candidates to be kept in the array
12** part. The actual size of the array is the largest `n' such that at
13** least half the slots between 0 and n are in use.
14** Hash uses a mix of chained scatter table with Brent's variation.
15** A main invariant of these tables is that, if an element is not
16** in its main position (i.e. the `original' position that its hash gives
17** to it), then the colliding element is in its own main position.
18** Hence even when the load factor reaches 100%, performance remains good.
19*/
20
21#include <string.h>
22
23#define ltable_c
24#define LUA_CORE
25
26#include "lua.h"
27
28#include "ldebug.h"
29#include "ldo.h"
30#include "lgc.h"
31#include "lmem.h"
32#include "lobject.h"
33#include "lstate.h"
34#include "lstring.h"
35#include "ltable.h"
36#include "lvm.h"
37
38
39/*
40** max size of array part is 2^MAXBITS
41*/
42#if LUAI_BITSINT >= 32
43#define MAXBITS      30
44#else
45#define MAXBITS      (LUAI_BITSINT-2)
46#endif
47
48#define MAXASIZE   (1 << MAXBITS)
49
50
51#define hashpow2(t,n)      (gnode(t, lmod((n), sizenode(t))))
52
53#define hashstr(t,str)      hashpow2(t, (str)->tsv.hash)
54#define hashboolean(t,p)   hashpow2(t, p)
55
56
57/*
58** for some types, it is better to avoid modulus by power of 2, as
59** they tend to have many 2 factors.
60*/
61#define hashmod(t,n)   (gnode(t, ((n) % ((sizenode(t)-1)|1))))
62
63
64#define hashpointer(t,p)   hashmod(t, IntPoint(p))
65
66
67#define dummynode      (&dummynode_)
68
69#define isdummy(n)      ((n) == dummynode)
70
71static const Node dummynode_ = {
72  {NILCONSTANT},  /* value */
73  {{NILCONSTANT, NULL}}  /* key */
74};
75
76
77/*
78** hash for lua_Numbers
79*/
80static Node *hashnum (const Table *t, lua_Number n) {
81  int i;
82  luai_hashnum(i, n);
83  if (i < 0) {
84    if (cast(unsigned int, i) == 0u - i)  /* use unsigned to avoid overflows */
85      i = 0;  /* handle INT_MIN */
86    i = -i;  /* must be a positive value */
87  }
88  return hashmod(t, i);
89}
90
91
92
93/*
94** returns the `main' position of an element in a table (that is, the index
95** of its hash value)
96*/
97static Node *mainposition (const Table *t, const TValue *key) {
98  switch (ttype(key)) {
99    case LUA_TNUMBER:
100      return hashnum(t, nvalue(key));
101    case LUA_TLNGSTR: {
102      TString *s = rawtsvalue(key);
103      if (s->tsv.extra == 0) {  /* no hash? */
104        s->tsv.hash = luaS_hash(getstr(s), s->tsv.len, s->tsv.hash);
105        s->tsv.extra = 1;  /* now it has its hash */
106      }
107      return hashstr(t, rawtsvalue(key));
108    }
109    case LUA_TSHRSTR:
110      return hashstr(t, rawtsvalue(key));
111    case LUA_TBOOLEAN:
112      return hashboolean(t, bvalue(key));
113    case LUA_TLIGHTUSERDATA:
114      return hashpointer(t, pvalue(key));
115    case LUA_TLCF:
116      return hashpointer(t, fvalue(key));
117    default:
118      return hashpointer(t, gcvalue(key));
119  }
120}
121
122
123/*
124** returns the index for `key' if `key' is an appropriate key to live in
125** the array part of the table, -1 otherwise.
126*/
127static int arrayindex (const TValue *key) {
128  if (ttisnumber(key)) {
129    lua_Number n = nvalue(key);
130    int k;
131    lua_number2int(k, n);
132    if (luai_numeq(cast_num(k), n))
133      return k;
134  }
135  return -1;  /* `key' did not match some condition */
136}
137
138
139/*
140** returns the index of a `key' for table traversals. First goes all
141** elements in the array part, then elements in the hash part. The
142** beginning of a traversal is signaled by -1.
143*/
144static int findindex (lua_State *L, Table *t, StkId key) {
145  int i;
146  if (ttisnil(key)) return -1;  /* first iteration */
147  i = arrayindex(key);
148  if (0 < i && i <= t->sizearray)  /* is `key' inside array part? */
149    return i-1;  /* yes; that's the index (corrected to C) */
150  else {
151    Node *n = mainposition(t, key);
152    for (;;) {  /* check whether `key' is somewhere in the chain */
153      /* key may be dead already, but it is ok to use it in `next' */
154      if (luaV_rawequalobj(gkey(n), key) ||
155            (ttisdeadkey(gkey(n)) && iscollectable(key) &&
156             deadvalue(gkey(n)) == gcvalue(key))) {
157        i = cast_int(n - gnode(t, 0));  /* key index in hash table */
158        /* hash elements are numbered after array ones */
159        return i + t->sizearray;
160      }
161      else n = gnext(n);
162      if (n == NULL)
163        luaG_runerror(L, "invalid key to " LUA_QL("next"));  /* key not found */
164    }
165  }
166}
167
168
169int luaH_next (lua_State *L, Table *t, StkId key) {
170  int i = findindex(L, t, key);  /* find original element */
171  for (i++; i < t->sizearray; i++) {  /* try first array part */
172    if (!ttisnil(&t->array[i])) {  /* a non-nil value? */
173      setnvalue(key, cast_num(i+1));
174      setobj2s(L, key+1, &t->array[i]);
175      return 1;
176    }
177  }
178  for (i -= t->sizearray; i < sizenode(t); i++) {  /* then hash part */
179    if (!ttisnil(gval(gnode(t, i)))) {  /* a non-nil value? */
180      setobj2s(L, key, gkey(gnode(t, i)));
181      setobj2s(L, key+1, gval(gnode(t, i)));
182      return 1;
183    }
184  }
185  return 0;  /* no more elements */
186}
187
188
189/*
190** {=============================================================
191** Rehash
192** ==============================================================
193*/
194
195
196static int computesizes (int nums[], int *narray) {
197  int i;
198  int twotoi;  /* 2^i */
199  int a = 0;  /* number of elements smaller than 2^i */
200  int na = 0;  /* number of elements to go to array part */
201  int n = 0;  /* optimal size for array part */
202  for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
203    if (nums[i] > 0) {
204      a += nums[i];
205      if (a > twotoi/2) {  /* more than half elements present? */
206        n = twotoi;  /* optimal size (till now) */
207        na = a;  /* all elements smaller than n will go to array part */
208      }
209    }
210    if (a == *narray) break;  /* all elements already counted */
211  }
212  *narray = n;
213  lua_assert(*narray/2 <= na && na <= *narray);
214  return na;
215}
216
217
218static int countint (const TValue *key, int *nums) {
219  int k = arrayindex(key);
220  if (0 < k && k <= MAXASIZE) {  /* is `key' an appropriate array index? */
221    nums[luaO_ceillog2(k)]++;  /* count as such */
222    return 1;
223  }
224  else
225    return 0;
226}
227
228
229static int numusearray (const Table *t, int *nums) {
230  int lg;
231  int ttlg;  /* 2^lg */
232  int ause = 0;  /* summation of `nums' */
233  int i = 1;  /* count to traverse all array keys */
234  for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) {  /* for each slice */
235    int lc = 0;  /* counter */
236    int lim = ttlg;
237    if (lim > t->sizearray) {
238      lim = t->sizearray;  /* adjust upper limit */
239      if (i > lim)
240        break;  /* no more elements to count */
241    }
242    /* count elements in range (2^(lg-1), 2^lg] */
243    for (; i <= lim; i++) {
244      if (!ttisnil(&t->array[i-1]))
245        lc++;
246    }
247    nums[lg] += lc;
248    ause += lc;
249  }
250  return ause;
251}
252
253
254static int numusehash (const Table *t, int *nums, int *pnasize) {
255  int totaluse = 0;  /* total number of elements */
256  int ause = 0;  /* summation of `nums' */
257  int i = sizenode(t);
258  while (i--) {
259    Node *n = &t->node[i];
260    if (!ttisnil(gval(n))) {
261      ause += countint(gkey(n), nums);
262      totaluse++;
263    }
264  }
265  *pnasize += ause;
266  return totaluse;
267}
268
269
270static void setarrayvector (lua_State *L, Table *t, int size) {
271  int i;
272  luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
273  for (i=t->sizearray; i<size; i++)
274     setnilvalue(&t->array[i]);
275  t->sizearray = size;
276}
277
278
279static void setnodevector (lua_State *L, Table *t, int size) {
280  int lsize;
281  if (size == 0) {  /* no elements to hash part? */
282    t->node = cast(Node *, dummynode);  /* use common `dummynode' */
283    lsize = 0;
284  }
285  else {
286    int i;
287    lsize = luaO_ceillog2(size);
288    if (lsize > MAXBITS)
289      luaG_runerror(L, "table overflow");
290    size = twoto(lsize);
291    t->node = luaM_newvector(L, size, Node);
292    for (i=0; i<size; i++) {
293      Node *n = gnode(t, i);
294      gnext(n) = NULL;
295      setnilvalue(gkey(n));
296      setnilvalue(gval(n));
297    }
298  }
299  t->lsizenode = cast_byte(lsize);
300  t->lastfree = gnode(t, size);  /* all positions are free */
301}
302
303
304void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
305  int i;
306  int oldasize = t->sizearray;
307  int oldhsize = t->lsizenode;
308  Node *nold = t->node;  /* save old hash ... */
309  if (nasize > oldasize)  /* array part must grow? */
310    setarrayvector(L, t, nasize);
311  /* create new hash part with appropriate size */
312  setnodevector(L, t, nhsize);
313  if (nasize < oldasize) {  /* array part must shrink? */
314    t->sizearray = nasize;
315    /* re-insert elements from vanishing slice */
316    for (i=nasize; i<oldasize; i++) {
317      if (!ttisnil(&t->array[i]))
318        luaH_setint(L, t, i + 1, &t->array[i]);
319    }
320    /* shrink array */
321    luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
322  }
323  /* re-insert elements from hash part */
324  for (i = twoto(oldhsize) - 1; i >= 0; i--) {
325    Node *old = nold+i;
326    if (!ttisnil(gval(old))) {
327      /* doesn't need barrier/invalidate cache, as entry was
328         already present in the table */
329      setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old));
330    }
331  }
332  if (!isdummy(nold))
333    luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old array */
334}
335
336
337void luaH_resizearray (lua_State *L, Table *t, int nasize) {
338  int nsize = isdummy(t->node) ? 0 : sizenode(t);
339  luaH_resize(L, t, nasize, nsize);
340}
341
342
343static void rehash (lua_State *L, Table *t, const TValue *ek) {
344  int nasize, na;
345  int nums[MAXBITS+1];  /* nums[i] = number of keys with 2^(i-1) < k <= 2^i */
346  int i;
347  int totaluse;
348  for (i=0; i<=MAXBITS; i++) nums[i] = 0;  /* reset counts */
349  nasize = numusearray(t, nums);  /* count keys in array part */
350  totaluse = nasize;  /* all those keys are integer keys */
351  totaluse += numusehash(t, nums, &nasize);  /* count keys in hash part */
352  /* count extra key */
353  nasize += countint(ek, nums);
354  totaluse++;
355  /* compute new size for array part */
356  na = computesizes(nums, &nasize);
357  /* resize the table to new computed sizes */
358  luaH_resize(L, t, nasize, totaluse - na);
359}
360
361
362
363/*
364** }=============================================================
365*/
366
367
368Table *luaH_new (lua_State *L) {
369  Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h;
370  t->metatable = NULL;
371  t->flags = cast_byte(~0);
372  t->array = NULL;
373  t->sizearray = 0;
374  setnodevector(L, t, 0);
375  return t;
376}
377
378
379void luaH_free (lua_State *L, Table *t) {
380  if (!isdummy(t->node))
381    luaM_freearray(L, t->node, cast(size_t, sizenode(t)));
382  luaM_freearray(L, t->array, t->sizearray);
383  luaM_free(L, t);
384}
385
386
387static Node *getfreepos (Table *t) {
388  while (t->lastfree > t->node) {
389    t->lastfree--;
390    if (ttisnil(gkey(t->lastfree)))
391      return t->lastfree;
392  }
393  return NULL;  /* could not find a free place */
394}
395
396
397
398/*
399** inserts a new key into a hash table; first, check whether key's main
400** position is free. If not, check whether colliding node is in its main
401** position or not: if it is not, move colliding node to an empty place and
402** put new key in its main position; otherwise (colliding node is in its main
403** position), new key goes to an empty position.
404*/
405TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
406  Node *mp;
407  if (ttisnil(key)) luaG_runerror(L, "table index is nil");
408  else if (ttisnumber(key) && luai_numisnan(L, nvalue(key)))
409    luaG_runerror(L, "table index is NaN");
410  mp = mainposition(t, key);
411  if (!ttisnil(gval(mp)) || isdummy(mp)) {  /* main position is taken? */
412    Node *othern;
413    Node *n = getfreepos(t);  /* get a free place */
414    if (n == NULL) {  /* cannot find a free place? */
415      rehash(L, t, key);  /* grow table */
416      /* whatever called 'newkey' take care of TM cache and GC barrier */
417      return luaH_set(L, t, key);  /* insert key into grown table */
418    }
419    lua_assert(!isdummy(n));
420    othern = mainposition(t, gkey(mp));
421    if (othern != mp) {  /* is colliding node out of its main position? */
422      /* yes; move colliding node into free position */
423      while (gnext(othern) != mp) othern = gnext(othern);  /* find previous */
424      gnext(othern) = n;  /* redo the chain with `n' in place of `mp' */
425      *n = *mp;  /* copy colliding node into free pos. (mp->next also goes) */
426      gnext(mp) = NULL;  /* now `mp' is free */
427      setnilvalue(gval(mp));
428    }
429    else {  /* colliding node is in its own main position */
430      /* new node will go into free position */
431      gnext(n) = gnext(mp);  /* chain new position */
432      gnext(mp) = n;
433      mp = n;
434    }
435  }
436  setobj2t(L, gkey(mp), key);
437  luaC_barrierback(L, obj2gco(t), key);
438  lua_assert(ttisnil(gval(mp)));
439  return gval(mp);
440}
441
442
443/*
444** search function for integers
445*/
446const TValue *luaH_getint (Table *t, int key) {
447  /* (1 <= key && key <= t->sizearray) */
448  if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
449    return &t->array[key-1];
450  else {
451    lua_Number nk = cast_num(key);
452    Node *n = hashnum(t, nk);
453    do {  /* check whether `key' is somewhere in the chain */
454      if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
455        return gval(n);  /* that's it */
456      else n = gnext(n);
457    } while (n);
458    return luaO_nilobject;
459  }
460}
461
462
463/*
464** search function for short strings
465*/
466const TValue *luaH_getstr (Table *t, TString *key) {
467  Node *n = hashstr(t, key);
468  lua_assert(key->tsv.tt == LUA_TSHRSTR);
469  do {  /* check whether `key' is somewhere in the chain */
470    if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key))
471      return gval(n);  /* that's it */
472    else n = gnext(n);
473  } while (n);
474  return luaO_nilobject;
475}
476
477
478/*
479** main search function
480*/
481const TValue *luaH_get (Table *t, const TValue *key) {
482  switch (ttype(key)) {
483    case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key));
484    case LUA_TNIL: return luaO_nilobject;
485    case LUA_TNUMBER: {
486      int k;
487      lua_Number n = nvalue(key);
488      lua_number2int(k, n);
489      if (luai_numeq(cast_num(k), n)) /* index is int? */
490        return luaH_getint(t, k);  /* use specialized version */
491      /* else go through */
492    }
493    default: {
494      Node *n = mainposition(t, key);
495      do {  /* check whether `key' is somewhere in the chain */
496        if (luaV_rawequalobj(gkey(n), key))
497          return gval(n);  /* that's it */
498        else n = gnext(n);
499      } while (n);
500      return luaO_nilobject;
501    }
502  }
503}
504
505
506/*
507** beware: when using this function you probably need to check a GC
508** barrier and invalidate the TM cache.
509*/
510TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
511  const TValue *p = luaH_get(t, key);
512  if (p != luaO_nilobject)
513    return cast(TValue *, p);
514  else return luaH_newkey(L, t, key);
515}
516
517
518void luaH_setint (lua_State *L, Table *t, int key, TValue *value) {
519  const TValue *p = luaH_getint(t, key);
520  TValue *cell;
521  if (p != luaO_nilobject)
522    cell = cast(TValue *, p);
523  else {
524    TValue k;
525    setnvalue(&k, cast_num(key));
526    cell = luaH_newkey(L, t, &k);
527  }
528  setobj2t(L, cell, value);
529}
530
531
532static int unbound_search (Table *t, unsigned int j) {
533  unsigned int i = j;  /* i is zero or a present index */
534  j++;
535  /* find `i' and `j' such that i is present and j is not */
536  while (!ttisnil(luaH_getint(t, j))) {
537    i = j;
538    j *= 2;
539    if (j > cast(unsigned int, MAX_INT)) {  /* overflow? */
540      /* table was built with bad purposes: resort to linear search */
541      i = 1;
542      while (!ttisnil(luaH_getint(t, i))) i++;
543      return i - 1;
544    }
545  }
546  /* now do a binary search between them */
547  while (j - i > 1) {
548    unsigned int m = (i+j)/2;
549    if (ttisnil(luaH_getint(t, m))) j = m;
550    else i = m;
551  }
552  return i;
553}
554
555
556/*
557** Try to find a boundary in table `t'. A `boundary' is an integer index
558** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
559*/
560int luaH_getn (Table *t) {
561  unsigned int j = t->sizearray;
562  if (j > 0 && ttisnil(&t->array[j - 1])) {
563    /* there is a boundary in the array part: (binary) search for it */
564    unsigned int i = 0;
565    while (j - i > 1) {
566      unsigned int m = (i+j)/2;
567      if (ttisnil(&t->array[m - 1])) j = m;
568      else i = m;
569    }
570    return i;
571  }
572  /* else must find a boundary in hash part */
573  else if (isdummy(t->node))  /* hash part is empty? */
574    return j;  /* that is easy... */
575  else return unbound_search(t, j);
576}
577
578
579
580#if defined(LUA_DEBUG)
581
582Node *luaH_mainposition (const Table *t, const TValue *key) {
583  return mainposition(t, key);
584}
585
586int luaH_isdummy (Node *n) { return isdummy(n); }
587
588#endif
Property changes on: trunk/src/lib/lua/ltable.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/llex.c
r0r22721
1/*
2** $Id: llex.c,v 2.63 2013/03/16 21:10:18 roberto Exp $
3** Lexical Analyzer
4** See Copyright Notice in lua.h
5*/
6
7
8#include <locale.h>
9#include <string.h>
10
11#define llex_c
12#define LUA_CORE
13
14#include "lua.h"
15
16#include "lctype.h"
17#include "ldo.h"
18#include "llex.h"
19#include "lobject.h"
20#include "lparser.h"
21#include "lstate.h"
22#include "lstring.h"
23#include "ltable.h"
24#include "lzio.h"
25
26
27
28#define next(ls) (ls->current = zgetc(ls->z))
29
30
31
32#define currIsNewline(ls)   (ls->current == '\n' || ls->current == '\r')
33
34
35/* ORDER RESERVED */
36static const char *const luaX_tokens [] = {
37    "and", "break", "do", "else", "elseif",
38    "end", "false", "for", "function", "goto", "if",
39    "in", "local", "nil", "not", "or", "repeat",
40    "return", "then", "true", "until", "while",
41    "..", "...", "==", ">=", "<=", "~=", "::", "<eof>",
42    "<number>", "<name>", "<string>"
43};
44
45
46#define save_and_next(ls) (save(ls, ls->current), next(ls))
47
48
49static l_noret lexerror (LexState *ls, const char *msg, int token);
50
51
52static void save (LexState *ls, int c) {
53  Mbuffer *b = ls->buff;
54  if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) {
55    size_t newsize;
56    if (luaZ_sizebuffer(b) >= MAX_SIZET/2)
57      lexerror(ls, "lexical element too long", 0);
58    newsize = luaZ_sizebuffer(b) * 2;
59    luaZ_resizebuffer(ls->L, b, newsize);
60  }
61  b->buffer[luaZ_bufflen(b)++] = cast(char, c);
62}
63
64
65void luaX_init (lua_State *L) {
66  int i;
67  for (i=0; i<NUM_RESERVED; i++) {
68    TString *ts = luaS_new(L, luaX_tokens[i]);
69    luaS_fix(ts);  /* reserved words are never collected */
70    ts->tsv.extra = cast_byte(i+1);  /* reserved word */
71  }
72}
73
74
75const char *luaX_token2str (LexState *ls, int token) {
76  if (token < FIRST_RESERVED) {  /* single-byte symbols? */
77    lua_assert(token == cast(unsigned char, token));
78    return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) :
79                              luaO_pushfstring(ls->L, "char(%d)", token);
80  }
81  else {
82    const char *s = luaX_tokens[token - FIRST_RESERVED];
83    if (token < TK_EOS)  /* fixed format (symbols and reserved words)? */
84      return luaO_pushfstring(ls->L, LUA_QS, s);
85    else  /* names, strings, and numerals */
86      return s;
87  }
88}
89
90
91static const char *txtToken (LexState *ls, int token) {
92  switch (token) {
93    case TK_NAME:
94    case TK_STRING:
95    case TK_NUMBER:
96      save(ls, '\0');
97      return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff));
98    default:
99      return luaX_token2str(ls, token);
100  }
101}
102
103
104static l_noret lexerror (LexState *ls, const char *msg, int token) {
105  char buff[LUA_IDSIZE];
106  luaO_chunkid(buff, getstr(ls->source), LUA_IDSIZE);
107  msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
108  if (token)
109    luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token));
110  luaD_throw(ls->L, LUA_ERRSYNTAX);
111}
112
113
114l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
115  lexerror(ls, msg, ls->t.token);
116}
117
118
119/*
120** creates a new string and anchors it in function's table so that
121** it will not be collected until the end of the function's compilation
122** (by that time it should be anchored in function's prototype)
123*/
124TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
125  lua_State *L = ls->L;
126  TValue *o;  /* entry for `str' */
127  TString *ts = luaS_newlstr(L, str, l);  /* create new string */
128  setsvalue2s(L, L->top++, ts);  /* temporarily anchor it in stack */
129  o = luaH_set(L, ls->fs->h, L->top - 1);
130  if (ttisnil(o)) {  /* not in use yet? (see 'addK') */
131    /* boolean value does not need GC barrier;
132       table has no metatable, so it does not need to invalidate cache */
133    setbvalue(o, 1);  /* t[string] = true */
134    luaC_checkGC(L);
135  }
136  L->top--;  /* remove string from stack */
137  return ts;
138}
139
140
141/*
142** increment line number and skips newline sequence (any of
143** \n, \r, \n\r, or \r\n)
144*/
145static void inclinenumber (LexState *ls) {
146  int old = ls->current;
147  lua_assert(currIsNewline(ls));
148  next(ls);  /* skip `\n' or `\r' */
149  if (currIsNewline(ls) && ls->current != old)
150    next(ls);  /* skip `\n\r' or `\r\n' */
151  if (++ls->linenumber >= MAX_INT)
152    luaX_syntaxerror(ls, "chunk has too many lines");
153}
154
155
156void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
157                    int firstchar) {
158  ls->decpoint = '.';
159  ls->L = L;
160  ls->current = firstchar;
161  ls->lookahead.token = TK_EOS;  /* no look-ahead token */
162  ls->z = z;
163  ls->fs = NULL;
164  ls->linenumber = 1;
165  ls->lastline = 1;
166  ls->source = source;
167  ls->envn = luaS_new(L, LUA_ENV);  /* create env name */
168  luaS_fix(ls->envn);  /* never collect this name */
169  luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER);  /* initialize buffer */
170}
171
172
173
174/*
175** =======================================================
176** LEXICAL ANALYZER
177** =======================================================
178*/
179
180
181
182static int check_next (LexState *ls, const char *set) {
183  if (ls->current == '\0' || !strchr(set, ls->current))
184    return 0;
185  save_and_next(ls);
186  return 1;
187}
188
189
190/*
191** change all characters 'from' in buffer to 'to'
192*/
193static void buffreplace (LexState *ls, char from, char to) {
194  size_t n = luaZ_bufflen(ls->buff);
195  char *p = luaZ_buffer(ls->buff);
196  while (n--)
197    if (p[n] == from) p[n] = to;
198}
199
200
201#if !defined(getlocaledecpoint)
202#define getlocaledecpoint()   (localeconv()->decimal_point[0])
203#endif
204
205
206#define buff2d(b,e)   luaO_str2d(luaZ_buffer(b), luaZ_bufflen(b) - 1, e)
207
208/*
209** in case of format error, try to change decimal point separator to
210** the one defined in the current locale and check again
211*/
212static void trydecpoint (LexState *ls, SemInfo *seminfo) {
213  char old = ls->decpoint;
214  ls->decpoint = getlocaledecpoint();
215  buffreplace(ls, old, ls->decpoint);  /* try new decimal separator */
216  if (!buff2d(ls->buff, &seminfo->r)) {
217    /* format error with correct decimal point: no more options */
218    buffreplace(ls, ls->decpoint, '.');  /* undo change (for error message) */
219    lexerror(ls, "malformed number", TK_NUMBER);
220  }
221}
222
223
224/* LUA_NUMBER */
225/*
226** this function is quite liberal in what it accepts, as 'luaO_str2d'
227** will reject ill-formed numerals.
228*/
229static void read_numeral (LexState *ls, SemInfo *seminfo) {
230  const char *expo = "Ee";
231  int first = ls->current;
232  lua_assert(lisdigit(ls->current));
233  save_and_next(ls);
234  if (first == '0' && check_next(ls, "Xx"))  /* hexadecimal? */
235    expo = "Pp";
236  for (;;) {
237    if (check_next(ls, expo))  /* exponent part? */
238      check_next(ls, "+-");  /* optional exponent sign */
239    if (lisxdigit(ls->current) || ls->current == '.')
240      save_and_next(ls);
241    else  break;
242  }
243  save(ls, '\0');
244  buffreplace(ls, '.', ls->decpoint);  /* follow locale for decimal point */
245  if (!buff2d(ls->buff, &seminfo->r))  /* format error? */
246    trydecpoint(ls, seminfo); /* try to update decimal point separator */
247}
248
249
250/*
251** skip a sequence '[=*[' or ']=*]' and return its number of '='s or
252** -1 if sequence is malformed
253*/
254static int skip_sep (LexState *ls) {
255  int count = 0;
256  int s = ls->current;
257  lua_assert(s == '[' || s == ']');
258  save_and_next(ls);
259  while (ls->current == '=') {
260    save_and_next(ls);
261    count++;
262  }
263  return (ls->current == s) ? count : (-count) - 1;
264}
265
266
267static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
268  save_and_next(ls);  /* skip 2nd `[' */
269  if (currIsNewline(ls))  /* string starts with a newline? */
270    inclinenumber(ls);  /* skip it */
271  for (;;) {
272    switch (ls->current) {
273      case EOZ:
274        lexerror(ls, (seminfo) ? "unfinished long string" :
275                                 "unfinished long comment", TK_EOS);
276        break;  /* to avoid warnings */
277      case ']': {
278        if (skip_sep(ls) == sep) {
279          save_and_next(ls);  /* skip 2nd `]' */
280          goto endloop;
281        }
282        break;
283      }
284      case '\n': case '\r': {
285        save(ls, '\n');
286        inclinenumber(ls);
287        if (!seminfo) luaZ_resetbuffer(ls->buff);  /* avoid wasting space */
288        break;
289      }
290      default: {
291        if (seminfo) save_and_next(ls);
292        else next(ls);
293      }
294    }
295  } endloop:
296  if (seminfo)
297    seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep),
298                                     luaZ_bufflen(ls->buff) - 2*(2 + sep));
299}
300
301
302static void escerror (LexState *ls, int *c, int n, const char *msg) {
303  int i;
304  luaZ_resetbuffer(ls->buff);  /* prepare error message */
305  save(ls, '\\');
306  for (i = 0; i < n && c[i] != EOZ; i++)
307    save(ls, c[i]);
308  lexerror(ls, msg, TK_STRING);
309}
310
311
312static int readhexaesc (LexState *ls) {
313  int c[3], i;  /* keep input for error message */
314  int r = 0;  /* result accumulator */
315  c[0] = 'x';  /* for error message */
316  for (i = 1; i < 3; i++) {  /* read two hexadecimal digits */
317    c[i] = next(ls);
318    if (!lisxdigit(c[i]))
319      escerror(ls, c, i + 1, "hexadecimal digit expected");
320    r = (r << 4) + luaO_hexavalue(c[i]);
321  }
322  return r;
323}
324
325
326static int readdecesc (LexState *ls) {
327  int c[3], i;
328  int r = 0;  /* result accumulator */
329  for (i = 0; i < 3 && lisdigit(ls->current); i++) {  /* read up to 3 digits */
330    c[i] = ls->current;
331    r = 10*r + c[i] - '0';
332    next(ls);
333  }
334  if (r > UCHAR_MAX)
335    escerror(ls, c, i, "decimal escape too large");
336  return r;
337}
338
339
340static void read_string (LexState *ls, int del, SemInfo *seminfo) {
341  save_and_next(ls);  /* keep delimiter (for error messages) */
342  while (ls->current != del) {
343    switch (ls->current) {
344      case EOZ:
345        lexerror(ls, "unfinished string", TK_EOS);
346        break;  /* to avoid warnings */
347      case '\n':
348      case '\r':
349        lexerror(ls, "unfinished string", TK_STRING);
350        break;  /* to avoid warnings */
351      case '\\': {  /* escape sequences */
352        int c;  /* final character to be saved */
353        next(ls);  /* do not save the `\' */
354        switch (ls->current) {
355          case 'a': c = '\a'; goto read_save;
356          case 'b': c = '\b'; goto read_save;
357          case 'f': c = '\f'; goto read_save;
358          case 'n': c = '\n'; goto read_save;
359          case 'r': c = '\r'; goto read_save;
360          case 't': c = '\t'; goto read_save;
361          case 'v': c = '\v'; goto read_save;
362          case 'x': c = readhexaesc(ls); goto read_save;
363          case '\n': case '\r':
364            inclinenumber(ls); c = '\n'; goto only_save;
365          case '\\': case '\"': case '\'':
366            c = ls->current; goto read_save;
367          case EOZ: goto no_save;  /* will raise an error next loop */
368          case 'z': {  /* zap following span of spaces */
369            next(ls);  /* skip the 'z' */
370            while (lisspace(ls->current)) {
371              if (currIsNewline(ls)) inclinenumber(ls);
372              else next(ls);
373            }
374            goto no_save;
375          }
376          default: {
377            if (!lisdigit(ls->current))
378              escerror(ls, &ls->current, 1, "invalid escape sequence");
379            /* digital escape \ddd */
380            c = readdecesc(ls);
381            goto only_save;
382          }
383        }
384       read_save: next(ls);  /* read next character */
385       only_save: save(ls, c);  /* save 'c' */
386       no_save: break;
387      }
388      default:
389        save_and_next(ls);
390    }
391  }
392  save_and_next(ls);  /* skip delimiter */
393  seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
394                                   luaZ_bufflen(ls->buff) - 2);
395}
396
397
398static int llex (LexState *ls, SemInfo *seminfo) {
399  luaZ_resetbuffer(ls->buff);
400  for (;;) {
401    switch (ls->current) {
402      case '\n': case '\r': {  /* line breaks */
403        inclinenumber(ls);
404        break;
405      }
406      case ' ': case '\f': case '\t': case '\v': {  /* spaces */
407        next(ls);
408        break;
409      }
410      case '-': {  /* '-' or '--' (comment) */
411        next(ls);
412        if (ls->current != '-') return '-';
413        /* else is a comment */
414        next(ls);
415        if (ls->current == '[') {  /* long comment? */
416          int sep = skip_sep(ls);
417          luaZ_resetbuffer(ls->buff);  /* `skip_sep' may dirty the buffer */
418          if (sep >= 0) {
419            read_long_string(ls, NULL, sep);  /* skip long comment */
420            luaZ_resetbuffer(ls->buff);  /* previous call may dirty the buff. */
421            break;
422          }
423        }
424        /* else short comment */
425        while (!currIsNewline(ls) && ls->current != EOZ)
426          next(ls);  /* skip until end of line (or end of file) */
427        break;
428      }
429      case '[': {  /* long string or simply '[' */
430        int sep = skip_sep(ls);
431        if (sep >= 0) {
432          read_long_string(ls, seminfo, sep);
433          return TK_STRING;
434        }
435        else if (sep == -1) return '[';
436        else lexerror(ls, "invalid long string delimiter", TK_STRING);
437      }
438      case '=': {
439        next(ls);
440        if (ls->current != '=') return '=';
441        else { next(ls); return TK_EQ; }
442      }
443      case '<': {
444        next(ls);
445        if (ls->current != '=') return '<';
446        else { next(ls); return TK_LE; }
447      }
448      case '>': {
449        next(ls);
450        if (ls->current != '=') return '>';
451        else { next(ls); return TK_GE; }
452      }
453      case '~': {
454        next(ls);
455        if (ls->current != '=') return '~';
456        else { next(ls); return TK_NE; }
457      }
458      case ':': {
459        next(ls);
460        if (ls->current != ':') return ':';
461        else { next(ls); return TK_DBCOLON; }
462      }
463      case '"': case '\'': {  /* short literal strings */
464        read_string(ls, ls->current, seminfo);
465        return TK_STRING;
466      }
467      case '.': {  /* '.', '..', '...', or number */
468        save_and_next(ls);
469        if (check_next(ls, ".")) {
470          if (check_next(ls, "."))
471            return TK_DOTS;   /* '...' */
472          else return TK_CONCAT;   /* '..' */
473        }
474        else if (!lisdigit(ls->current)) return '.';
475        /* else go through */
476      }
477      case '0': case '1': case '2': case '3': case '4':
478      case '5': case '6': case '7': case '8': case '9': {
479        read_numeral(ls, seminfo);
480        return TK_NUMBER;
481      }
482      case EOZ: {
483        return TK_EOS;
484      }
485      default: {
486        if (lislalpha(ls->current)) {  /* identifier or reserved word? */
487          TString *ts;
488          do {
489            save_and_next(ls);
490          } while (lislalnum(ls->current));
491          ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
492                                  luaZ_bufflen(ls->buff));
493          seminfo->ts = ts;
494          if (isreserved(ts))  /* reserved word? */
495            return ts->tsv.extra - 1 + FIRST_RESERVED;
496          else {
497            return TK_NAME;
498          }
499        }
500        else {  /* single-char tokens (+ - / ...) */
501          int c = ls->current;
502          next(ls);
503          return c;
504        }
505      }
506    }
507  }
508}
509
510
511void luaX_next (LexState *ls) {
512  ls->lastline = ls->linenumber;
513  if (ls->lookahead.token != TK_EOS) {  /* is there a look-ahead token? */
514    ls->t = ls->lookahead;  /* use this one */
515    ls->lookahead.token = TK_EOS;  /* and discharge it */
516  }
517  else
518    ls->t.token = llex(ls, &ls->t.seminfo);  /* read next token */
519}
520
521
522int luaX_lookahead (LexState *ls) {
523  lua_assert(ls->lookahead.token == TK_EOS);
524  ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
525  return ls->lookahead.token;
526}
527
Property changes on: trunk/src/lib/lua/llex.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/lctype.h
r0r22721
1/*
2** $Id: lctype.h,v 1.12 2011/07/15 12:50:29 roberto Exp $
3** 'ctype' functions for Lua
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lctype_h
8#define lctype_h
9
10#include "lua.h"
11
12
13/*
14** WARNING: the functions defined here do not necessarily correspond
15** to the similar functions in the standard C ctype.h. They are
16** optimized for the specific needs of Lua
17*/
18
19#if !defined(LUA_USE_CTYPE)
20
21#if 'A' == 65 && '0' == 48
22/* ASCII case: can use its own tables; faster and fixed */
23#define LUA_USE_CTYPE   0
24#else
25/* must use standard C ctype */
26#define LUA_USE_CTYPE   1
27#endif
28
29#endif
30
31
32#if !LUA_USE_CTYPE   /* { */
33
34#include <limits.h>
35
36#include "llimits.h"
37
38
39#define ALPHABIT   0
40#define DIGITBIT   1
41#define PRINTBIT   2
42#define SPACEBIT   3
43#define XDIGITBIT   4
44
45
46#define MASK(B)      (1 << (B))
47
48
49/*
50** add 1 to char to allow index -1 (EOZ)
51*/
52#define testprop(c,p)   (luai_ctype_[(c)+1] & (p))
53
54/*
55** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_'
56*/
57#define lislalpha(c)   testprop(c, MASK(ALPHABIT))
58#define lislalnum(c)   testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT)))
59#define lisdigit(c)   testprop(c, MASK(DIGITBIT))
60#define lisspace(c)   testprop(c, MASK(SPACEBIT))
61#define lisprint(c)   testprop(c, MASK(PRINTBIT))
62#define lisxdigit(c)   testprop(c, MASK(XDIGITBIT))
63
64/*
65** this 'ltolower' only works for alphabetic characters
66*/
67#define ltolower(c)   ((c) | ('A' ^ 'a'))
68
69
70/* two more entries for 0 and -1 (EOZ) */
71LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2];
72
73
74#else         /* }{ */
75
76/*
77** use standard C ctypes
78*/
79
80#include <ctype.h>
81
82
83#define lislalpha(c)   (isalpha(c) || (c) == '_')
84#define lislalnum(c)   (isalnum(c) || (c) == '_')
85#define lisdigit(c)   (isdigit(c))
86#define lisspace(c)   (isspace(c))
87#define lisprint(c)   (isprint(c))
88#define lisxdigit(c)   (isxdigit(c))
89
90#define ltolower(c)   (tolower(c))
91
92#endif         /* } */
93
94#endif
95
Property changes on: trunk/src/lib/lua/lctype.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/lauxlib.h
r0r22721
1/*
2** $Id: lauxlib.h,v 1.120 2011/11/29 15:55:08 roberto Exp $
3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lauxlib_h
9#define lauxlib_h
10
11
12#include <stddef.h>
13#include <stdio.h>
14
15#include "lua.h"
16
17
18
19/* extra error code for `luaL_load' */
20#define LUA_ERRFILE     (LUA_ERRERR+1)
21
22
23typedef struct luaL_Reg {
24  const char *name;
25  lua_CFunction func;
26} luaL_Reg;
27
28
29LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver);
30#define luaL_checkversion(L)   luaL_checkversion_(L, LUA_VERSION_NUM)
31
32LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
33LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
34LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
35LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
36LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
37                                                          size_t *l);
38LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
39                                          const char *def, size_t *l);
40LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
41LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
42
43LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
44LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
45                                          lua_Integer def);
46LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg);
47LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg,
48                                            lua_Unsigned def);
49
50LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
51LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
52LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
53
54LUALIB_API int   (luaL_newmetatable) (lua_State *L, const char *tname);
55LUALIB_API void  (luaL_setmetatable) (lua_State *L, const char *tname);
56LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
57LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
58
59LUALIB_API void (luaL_where) (lua_State *L, int lvl);
60LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
61
62LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
63                                   const char *const lst[]);
64
65LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname);
66LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
67
68/* pre-defined references */
69#define LUA_NOREF       (-2)
70#define LUA_REFNIL      (-1)
71
72LUALIB_API int (luaL_ref) (lua_State *L, int t);
73LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
74
75LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
76                                               const char *mode);
77
78#define luaL_loadfile(L,f)   luaL_loadfilex(L,f,NULL)
79
80LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
81                                   const char *name, const char *mode);
82LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
83
84LUALIB_API lua_State *(luaL_newstate) (void);
85
86LUALIB_API int (luaL_len) (lua_State *L, int idx);
87
88LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
89                                                  const char *r);
90
91LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
92
93LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname);
94
95LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1,
96                                  const char *msg, int level);
97
98LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
99                                 lua_CFunction openf, int glb);
100
101/*
102** ===============================================================
103** some useful macros
104** ===============================================================
105*/
106
107
108#define luaL_newlibtable(L,l)   \
109  lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
110
111#define luaL_newlib(L,l)   (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
112
113#define luaL_argcheck(L, cond,numarg,extramsg)   \
114      ((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
115#define luaL_checkstring(L,n)   (luaL_checklstring(L, (n), NULL))
116#define luaL_optstring(L,n,d)   (luaL_optlstring(L, (n), (d), NULL))
117#define luaL_checkint(L,n)   ((int)luaL_checkinteger(L, (n)))
118#define luaL_optint(L,n,d)   ((int)luaL_optinteger(L, (n), (d)))
119#define luaL_checklong(L,n)   ((long)luaL_checkinteger(L, (n)))
120#define luaL_optlong(L,n,d)   ((long)luaL_optinteger(L, (n), (d)))
121
122#define luaL_typename(L,i)   lua_typename(L, lua_type(L,(i)))
123
124#define luaL_dofile(L, fn) \
125   (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
126
127#define luaL_dostring(L, s) \
128   (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
129
130#define luaL_getmetatable(L,n)   (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
131
132#define luaL_opt(L,f,n,d)   (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
133
134#define luaL_loadbuffer(L,s,sz,n)   luaL_loadbufferx(L,s,sz,n,NULL)
135
136
137/*
138** {======================================================
139** Generic Buffer manipulation
140** =======================================================
141*/
142
143typedef struct luaL_Buffer {
144  char *b;  /* buffer address */
145  size_t size;  /* buffer size */
146  size_t n;  /* number of characters in buffer */
147  lua_State *L;
148  char initb[LUAL_BUFFERSIZE];  /* initial buffer */
149} luaL_Buffer;
150
151
152#define luaL_addchar(B,c) \
153  ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \
154   ((B)->b[(B)->n++] = (c)))
155
156#define luaL_addsize(B,s)   ((B)->n += (s))
157
158LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
159LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
160LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
161LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
162LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
163LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
164LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz);
165LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz);
166
167#define luaL_prepbuffer(B)   luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
168
169/* }====================================================== */
170
171
172
173/*
174** {======================================================
175** File handles for IO library
176** =======================================================
177*/
178
179/*
180** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and
181** initial structure 'luaL_Stream' (it may contain other fields
182** after that initial structure).
183*/
184
185#define LUA_FILEHANDLE          "FILE*"
186
187
188typedef struct luaL_Stream {
189  FILE *f;  /* stream (NULL for incompletely created streams) */
190  lua_CFunction closef;  /* to close stream (NULL for closed streams) */
191} luaL_Stream;
192
193/* }====================================================== */
194
195
196
197/* compatibility with old module system */
198#if defined(LUA_COMPAT_MODULE)
199
200LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname,
201                                   int sizehint);
202LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
203                                const luaL_Reg *l, int nup);
204
205#define luaL_register(L,n,l)   (luaL_openlib(L,(n),(l),0))
206
207#endif
208
209
210#endif
211
212
Property changes on: trunk/src/lib/lua/lauxlib.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/ltable.h
r0r22721
1/*
2** $Id: ltable.h,v 2.16 2011/08/17 20:26:47 roberto Exp $
3** Lua tables (hash)
4** See Copyright Notice in lua.h
5*/
6
7#ifndef ltable_h
8#define ltable_h
9
10#include "lobject.h"
11
12
13#define gnode(t,i)   (&(t)->node[i])
14#define gkey(n)      (&(n)->i_key.tvk)
15#define gval(n)      (&(n)->i_val)
16#define gnext(n)   ((n)->i_key.nk.next)
17
18#define invalidateTMcache(t)   ((t)->flags = 0)
19
20
21LUAI_FUNC const TValue *luaH_getint (Table *t, int key);
22LUAI_FUNC void luaH_setint (lua_State *L, Table *t, int key, TValue *value);
23LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
24LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
25LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key);
26LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
27LUAI_FUNC Table *luaH_new (lua_State *L);
28LUAI_FUNC void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize);
29LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
30LUAI_FUNC void luaH_free (lua_State *L, Table *t);
31LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
32LUAI_FUNC int luaH_getn (Table *t);
33
34
35#if defined(LUA_DEBUG)
36LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
37LUAI_FUNC int luaH_isdummy (Node *n);
38#endif
39
40
41#endif
Property changes on: trunk/src/lib/lua/ltable.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lopcodes.c
r0r22721
1/*
2** $Id: lopcodes.c,v 1.49 2012/05/14 13:34:18 roberto Exp $
3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h
5*/
6
7
8#define lopcodes_c
9#define LUA_CORE
10
11
12#include "lopcodes.h"
13
14
15/* ORDER OP */
16
17LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
18  "MOVE",
19  "LOADK",
20  "LOADKX",
21  "LOADBOOL",
22  "LOADNIL",
23  "GETUPVAL",
24  "GETTABUP",
25  "GETTABLE",
26  "SETTABUP",
27  "SETUPVAL",
28  "SETTABLE",
29  "NEWTABLE",
30  "SELF",
31  "ADD",
32  "SUB",
33  "MUL",
34  "DIV",
35  "MOD",
36  "POW",
37  "UNM",
38  "NOT",
39  "LEN",
40  "CONCAT",
41  "JMP",
42  "EQ",
43  "LT",
44  "LE",
45  "TEST",
46  "TESTSET",
47  "CALL",
48  "TAILCALL",
49  "RETURN",
50  "FORLOOP",
51  "FORPREP",
52  "TFORCALL",
53  "TFORLOOP",
54  "SETLIST",
55  "CLOSURE",
56  "VARARG",
57  "EXTRAARG",
58  NULL
59};
60
61
62#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
63
64LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
65/*       T  A    B       C     mode         opcode   */
66  opmode(0, 1, OpArgR, OpArgN, iABC)      /* OP_MOVE */
67 ,opmode(0, 1, OpArgK, OpArgN, iABx)      /* OP_LOADK */
68 ,opmode(0, 1, OpArgN, OpArgN, iABx)      /* OP_LOADKX */
69 ,opmode(0, 1, OpArgU, OpArgU, iABC)      /* OP_LOADBOOL */
70 ,opmode(0, 1, OpArgU, OpArgN, iABC)      /* OP_LOADNIL */
71 ,opmode(0, 1, OpArgU, OpArgN, iABC)      /* OP_GETUPVAL */
72 ,opmode(0, 1, OpArgU, OpArgK, iABC)      /* OP_GETTABUP */
73 ,opmode(0, 1, OpArgR, OpArgK, iABC)      /* OP_GETTABLE */
74 ,opmode(0, 0, OpArgK, OpArgK, iABC)      /* OP_SETTABUP */
75 ,opmode(0, 0, OpArgU, OpArgN, iABC)      /* OP_SETUPVAL */
76 ,opmode(0, 0, OpArgK, OpArgK, iABC)      /* OP_SETTABLE */
77 ,opmode(0, 1, OpArgU, OpArgU, iABC)      /* OP_NEWTABLE */
78 ,opmode(0, 1, OpArgR, OpArgK, iABC)      /* OP_SELF */
79 ,opmode(0, 1, OpArgK, OpArgK, iABC)      /* OP_ADD */
80 ,opmode(0, 1, OpArgK, OpArgK, iABC)      /* OP_SUB */
81 ,opmode(0, 1, OpArgK, OpArgK, iABC)      /* OP_MUL */
82 ,opmode(0, 1, OpArgK, OpArgK, iABC)      /* OP_DIV */
83 ,opmode(0, 1, OpArgK, OpArgK, iABC)      /* OP_MOD */
84 ,opmode(0, 1, OpArgK, OpArgK, iABC)      /* OP_POW */
85 ,opmode(0, 1, OpArgR, OpArgN, iABC)      /* OP_UNM */
86 ,opmode(0, 1, OpArgR, OpArgN, iABC)      /* OP_NOT */
87 ,opmode(0, 1, OpArgR, OpArgN, iABC)      /* OP_LEN */
88 ,opmode(0, 1, OpArgR, OpArgR, iABC)      /* OP_CONCAT */
89 ,opmode(0, 0, OpArgR, OpArgN, iAsBx)      /* OP_JMP */
90 ,opmode(1, 0, OpArgK, OpArgK, iABC)      /* OP_EQ */
91 ,opmode(1, 0, OpArgK, OpArgK, iABC)      /* OP_LT */
92 ,opmode(1, 0, OpArgK, OpArgK, iABC)      /* OP_LE */
93 ,opmode(1, 0, OpArgN, OpArgU, iABC)      /* OP_TEST */
94 ,opmode(1, 1, OpArgR, OpArgU, iABC)      /* OP_TESTSET */
95 ,opmode(0, 1, OpArgU, OpArgU, iABC)      /* OP_CALL */
96 ,opmode(0, 1, OpArgU, OpArgU, iABC)      /* OP_TAILCALL */
97 ,opmode(0, 0, OpArgU, OpArgN, iABC)      /* OP_RETURN */
98 ,opmode(0, 1, OpArgR, OpArgN, iAsBx)      /* OP_FORLOOP */
99 ,opmode(0, 1, OpArgR, OpArgN, iAsBx)      /* OP_FORPREP */
100 ,opmode(0, 0, OpArgN, OpArgU, iABC)      /* OP_TFORCALL */
101 ,opmode(0, 1, OpArgR, OpArgN, iAsBx)      /* OP_TFORLOOP */
102 ,opmode(0, 0, OpArgU, OpArgU, iABC)      /* OP_SETLIST */
103 ,opmode(0, 1, OpArgU, OpArgN, iABx)      /* OP_CLOSURE */
104 ,opmode(0, 1, OpArgU, OpArgN, iABC)      /* OP_VARARG */
105 ,opmode(0, 0, OpArgU, OpArgU, iAx)      /* OP_EXTRAARG */
106};
107
Property changes on: trunk/src/lib/lua/lopcodes.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/llex.h
r0r22721
1/*
2** $Id: llex.h,v 1.72 2011/11/30 12:43:51 roberto Exp $
3** Lexical Analyzer
4** See Copyright Notice in lua.h
5*/
6
7#ifndef llex_h
8#define llex_h
9
10#include "lobject.h"
11#include "lzio.h"
12
13
14#define FIRST_RESERVED   257
15
16
17
18/*
19* WARNING: if you change the order of this enumeration,
20* grep "ORDER RESERVED"
21*/
22enum RESERVED {
23  /* terminal symbols denoted by reserved words */
24  TK_AND = FIRST_RESERVED, TK_BREAK,
25  TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
26  TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
27  TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
28  /* other terminal symbols */
29  TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_DBCOLON, TK_EOS,
30  TK_NUMBER, TK_NAME, TK_STRING
31};
32
33/* number of reserved words */
34#define NUM_RESERVED   (cast(int, TK_WHILE-FIRST_RESERVED+1))
35
36
37typedef union {
38  lua_Number r;
39  TString *ts;
40} SemInfo;  /* semantics information */
41
42
43typedef struct Token {
44  int token;
45  SemInfo seminfo;
46} Token;
47
48
49/* state of the lexer plus state of the parser when shared by all
50   functions */
51typedef struct LexState {
52  int current;  /* current character (charint) */
53  int linenumber;  /* input line counter */
54  int lastline;  /* line of last token `consumed' */
55  Token t;  /* current token */
56  Token lookahead;  /* look ahead token */
57  struct FuncState *fs;  /* current function (parser) */
58  struct lua_State *L;
59  ZIO *z;  /* input stream */
60  Mbuffer *buff;  /* buffer for tokens */
61  struct Dyndata *dyd;  /* dynamic structures used by the parser */
62  TString *source;  /* current source name */
63  TString *envn;  /* environment variable name */
64  char decpoint;  /* locale decimal point */
65} LexState;
66
67
68LUAI_FUNC void luaX_init (lua_State *L);
69LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
70                              TString *source, int firstchar);
71LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
72LUAI_FUNC void luaX_next (LexState *ls);
73LUAI_FUNC int luaX_lookahead (LexState *ls);
74LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s);
75LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);
76
77
78#endif
Property changes on: trunk/src/lib/lua/llex.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/ltablib.c
r0r22721
1/*
2** $Id: ltablib.c,v 1.65 2013/03/07 18:17:24 roberto Exp $
3** Library for Table Manipulation
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stddef.h>
9
10#define ltablib_c
11#define LUA_LIB
12
13#include "lua.h"
14
15#include "lauxlib.h"
16#include "lualib.h"
17
18
19#define aux_getn(L,n)   (luaL_checktype(L, n, LUA_TTABLE), luaL_len(L, n))
20
21
22
23#if defined(LUA_COMPAT_MAXN)
24static int maxn (lua_State *L) {
25  lua_Number max = 0;
26  luaL_checktype(L, 1, LUA_TTABLE);
27  lua_pushnil(L);  /* first key */
28  while (lua_next(L, 1)) {
29    lua_pop(L, 1);  /* remove value */
30    if (lua_type(L, -1) == LUA_TNUMBER) {
31      lua_Number v = lua_tonumber(L, -1);
32      if (v > max) max = v;
33    }
34  }
35  lua_pushnumber(L, max);
36  return 1;
37}
38#endif
39
40
41static int tinsert (lua_State *L) {
42  int e = aux_getn(L, 1) + 1;  /* first empty element */
43  int pos;  /* where to insert new element */
44  switch (lua_gettop(L)) {
45    case 2: {  /* called with only 2 arguments */
46      pos = e;  /* insert new element at the end */
47      break;
48    }
49    case 3: {
50      int i;
51      pos = luaL_checkint(L, 2);  /* 2nd argument is the position */
52      luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds");
53      for (i = e; i > pos; i--) {  /* move up elements */
54        lua_rawgeti(L, 1, i-1);
55        lua_rawseti(L, 1, i);  /* t[i] = t[i-1] */
56      }
57      break;
58    }
59    default: {
60      return luaL_error(L, "wrong number of arguments to " LUA_QL("insert"));
61    }
62  }
63  lua_rawseti(L, 1, pos);  /* t[pos] = v */
64  return 0;
65}
66
67
68static int tremove (lua_State *L) {
69  int size = aux_getn(L, 1);
70  int pos = luaL_optint(L, 2, size);
71  if (pos != size)  /* validate 'pos' if given */
72    luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds");
73  lua_rawgeti(L, 1, pos);  /* result = t[pos] */
74  for ( ; pos < size; pos++) {
75    lua_rawgeti(L, 1, pos+1);
76    lua_rawseti(L, 1, pos);  /* t[pos] = t[pos+1] */
77  }
78  lua_pushnil(L);
79  lua_rawseti(L, 1, pos);  /* t[pos] = nil */
80  return 1;
81}
82
83
84static void addfield (lua_State *L, luaL_Buffer *b, int i) {
85  lua_rawgeti(L, 1, i);
86  if (!lua_isstring(L, -1))
87    luaL_error(L, "invalid value (%s) at index %d in table for "
88                  LUA_QL("concat"), luaL_typename(L, -1), i);
89  luaL_addvalue(b);
90}
91
92
93static int tconcat (lua_State *L) {
94  luaL_Buffer b;
95  size_t lsep;
96  int i, last;
97  const char *sep = luaL_optlstring(L, 2, "", &lsep);
98  luaL_checktype(L, 1, LUA_TTABLE);
99  i = luaL_optint(L, 3, 1);
100  last = luaL_opt(L, luaL_checkint, 4, luaL_len(L, 1));
101  luaL_buffinit(L, &b);
102  for (; i < last; i++) {
103    addfield(L, &b, i);
104    luaL_addlstring(&b, sep, lsep);
105  }
106  if (i == last)  /* add last value (if interval was not empty) */
107    addfield(L, &b, i);
108  luaL_pushresult(&b);
109  return 1;
110}
111
112
113/*
114** {======================================================
115** Pack/unpack
116** =======================================================
117*/
118
119static int pack (lua_State *L) {
120  int n = lua_gettop(L);  /* number of elements to pack */
121  lua_createtable(L, n, 1);  /* create result table */
122  lua_pushinteger(L, n);
123  lua_setfield(L, -2, "n");  /* t.n = number of elements */
124  if (n > 0) {  /* at least one element? */
125    int i;
126    lua_pushvalue(L, 1);
127    lua_rawseti(L, -2, 1);  /* insert first element */
128    lua_replace(L, 1);  /* move table into index 1 */
129    for (i = n; i >= 2; i--)  /* assign other elements */
130      lua_rawseti(L, 1, i);
131  }
132  return 1;  /* return table */
133}
134
135
136static int unpack (lua_State *L) {
137  int i, e, n;
138  luaL_checktype(L, 1, LUA_TTABLE);
139  i = luaL_optint(L, 2, 1);
140  e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1));
141  if (i > e) return 0;  /* empty range */
142  n = e - i + 1;  /* number of elements */
143  if (n <= 0 || !lua_checkstack(L, n))  /* n <= 0 means arith. overflow */
144    return luaL_error(L, "too many results to unpack");
145  lua_rawgeti(L, 1, i);  /* push arg[i] (avoiding overflow problems) */
146  while (i++ < e)  /* push arg[i + 1...e] */
147    lua_rawgeti(L, 1, i);
148  return n;
149}
150
151/* }====================================================== */
152
153
154
155/*
156** {======================================================
157** Quicksort
158** (based on `Algorithms in MODULA-3', Robert Sedgewick;
159**  Addison-Wesley, 1993.)
160** =======================================================
161*/
162
163
164static void set2 (lua_State *L, int i, int j) {
165  lua_rawseti(L, 1, i);
166  lua_rawseti(L, 1, j);
167}
168
169static int sort_comp (lua_State *L, int a, int b) {
170  if (!lua_isnil(L, 2)) {  /* function? */
171    int res;
172    lua_pushvalue(L, 2);
173    lua_pushvalue(L, a-1);  /* -1 to compensate function */
174    lua_pushvalue(L, b-2);  /* -2 to compensate function and `a' */
175    lua_call(L, 2, 1);
176    res = lua_toboolean(L, -1);
177    lua_pop(L, 1);
178    return res;
179  }
180  else  /* a < b? */
181    return lua_compare(L, a, b, LUA_OPLT);
182}
183
184static void auxsort (lua_State *L, int l, int u) {
185  while (l < u) {  /* for tail recursion */
186    int i, j;
187    /* sort elements a[l], a[(l+u)/2] and a[u] */
188    lua_rawgeti(L, 1, l);
189    lua_rawgeti(L, 1, u);
190    if (sort_comp(L, -1, -2))  /* a[u] < a[l]? */
191      set2(L, l, u);  /* swap a[l] - a[u] */
192    else
193      lua_pop(L, 2);
194    if (u-l == 1) break;  /* only 2 elements */
195    i = (l+u)/2;
196    lua_rawgeti(L, 1, i);
197    lua_rawgeti(L, 1, l);
198    if (sort_comp(L, -2, -1))  /* a[i]<a[l]? */
199      set2(L, i, l);
200    else {
201      lua_pop(L, 1);  /* remove a[l] */
202      lua_rawgeti(L, 1, u);
203      if (sort_comp(L, -1, -2))  /* a[u]<a[i]? */
204        set2(L, i, u);
205      else
206        lua_pop(L, 2);
207    }
208    if (u-l == 2) break;  /* only 3 elements */
209    lua_rawgeti(L, 1, i);  /* Pivot */
210    lua_pushvalue(L, -1);
211    lua_rawgeti(L, 1, u-1);
212    set2(L, i, u-1);
213    /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
214    i = l; j = u-1;
215    for (;;) {  /* invariant: a[l..i] <= P <= a[j..u] */
216      /* repeat ++i until a[i] >= P */
217      while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
218        if (i>=u) luaL_error(L, "invalid order function for sorting");
219        lua_pop(L, 1);  /* remove a[i] */
220      }
221      /* repeat --j until a[j] <= P */
222      while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
223        if (j<=l) luaL_error(L, "invalid order function for sorting");
224        lua_pop(L, 1);  /* remove a[j] */
225      }
226      if (j<i) {
227        lua_pop(L, 3);  /* pop pivot, a[i], a[j] */
228        break;
229      }
230      set2(L, i, j);
231    }
232    lua_rawgeti(L, 1, u-1);
233    lua_rawgeti(L, 1, i);
234    set2(L, u-1, i);  /* swap pivot (a[u-1]) with a[i] */
235    /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
236    /* adjust so that smaller half is in [j..i] and larger one in [l..u] */
237    if (i-l < u-i) {
238      j=l; i=i-1; l=i+2;
239    }
240    else {
241      j=i+1; i=u; u=j-2;
242    }
243    auxsort(L, j, i);  /* call recursively the smaller one */
244  }  /* repeat the routine for the larger one */
245}
246
247static int sort (lua_State *L) {
248  int n = aux_getn(L, 1);
249  luaL_checkstack(L, 40, "");  /* assume array is smaller than 2^40 */
250  if (!lua_isnoneornil(L, 2))  /* is there a 2nd argument? */
251    luaL_checktype(L, 2, LUA_TFUNCTION);
252  lua_settop(L, 2);  /* make sure there is two arguments */
253  auxsort(L, 1, n);
254  return 0;
255}
256
257/* }====================================================== */
258
259
260static const luaL_Reg tab_funcs[] = {
261  {"concat", tconcat},
262#if defined(LUA_COMPAT_MAXN)
263  {"maxn", maxn},
264#endif
265  {"insert", tinsert},
266  {"pack", pack},
267  {"unpack", unpack},
268  {"remove", tremove},
269  {"sort", sort},
270  {NULL, NULL}
271};
272
273
274LUAMOD_API int luaopen_table (lua_State *L) {
275  luaL_newlib(L, tab_funcs);
276#if defined(LUA_COMPAT_UNPACK)
277  /* _G.unpack = table.unpack */
278  lua_getfield(L, -1, "unpack");
279  lua_setglobal(L, "unpack");
280#endif
281  return 1;
282}
283
Property changes on: trunk/src/lib/lua/ltablib.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lstrlib.c
r0r22721
1/*
2** $Id: lstrlib.c,v 1.178 2012/08/14 18:12:34 roberto Exp $
3** Standard library for string operations and pattern-matching
4** See Copyright Notice in lua.h
5*/
6
7
8#include <ctype.h>
9#include <stddef.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14#define lstrlib_c
15#define LUA_LIB
16
17#include "lua.h"
18
19#include "lauxlib.h"
20#include "lualib.h"
21
22
23/*
24** maximum number of captures that a pattern can do during
25** pattern-matching. This limit is arbitrary.
26*/
27#if !defined(LUA_MAXCAPTURES)
28#define LUA_MAXCAPTURES      32
29#endif
30
31
32/* macro to `unsign' a character */
33#define uchar(c)   ((unsigned char)(c))
34
35
36
37static int str_len (lua_State *L) {
38  size_t l;
39  luaL_checklstring(L, 1, &l);
40  lua_pushinteger(L, (lua_Integer)l);
41  return 1;
42}
43
44
45/* translate a relative string position: negative means back from end */
46static size_t posrelat (ptrdiff_t pos, size_t len) {
47  if (pos >= 0) return (size_t)pos;
48  else if (0u - (size_t)pos > len) return 0;
49  else return len - ((size_t)-pos) + 1;
50}
51
52
53static int str_sub (lua_State *L) {
54  size_t l;
55  const char *s = luaL_checklstring(L, 1, &l);
56  size_t start = posrelat(luaL_checkinteger(L, 2), l);
57  size_t end = posrelat(luaL_optinteger(L, 3, -1), l);
58  if (start < 1) start = 1;
59  if (end > l) end = l;
60  if (start <= end)
61    lua_pushlstring(L, s + start - 1, end - start + 1);
62  else lua_pushliteral(L, "");
63  return 1;
64}
65
66
67static int str_reverse (lua_State *L) {
68  size_t l, i;
69  luaL_Buffer b;
70  const char *s = luaL_checklstring(L, 1, &l);
71  char *p = luaL_buffinitsize(L, &b, l);
72  for (i = 0; i < l; i++)
73    p[i] = s[l - i - 1];
74  luaL_pushresultsize(&b, l);
75  return 1;
76}
77
78
79static int str_lower (lua_State *L) {
80  size_t l;
81  size_t i;
82  luaL_Buffer b;
83  const char *s = luaL_checklstring(L, 1, &l);
84  char *p = luaL_buffinitsize(L, &b, l);
85  for (i=0; i<l; i++)
86    p[i] = tolower(uchar(s[i]));
87  luaL_pushresultsize(&b, l);
88  return 1;
89}
90
91
92static int str_upper (lua_State *L) {
93  size_t l;
94  size_t i;
95  luaL_Buffer b;
96  const char *s = luaL_checklstring(L, 1, &l);
97  char *p = luaL_buffinitsize(L, &b, l);
98  for (i=0; i<l; i++)
99    p[i] = toupper(uchar(s[i]));
100  luaL_pushresultsize(&b, l);
101  return 1;
102}
103
104
105/* reasonable limit to avoid arithmetic overflow */
106#define MAXSIZE      ((~(size_t)0) >> 1)
107
108static int str_rep (lua_State *L) {
109  size_t l, lsep;
110  const char *s = luaL_checklstring(L, 1, &l);
111  int n = luaL_checkint(L, 2);
112  const char *sep = luaL_optlstring(L, 3, "", &lsep);
113  if (n <= 0) lua_pushliteral(L, "");
114  else if (l + lsep < l || l + lsep >= MAXSIZE / n)  /* may overflow? */
115    return luaL_error(L, "resulting string too large");
116  else {
117    size_t totallen = n * l + (n - 1) * lsep;
118    luaL_Buffer b;
119    char *p = luaL_buffinitsize(L, &b, totallen);
120    while (n-- > 1) {  /* first n-1 copies (followed by separator) */
121      memcpy(p, s, l * sizeof(char)); p += l;
122      if (lsep > 0) {  /* avoid empty 'memcpy' (may be expensive) */
123        memcpy(p, sep, lsep * sizeof(char)); p += lsep;
124      }
125    }
126    memcpy(p, s, l * sizeof(char));  /* last copy (not followed by separator) */
127    luaL_pushresultsize(&b, totallen);
128  }
129  return 1;
130}
131
132
133static int str_byte (lua_State *L) {
134  size_t l;
135  const char *s = luaL_checklstring(L, 1, &l);
136  size_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
137  size_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
138  int n, i;
139  if (posi < 1) posi = 1;
140  if (pose > l) pose = l;
141  if (posi > pose) return 0;  /* empty interval; return no values */
142  n = (int)(pose -  posi + 1);
143  if (posi + n <= pose)  /* (size_t -> int) overflow? */
144    return luaL_error(L, "string slice too long");
145  luaL_checkstack(L, n, "string slice too long");
146  for (i=0; i<n; i++)
147    lua_pushinteger(L, uchar(s[posi+i-1]));
148  return n;
149}
150
151
152static int str_char (lua_State *L) {
153  int n = lua_gettop(L);  /* number of arguments */
154  int i;
155  luaL_Buffer b;
156  char *p = luaL_buffinitsize(L, &b, n);
157  for (i=1; i<=n; i++) {
158    int c = luaL_checkint(L, i);
159    luaL_argcheck(L, uchar(c) == c, i, "value out of range");
160    p[i - 1] = uchar(c);
161  }
162  luaL_pushresultsize(&b, n);
163  return 1;
164}
165
166
167static int writer (lua_State *L, const void* b, size_t size, void* B) {
168  (void)L;
169  luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);
170  return 0;
171}
172
173
174static int str_dump (lua_State *L) {
175  luaL_Buffer b;
176  luaL_checktype(L, 1, LUA_TFUNCTION);
177  lua_settop(L, 1);
178  luaL_buffinit(L,&b);
179  if (lua_dump(L, writer, &b) != 0)
180    return luaL_error(L, "unable to dump given function");
181  luaL_pushresult(&b);
182  return 1;
183}
184
185
186
187/*
188** {======================================================
189** PATTERN MATCHING
190** =======================================================
191*/
192
193
194#define CAP_UNFINISHED   (-1)
195#define CAP_POSITION   (-2)
196
197
198typedef struct MatchState {
199  int matchdepth;  /* control for recursive depth (to avoid C stack overflow) */
200  const char *src_init;  /* init of source string */
201  const char *src_end;  /* end ('\0') of source string */
202  const char *p_end;  /* end ('\0') of pattern */
203  lua_State *L;
204  int level;  /* total number of captures (finished or unfinished) */
205  struct {
206    const char *init;
207    ptrdiff_t len;
208  } capture[LUA_MAXCAPTURES];
209} MatchState;
210
211
212/* recursive function */
213static const char *match (MatchState *ms, const char *s, const char *p);
214
215
216/* maximum recursion depth for 'match' */
217#if !defined(MAXCCALLS)
218#define MAXCCALLS   200
219#endif
220
221
222#define L_ESC      '%'
223#define SPECIALS   "^$*+?.([%-"
224
225
226static int check_capture (MatchState *ms, int l) {
227  l -= '1';
228  if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
229    return luaL_error(ms->L, "invalid capture index %%%d", l + 1);
230  return l;
231}
232
233
234static int capture_to_close (MatchState *ms) {
235  int level = ms->level;
236  for (level--; level>=0; level--)
237    if (ms->capture[level].len == CAP_UNFINISHED) return level;
238  return luaL_error(ms->L, "invalid pattern capture");
239}
240
241
242static const char *classend (MatchState *ms, const char *p) {
243  switch (*p++) {
244    case L_ESC: {
245      if (p == ms->p_end)
246        luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")");
247      return p+1;
248    }
249    case '[': {
250      if (*p == '^') p++;
251      do {  /* look for a `]' */
252        if (p == ms->p_end)
253          luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")");
254        if (*(p++) == L_ESC && p < ms->p_end)
255          p++;  /* skip escapes (e.g. `%]') */
256      } while (*p != ']');
257      return p+1;
258    }
259    default: {
260      return p;
261    }
262  }
263}
264
265
266static int match_class (int c, int cl) {
267  int res;
268  switch (tolower(cl)) {
269    case 'a' : res = isalpha(c); break;
270    case 'c' : res = iscntrl(c); break;
271    case 'd' : res = isdigit(c); break;
272    case 'g' : res = isgraph(c); break;
273    case 'l' : res = islower(c); break;
274    case 'p' : res = ispunct(c); break;
275    case 's' : res = isspace(c); break;
276    case 'u' : res = isupper(c); break;
277    case 'w' : res = isalnum(c); break;
278    case 'x' : res = isxdigit(c); break;
279    case 'z' : res = (c == 0); break;  /* deprecated option */
280    default: return (cl == c);
281  }
282  return (islower(cl) ? res : !res);
283}
284
285
286static int matchbracketclass (int c, const char *p, const char *ec) {
287  int sig = 1;
288  if (*(p+1) == '^') {
289    sig = 0;
290    p++;  /* skip the `^' */
291  }
292  while (++p < ec) {
293    if (*p == L_ESC) {
294      p++;
295      if (match_class(c, uchar(*p)))
296        return sig;
297    }
298    else if ((*(p+1) == '-') && (p+2 < ec)) {
299      p+=2;
300      if (uchar(*(p-2)) <= c && c <= uchar(*p))
301        return sig;
302    }
303    else if (uchar(*p) == c) return sig;
304  }
305  return !sig;
306}
307
308
309static int singlematch (MatchState *ms, const char *s, const char *p,
310                        const char *ep) {
311  if (s >= ms->src_end)
312    return 0;
313  else {
314    int c = uchar(*s);
315    switch (*p) {
316      case '.': return 1;  /* matches any char */
317      case L_ESC: return match_class(c, uchar(*(p+1)));
318      case '[': return matchbracketclass(c, p, ep-1);
319      default:  return (uchar(*p) == c);
320    }
321  }
322}
323
324
325static const char *matchbalance (MatchState *ms, const char *s,
326                                   const char *p) {
327  if (p >= ms->p_end - 1)
328    luaL_error(ms->L, "malformed pattern "
329                      "(missing arguments to " LUA_QL("%%b") ")");
330  if (*s != *p) return NULL;
331  else {
332    int b = *p;
333    int e = *(p+1);
334    int cont = 1;
335    while (++s < ms->src_end) {
336      if (*s == e) {
337        if (--cont == 0) return s+1;
338      }
339      else if (*s == b) cont++;
340    }
341  }
342  return NULL;  /* string ends out of balance */
343}
344
345
346static const char *max_expand (MatchState *ms, const char *s,
347                                 const char *p, const char *ep) {
348  ptrdiff_t i = 0;  /* counts maximum expand for item */
349  while (singlematch(ms, s + i, p, ep))
350    i++;
351  /* keeps trying to match with the maximum repetitions */
352  while (i>=0) {
353    const char *res = match(ms, (s+i), ep+1);
354    if (res) return res;
355    i--;  /* else didn't match; reduce 1 repetition to try again */
356  }
357  return NULL;
358}
359
360
361static const char *min_expand (MatchState *ms, const char *s,
362                                 const char *p, const char *ep) {
363  for (;;) {
364    const char *res = match(ms, s, ep+1);
365    if (res != NULL)
366      return res;
367    else if (singlematch(ms, s, p, ep))
368      s++;  /* try with one more repetition */
369    else return NULL;
370  }
371}
372
373
374static const char *start_capture (MatchState *ms, const char *s,
375                                    const char *p, int what) {
376  const char *res;
377  int level = ms->level;
378  if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures");
379  ms->capture[level].init = s;
380  ms->capture[level].len = what;
381  ms->level = level+1;
382  if ((res=match(ms, s, p)) == NULL)  /* match failed? */
383    ms->level--;  /* undo capture */
384  return res;
385}
386
387
388static const char *end_capture (MatchState *ms, const char *s,
389                                  const char *p) {
390  int l = capture_to_close(ms);
391  const char *res;
392  ms->capture[l].len = s - ms->capture[l].init;  /* close capture */
393  if ((res = match(ms, s, p)) == NULL)  /* match failed? */
394    ms->capture[l].len = CAP_UNFINISHED;  /* undo capture */
395  return res;
396}
397
398
399static const char *match_capture (MatchState *ms, const char *s, int l) {
400  size_t len;
401  l = check_capture(ms, l);
402  len = ms->capture[l].len;
403  if ((size_t)(ms->src_end-s) >= len &&
404      memcmp(ms->capture[l].init, s, len) == 0)
405    return s+len;
406  else return NULL;
407}
408
409
410static const char *match (MatchState *ms, const char *s, const char *p) {
411  if (ms->matchdepth-- == 0)
412    luaL_error(ms->L, "pattern too complex");
413  init: /* using goto's to optimize tail recursion */
414  if (p != ms->p_end) {  /* end of pattern? */
415    switch (*p) {
416      case '(': {  /* start capture */
417        if (*(p + 1) == ')')  /* position capture? */
418          s = start_capture(ms, s, p + 2, CAP_POSITION);
419        else
420          s = start_capture(ms, s, p + 1, CAP_UNFINISHED);
421        break;
422      }
423      case ')': {  /* end capture */
424        s = end_capture(ms, s, p + 1);
425        break;
426      }
427      case '$': {
428        if ((p + 1) != ms->p_end)  /* is the `$' the last char in pattern? */
429          goto dflt;  /* no; go to default */
430        s = (s == ms->src_end) ? s : NULL;  /* check end of string */
431        break;
432      }
433      case L_ESC: {  /* escaped sequences not in the format class[*+?-]? */
434        switch (*(p + 1)) {
435          case 'b': {  /* balanced string? */
436            s = matchbalance(ms, s, p + 2);
437            if (s != NULL) {
438              p += 4; goto init;  /* return match(ms, s, p + 4); */
439            }  /* else fail (s == NULL) */
440            break;
441          }
442          case 'f': {  /* frontier? */
443            const char *ep; char previous;
444            p += 2;
445            if (*p != '[')
446              luaL_error(ms->L, "missing " LUA_QL("[") " after "
447                                 LUA_QL("%%f") " in pattern");
448            ep = classend(ms, p);  /* points to what is next */
449            previous = (s == ms->src_init) ? '\0' : *(s - 1);
450            if (!matchbracketclass(uchar(previous), p, ep - 1) &&
451               matchbracketclass(uchar(*s), p, ep - 1)) {
452              p = ep; goto init;  /* return match(ms, s, ep); */
453            }
454            s = NULL;  /* match failed */
455            break;
456          }
457          case '0': case '1': case '2': case '3':
458          case '4': case '5': case '6': case '7':
459          case '8': case '9': {  /* capture results (%0-%9)? */
460            s = match_capture(ms, s, uchar(*(p + 1)));
461            if (s != NULL) {
462              p += 2; goto init;  /* return match(ms, s, p + 2) */
463            }
464            break;
465          }
466          default: goto dflt;
467        }
468        break;
469      }
470      default: dflt: {  /* pattern class plus optional suffix */
471        const char *ep = classend(ms, p);  /* points to optional suffix */
472        /* does not match at least once? */
473        if (!singlematch(ms, s, p, ep)) {
474          if (*ep == '*' || *ep == '?' || *ep == '-') {  /* accept empty? */
475            p = ep + 1; goto init;  /* return match(ms, s, ep + 1); */
476          }
477          else  /* '+' or no suffix */
478            s = NULL;  /* fail */
479        }
480        else {  /* matched once */
481          switch (*ep) {  /* handle optional suffix */
482            case '?': {  /* optional */
483              const char *res;
484              if ((res = match(ms, s + 1, ep + 1)) != NULL)
485                s = res;
486              else {
487                p = ep + 1; goto init;  /* else return match(ms, s, ep + 1); */
488              }
489              break;
490            }
491            case '+':  /* 1 or more repetitions */
492              s++;  /* 1 match already done */
493              /* go through */
494            case '*':  /* 0 or more repetitions */
495              s = max_expand(ms, s, p, ep);
496              break;
497            case '-':  /* 0 or more repetitions (minimum) */
498              s = min_expand(ms, s, p, ep);
499              break;
500            default:  /* no suffix */
501              s++; p = ep; goto init;  /* return match(ms, s + 1, ep); */
502          }
503        }
504        break;
505      }
506    }
507  }
508  ms->matchdepth++;
509  return s;
510}
511
512
513
514static const char *lmemfind (const char *s1, size_t l1,
515                               const char *s2, size_t l2) {
516  if (l2 == 0) return s1;  /* empty strings are everywhere */
517  else if (l2 > l1) return NULL;  /* avoids a negative `l1' */
518  else {
519    const char *init;  /* to search for a `*s2' inside `s1' */
520    l2--;  /* 1st char will be checked by `memchr' */
521    l1 = l1-l2;  /* `s2' cannot be found after that */
522    while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
523      init++;   /* 1st char is already checked */
524      if (memcmp(init, s2+1, l2) == 0)
525        return init-1;
526      else {  /* correct `l1' and `s1' to try again */
527        l1 -= init-s1;
528        s1 = init;
529      }
530    }
531    return NULL;  /* not found */
532  }
533}
534
535
536static void push_onecapture (MatchState *ms, int i, const char *s,
537                                                    const char *e) {
538  if (i >= ms->level) {
539    if (i == 0)  /* ms->level == 0, too */
540      lua_pushlstring(ms->L, s, e - s);  /* add whole match */
541    else
542      luaL_error(ms->L, "invalid capture index");
543  }
544  else {
545    ptrdiff_t l = ms->capture[i].len;
546    if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
547    if (l == CAP_POSITION)
548      lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
549    else
550      lua_pushlstring(ms->L, ms->capture[i].init, l);
551  }
552}
553
554
555static int push_captures (MatchState *ms, const char *s, const char *e) {
556  int i;
557  int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
558  luaL_checkstack(ms->L, nlevels, "too many captures");
559  for (i = 0; i < nlevels; i++)
560    push_onecapture(ms, i, s, e);
561  return nlevels;  /* number of strings pushed */
562}
563
564
565/* check whether pattern has no special characters */
566static int nospecials (const char *p, size_t l) {
567  size_t upto = 0;
568  do {
569    if (strpbrk(p + upto, SPECIALS))
570      return 0;  /* pattern has a special character */
571    upto += strlen(p + upto) + 1;  /* may have more after \0 */
572  } while (upto <= l);
573  return 1;  /* no special chars found */
574}
575
576
577static int str_find_aux (lua_State *L, int find) {
578  size_t ls, lp;
579  const char *s = luaL_checklstring(L, 1, &ls);
580  const char *p = luaL_checklstring(L, 2, &lp);
581  size_t init = posrelat(luaL_optinteger(L, 3, 1), ls);
582  if (init < 1) init = 1;
583  else if (init > ls + 1) {  /* start after string's end? */
584    lua_pushnil(L);  /* cannot find anything */
585    return 1;
586  }
587  /* explicit request or no special characters? */
588  if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) {
589    /* do a plain search */
590    const char *s2 = lmemfind(s + init - 1, ls - init + 1, p, lp);
591    if (s2) {
592      lua_pushinteger(L, s2 - s + 1);
593      lua_pushinteger(L, s2 - s + lp);
594      return 2;
595    }
596  }
597  else {
598    MatchState ms;
599    const char *s1 = s + init - 1;
600    int anchor = (*p == '^');
601    if (anchor) {
602      p++; lp--;  /* skip anchor character */
603    }
604    ms.L = L;
605    ms.matchdepth = MAXCCALLS;
606    ms.src_init = s;
607    ms.src_end = s + ls;
608    ms.p_end = p + lp;
609    do {
610      const char *res;
611      ms.level = 0;
612      lua_assert(ms.matchdepth == MAXCCALLS);
613      if ((res=match(&ms, s1, p)) != NULL) {
614        if (find) {
615          lua_pushinteger(L, s1 - s + 1);  /* start */
616          lua_pushinteger(L, res - s);   /* end */
617          return push_captures(&ms, NULL, 0) + 2;
618        }
619        else
620          return push_captures(&ms, s1, res);
621      }
622    } while (s1++ < ms.src_end && !anchor);
623  }
624  lua_pushnil(L);  /* not found */
625  return 1;
626}
627
628
629static int str_find (lua_State *L) {
630  return str_find_aux(L, 1);
631}
632
633
634static int str_match (lua_State *L) {
635  return str_find_aux(L, 0);
636}
637
638
639static int gmatch_aux (lua_State *L) {
640  MatchState ms;
641  size_t ls, lp;
642  const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
643  const char *p = lua_tolstring(L, lua_upvalueindex(2), &lp);
644  const char *src;
645  ms.L = L;
646  ms.matchdepth = MAXCCALLS;
647  ms.src_init = s;
648  ms.src_end = s+ls;
649  ms.p_end = p + lp;
650  for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3));
651       src <= ms.src_end;
652       src++) {
653    const char *e;
654    ms.level = 0;
655    lua_assert(ms.matchdepth == MAXCCALLS);
656    if ((e = match(&ms, src, p)) != NULL) {
657      lua_Integer newstart = e-s;
658      if (e == src) newstart++;  /* empty match? go at least one position */
659      lua_pushinteger(L, newstart);
660      lua_replace(L, lua_upvalueindex(3));
661      return push_captures(&ms, src, e);
662    }
663  }
664  return 0;  /* not found */
665}
666
667
668static int gmatch (lua_State *L) {
669  luaL_checkstring(L, 1);
670  luaL_checkstring(L, 2);
671  lua_settop(L, 2);
672  lua_pushinteger(L, 0);
673  lua_pushcclosure(L, gmatch_aux, 3);
674  return 1;
675}
676
677
678static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
679                                                   const char *e) {
680  size_t l, i;
681  const char *news = lua_tolstring(ms->L, 3, &l);
682  for (i = 0; i < l; i++) {
683    if (news[i] != L_ESC)
684      luaL_addchar(b, news[i]);
685    else {
686      i++;  /* skip ESC */
687      if (!isdigit(uchar(news[i]))) {
688        if (news[i] != L_ESC)
689          luaL_error(ms->L, "invalid use of " LUA_QL("%c")
690                           " in replacement string", L_ESC);
691        luaL_addchar(b, news[i]);
692      }
693      else if (news[i] == '0')
694          luaL_addlstring(b, s, e - s);
695      else {
696        push_onecapture(ms, news[i] - '1', s, e);
697        luaL_addvalue(b);  /* add capture to accumulated result */
698      }
699    }
700  }
701}
702
703
704static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
705                                       const char *e, int tr) {
706  lua_State *L = ms->L;
707  switch (tr) {
708    case LUA_TFUNCTION: {
709      int n;
710      lua_pushvalue(L, 3);
711      n = push_captures(ms, s, e);
712      lua_call(L, n, 1);
713      break;
714    }
715    case LUA_TTABLE: {
716      push_onecapture(ms, 0, s, e);
717      lua_gettable(L, 3);
718      break;
719    }
720    default: {  /* LUA_TNUMBER or LUA_TSTRING */
721      add_s(ms, b, s, e);
722      return;
723    }
724  }
725  if (!lua_toboolean(L, -1)) {  /* nil or false? */
726    lua_pop(L, 1);
727    lua_pushlstring(L, s, e - s);  /* keep original text */
728  }
729  else if (!lua_isstring(L, -1))
730    luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
731  luaL_addvalue(b);  /* add result to accumulator */
732}
733
734
735static int str_gsub (lua_State *L) {
736  size_t srcl, lp;
737  const char *src = luaL_checklstring(L, 1, &srcl);
738  const char *p = luaL_checklstring(L, 2, &lp);
739  int tr = lua_type(L, 3);
740  size_t max_s = luaL_optinteger(L, 4, srcl+1);
741  int anchor = (*p == '^');
742  size_t n = 0;
743  MatchState ms;
744  luaL_Buffer b;
745  luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
746                   tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
747                      "string/function/table expected");
748  luaL_buffinit(L, &b);
749  if (anchor) {
750    p++; lp--;  /* skip anchor character */
751  }
752  ms.L = L;
753  ms.matchdepth = MAXCCALLS;
754  ms.src_init = src;
755  ms.src_end = src+srcl;
756  ms.p_end = p + lp;
757  while (n < max_s) {
758    const char *e;
759    ms.level = 0;
760    lua_assert(ms.matchdepth == MAXCCALLS);
761    e = match(&ms, src, p);
762    if (e) {
763      n++;
764      add_value(&ms, &b, src, e, tr);
765    }
766    if (e && e>src) /* non empty match? */
767      src = e;  /* skip it */
768    else if (src < ms.src_end)
769      luaL_addchar(&b, *src++);
770    else break;
771    if (anchor) break;
772  }
773  luaL_addlstring(&b, src, ms.src_end-src);
774  luaL_pushresult(&b);
775  lua_pushinteger(L, n);  /* number of substitutions */
776  return 2;
777}
778
779/* }====================================================== */
780
781
782
783/*
784** {======================================================
785** STRING FORMAT
786** =======================================================
787*/
788
789/*
790** LUA_INTFRMLEN is the length modifier for integer conversions in
791** 'string.format'; LUA_INTFRM_T is the integer type corresponding to
792** the previous length
793*/
794#if !defined(LUA_INTFRMLEN)   /* { */
795#if defined(LUA_USE_LONGLONG)
796
797#define LUA_INTFRMLEN      "ll"
798#define LUA_INTFRM_T      long long
799
800#else
801
802#define LUA_INTFRMLEN      "l"
803#define LUA_INTFRM_T      long
804
805#endif
806#endif            /* } */
807
808
809/*
810** LUA_FLTFRMLEN is the length modifier for float conversions in
811** 'string.format'; LUA_FLTFRM_T is the float type corresponding to
812** the previous length
813*/
814#if !defined(LUA_FLTFRMLEN)
815
816#define LUA_FLTFRMLEN      ""
817#define LUA_FLTFRM_T      double
818
819#endif
820
821
822/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
823#define MAX_ITEM   512
824/* valid flags in a format specification */
825#define FLAGS   "-+ #0"
826/*
827** maximum size of each format specification (such as '%-099.99d')
828** (+10 accounts for %99.99x plus margin of error)
829*/
830#define MAX_FORMAT   (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10)
831
832
833static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
834  size_t l;
835  const char *s = luaL_checklstring(L, arg, &l);
836  luaL_addchar(b, '"');
837  while (l--) {
838    if (*s == '"' || *s == '\\' || *s == '\n') {
839      luaL_addchar(b, '\\');
840      luaL_addchar(b, *s);
841    }
842    else if (*s == '\0' || iscntrl(uchar(*s))) {
843      char buff[10];
844      if (!isdigit(uchar(*(s+1))))
845        sprintf(buff, "\\%d", (int)uchar(*s));
846      else
847        sprintf(buff, "\\%03d", (int)uchar(*s));
848      luaL_addstring(b, buff);
849    }
850    else
851      luaL_addchar(b, *s);
852    s++;
853  }
854  luaL_addchar(b, '"');
855}
856
857static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
858  const char *p = strfrmt;
859  while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++;  /* skip flags */
860  if ((size_t)(p - strfrmt) >= sizeof(FLAGS)/sizeof(char))
861    luaL_error(L, "invalid format (repeated flags)");
862  if (isdigit(uchar(*p))) p++;  /* skip width */
863  if (isdigit(uchar(*p))) p++;  /* (2 digits at most) */
864  if (*p == '.') {
865    p++;
866    if (isdigit(uchar(*p))) p++;  /* skip precision */
867    if (isdigit(uchar(*p))) p++;  /* (2 digits at most) */
868  }
869  if (isdigit(uchar(*p)))
870    luaL_error(L, "invalid format (width or precision too long)");
871  *(form++) = '%';
872  memcpy(form, strfrmt, (p - strfrmt + 1) * sizeof(char));
873  form += p - strfrmt + 1;
874  *form = '\0';
875  return p;
876}
877
878
879/*
880** add length modifier into formats
881*/
882static void addlenmod (char *form, const char *lenmod) {
883  size_t l = strlen(form);
884  size_t lm = strlen(lenmod);
885  char spec = form[l - 1];
886  strcpy(form + l - 1, lenmod);
887  form[l + lm - 1] = spec;
888  form[l + lm] = '\0';
889}
890
891
892static int str_format (lua_State *L) {
893  int top = lua_gettop(L);
894  int arg = 1;
895  size_t sfl;
896  const char *strfrmt = luaL_checklstring(L, arg, &sfl);
897  const char *strfrmt_end = strfrmt+sfl;
898  luaL_Buffer b;
899  luaL_buffinit(L, &b);
900  while (strfrmt < strfrmt_end) {
901    if (*strfrmt != L_ESC)
902      luaL_addchar(&b, *strfrmt++);
903    else if (*++strfrmt == L_ESC)
904      luaL_addchar(&b, *strfrmt++);  /* %% */
905    else { /* format item */
906      char form[MAX_FORMAT];  /* to store the format (`%...') */
907      char *buff = luaL_prepbuffsize(&b, MAX_ITEM);  /* to put formatted item */
908      int nb = 0;  /* number of bytes in added item */
909      if (++arg > top)
910        luaL_argerror(L, arg, "no value");
911      strfrmt = scanformat(L, strfrmt, form);
912      switch (*strfrmt++) {
913        case 'c': {
914          nb = sprintf(buff, form, luaL_checkint(L, arg));
915          break;
916        }
917        case 'd': case 'i': {
918          lua_Number n = luaL_checknumber(L, arg);
919          LUA_INTFRM_T ni = (LUA_INTFRM_T)n;
920          lua_Number diff = n - (lua_Number)ni;
921          luaL_argcheck(L, -1 < diff && diff < 1, arg,
922                        "not a number in proper range");
923          addlenmod(form, LUA_INTFRMLEN);
924          nb = sprintf(buff, form, ni);
925          break;
926        }
927        case 'o': case 'u': case 'x': case 'X': {
928          lua_Number n = luaL_checknumber(L, arg);
929          unsigned LUA_INTFRM_T ni = (unsigned LUA_INTFRM_T)n;
930          lua_Number diff = n - (lua_Number)ni;
931          luaL_argcheck(L, -1 < diff && diff < 1, arg,
932                        "not a non-negative number in proper range");
933          addlenmod(form, LUA_INTFRMLEN);
934          nb = sprintf(buff, form, ni);
935          break;
936        }
937        case 'e': case 'E': case 'f':
938#if defined(LUA_USE_AFORMAT)
939        case 'a': case 'A':
940#endif
941        case 'g': case 'G': {
942          addlenmod(form, LUA_FLTFRMLEN);
943          nb = sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg));
944          break;
945        }
946        case 'q': {
947          addquoted(L, &b, arg);
948          break;
949        }
950        case 's': {
951          size_t l;
952          const char *s = luaL_tolstring(L, arg, &l);
953          if (!strchr(form, '.') && l >= 100) {
954            /* no precision and string is too long to be formatted;
955               keep original string */
956            luaL_addvalue(&b);
957            break;
958          }
959          else {
960            nb = sprintf(buff, form, s);
961            lua_pop(L, 1);  /* remove result from 'luaL_tolstring' */
962            break;
963          }
964        }
965        default: {  /* also treat cases `pnLlh' */
966          return luaL_error(L, "invalid option " LUA_QL("%%%c") " to "
967                               LUA_QL("format"), *(strfrmt - 1));
968        }
969      }
970      luaL_addsize(&b, nb);
971    }
972  }
973  luaL_pushresult(&b);
974  return 1;
975}
976
977/* }====================================================== */
978
979
980static const luaL_Reg strlib[] = {
981  {"byte", str_byte},
982  {"char", str_char},
983  {"dump", str_dump},
984  {"find", str_find},
985  {"format", str_format},
986  {"gmatch", gmatch},
987  {"gsub", str_gsub},
988  {"len", str_len},
989  {"lower", str_lower},
990  {"match", str_match},
991  {"rep", str_rep},
992  {"reverse", str_reverse},
993  {"sub", str_sub},
994  {"upper", str_upper},
995  {NULL, NULL}
996};
997
998
999static void createmetatable (lua_State *L) {
1000  lua_createtable(L, 0, 1);  /* table to be metatable for strings */
1001  lua_pushliteral(L, "");  /* dummy string */
1002  lua_pushvalue(L, -2);  /* copy table */
1003  lua_setmetatable(L, -2);  /* set table as metatable for strings */
1004  lua_pop(L, 1);  /* pop dummy string */
1005  lua_pushvalue(L, -2);  /* get string library */
1006  lua_setfield(L, -2, "__index");  /* metatable.__index = string */
1007  lua_pop(L, 1);  /* pop metatable */
1008}
1009
1010
1011/*
1012** Open string library
1013*/
1014LUAMOD_API int luaopen_string (lua_State *L) {
1015  luaL_newlib(L, strlib);
1016  createmetatable(L);
1017  return 1;
1018}
1019
Property changes on: trunk/src/lib/lua/lstrlib.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lbaselib.c
r0r22721
1/*
2** $Id: lbaselib.c,v 1.276 2013/02/21 13:44:53 roberto Exp $
3** Basic library
4** See Copyright Notice in lua.h
5*/
6
7
8
9#include <ctype.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14#define lbaselib_c
15#define LUA_LIB
16
17#include "lua.h"
18
19#include "lauxlib.h"
20#include "lualib.h"
21
22
23static int luaB_print (lua_State *L) {
24  int n = lua_gettop(L);  /* number of arguments */
25  int i;
26  lua_getglobal(L, "tostring");
27  for (i=1; i<=n; i++) {
28    const char *s;
29    size_t l;
30    lua_pushvalue(L, -1);  /* function to be called */
31    lua_pushvalue(L, i);   /* value to print */
32    lua_call(L, 1, 1);
33    s = lua_tolstring(L, -1, &l);  /* get result */
34    if (s == NULL)
35      return luaL_error(L,
36         LUA_QL("tostring") " must return a string to " LUA_QL("print"));
37    if (i>1) luai_writestring("\t", 1);
38    luai_writestring(s, l);
39    lua_pop(L, 1);  /* pop result */
40  }
41  luai_writeline();
42  return 0;
43}
44
45
46#define SPACECHARS   " \f\n\r\t\v"
47
48static int luaB_tonumber (lua_State *L) {
49  if (lua_isnoneornil(L, 2)) {  /* standard conversion */
50    int isnum;
51    lua_Number n = lua_tonumberx(L, 1, &isnum);
52    if (isnum) {
53      lua_pushnumber(L, n);
54      return 1;
55    }  /* else not a number; must be something */
56    luaL_checkany(L, 1);
57  }
58  else {
59    size_t l;
60    const char *s = luaL_checklstring(L, 1, &l);
61    const char *e = s + l;  /* end point for 's' */
62    int base = luaL_checkint(L, 2);
63    int neg = 0;
64    luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
65    s += strspn(s, SPACECHARS);  /* skip initial spaces */
66    if (*s == '-') { s++; neg = 1; }  /* handle signal */
67    else if (*s == '+') s++;
68    if (isalnum((unsigned char)*s)) {
69      lua_Number n = 0;
70      do {
71        int digit = (isdigit((unsigned char)*s)) ? *s - '0'
72                       : toupper((unsigned char)*s) - 'A' + 10;
73        if (digit >= base) break;  /* invalid numeral; force a fail */
74        n = n * (lua_Number)base + (lua_Number)digit;
75        s++;
76      } while (isalnum((unsigned char)*s));
77      s += strspn(s, SPACECHARS);  /* skip trailing spaces */
78      if (s == e) {  /* no invalid trailing characters? */
79        lua_pushnumber(L, (neg) ? -n : n);
80        return 1;
81      }  /* else not a number */
82    }  /* else not a number */
83  }
84  lua_pushnil(L);  /* not a number */
85  return 1;
86}
87
88
89static int luaB_error (lua_State *L) {
90  int level = luaL_optint(L, 2, 1);
91  lua_settop(L, 1);
92  if (lua_isstring(L, 1) && level > 0) {  /* add extra information? */
93    luaL_where(L, level);
94    lua_pushvalue(L, 1);
95    lua_concat(L, 2);
96  }
97  return lua_error(L);
98}
99
100
101static int luaB_getmetatable (lua_State *L) {
102  luaL_checkany(L, 1);
103  if (!lua_getmetatable(L, 1)) {
104    lua_pushnil(L);
105    return 1;  /* no metatable */
106  }
107  luaL_getmetafield(L, 1, "__metatable");
108  return 1;  /* returns either __metatable field (if present) or metatable */
109}
110
111
112static int luaB_setmetatable (lua_State *L) {
113  int t = lua_type(L, 2);
114  luaL_checktype(L, 1, LUA_TTABLE);
115  luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
116                    "nil or table expected");
117  if (luaL_getmetafield(L, 1, "__metatable"))
118    return luaL_error(L, "cannot change a protected metatable");
119  lua_settop(L, 2);
120  lua_setmetatable(L, 1);
121  return 1;
122}
123
124
125static int luaB_rawequal (lua_State *L) {
126  luaL_checkany(L, 1);
127  luaL_checkany(L, 2);
128  lua_pushboolean(L, lua_rawequal(L, 1, 2));
129  return 1;
130}
131
132
133static int luaB_rawlen (lua_State *L) {
134  int t = lua_type(L, 1);
135  luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1,
136                   "table or string expected");
137  lua_pushinteger(L, lua_rawlen(L, 1));
138  return 1;
139}
140
141
142static int luaB_rawget (lua_State *L) {
143  luaL_checktype(L, 1, LUA_TTABLE);
144  luaL_checkany(L, 2);
145  lua_settop(L, 2);
146  lua_rawget(L, 1);
147  return 1;
148}
149
150static int luaB_rawset (lua_State *L) {
151  luaL_checktype(L, 1, LUA_TTABLE);
152  luaL_checkany(L, 2);
153  luaL_checkany(L, 3);
154  lua_settop(L, 3);
155  lua_rawset(L, 1);
156  return 1;
157}
158
159
160static int luaB_collectgarbage (lua_State *L) {
161  static const char *const opts[] = {"stop", "restart", "collect",
162    "count", "step", "setpause", "setstepmul",
163    "setmajorinc", "isrunning", "generational", "incremental", NULL};
164  static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
165    LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
166    LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC};
167  int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];
168  int ex = luaL_optint(L, 2, 0);
169  int res = lua_gc(L, o, ex);
170  switch (o) {
171    case LUA_GCCOUNT: {
172      int b = lua_gc(L, LUA_GCCOUNTB, 0);
173      lua_pushnumber(L, res + ((lua_Number)b/1024));
174      lua_pushinteger(L, b);
175      return 2;
176    }
177    case LUA_GCSTEP: case LUA_GCISRUNNING: {
178      lua_pushboolean(L, res);
179      return 1;
180    }
181    default: {
182      lua_pushinteger(L, res);
183      return 1;
184    }
185  }
186}
187
188
189static int luaB_type (lua_State *L) {
190  luaL_checkany(L, 1);
191  lua_pushstring(L, luaL_typename(L, 1));
192  return 1;
193}
194
195
196static int pairsmeta (lua_State *L, const char *method, int iszero,
197                      lua_CFunction iter) {
198  if (!luaL_getmetafield(L, 1, method)) {  /* no metamethod? */
199    luaL_checktype(L, 1, LUA_TTABLE);  /* argument must be a table */
200    lua_pushcfunction(L, iter);  /* will return generator, */
201    lua_pushvalue(L, 1);  /* state, */
202    if (iszero) lua_pushinteger(L, 0);  /* and initial value */
203    else lua_pushnil(L);
204  }
205  else {
206    lua_pushvalue(L, 1);  /* argument 'self' to metamethod */
207    lua_call(L, 1, 3);  /* get 3 values from metamethod */
208  }
209  return 3;
210}
211
212
213static int luaB_next (lua_State *L) {
214  luaL_checktype(L, 1, LUA_TTABLE);
215  lua_settop(L, 2);  /* create a 2nd argument if there isn't one */
216  if (lua_next(L, 1))
217    return 2;
218  else {
219    lua_pushnil(L);
220    return 1;
221  }
222}
223
224
225static int luaB_pairs (lua_State *L) {
226  return pairsmeta(L, "__pairs", 0, luaB_next);
227}
228
229
230static int ipairsaux (lua_State *L) {
231  int i = luaL_checkint(L, 2);
232  luaL_checktype(L, 1, LUA_TTABLE);
233  i++;  /* next value */
234  lua_pushinteger(L, i);
235  lua_rawgeti(L, 1, i);
236  return (lua_isnil(L, -1)) ? 1 : 2;
237}
238
239
240static int luaB_ipairs (lua_State *L) {
241  return pairsmeta(L, "__ipairs", 1, ipairsaux);
242}
243
244
245static int load_aux (lua_State *L, int status, int envidx) {
246  if (status == LUA_OK) {
247    if (envidx != 0) {  /* 'env' parameter? */
248      lua_pushvalue(L, envidx);  /* environment for loaded function */
249      if (!lua_setupvalue(L, -2, 1))  /* set it as 1st upvalue */
250        lua_pop(L, 1);  /* remove 'env' if not used by previous call */
251    }
252    return 1;
253  }
254  else {  /* error (message is on top of the stack) */
255    lua_pushnil(L);
256    lua_insert(L, -2);  /* put before error message */
257    return 2;  /* return nil plus error message */
258  }
259}
260
261
262static int luaB_loadfile (lua_State *L) {
263  const char *fname = luaL_optstring(L, 1, NULL);
264  const char *mode = luaL_optstring(L, 2, NULL);
265  int env = (!lua_isnone(L, 3) ? 3 : 0);  /* 'env' index or 0 if no 'env' */
266  int status = luaL_loadfilex(L, fname, mode);
267  return load_aux(L, status, env);
268}
269
270
271/*
272** {======================================================
273** Generic Read function
274** =======================================================
275*/
276
277
278/*
279** reserved slot, above all arguments, to hold a copy of the returned
280** string to avoid it being collected while parsed. 'load' has four
281** optional arguments (chunk, source name, mode, and environment).
282*/
283#define RESERVEDSLOT   5
284
285
286/*
287** Reader for generic `load' function: `lua_load' uses the
288** stack for internal stuff, so the reader cannot change the
289** stack top. Instead, it keeps its resulting string in a
290** reserved slot inside the stack.
291*/
292static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
293  (void)(ud);  /* not used */
294  luaL_checkstack(L, 2, "too many nested functions");
295  lua_pushvalue(L, 1);  /* get function */
296  lua_call(L, 0, 1);  /* call it */
297  if (lua_isnil(L, -1)) {
298    lua_pop(L, 1);  /* pop result */
299    *size = 0;
300    return NULL;
301  }
302  else if (!lua_isstring(L, -1))
303    luaL_error(L, "reader function must return a string");
304  lua_replace(L, RESERVEDSLOT);  /* save string in reserved slot */
305  return lua_tolstring(L, RESERVEDSLOT, size);
306}
307
308
309static int luaB_load (lua_State *L) {
310  int status;
311  size_t l;
312  const char *s = lua_tolstring(L, 1, &l);
313  const char *mode = luaL_optstring(L, 3, "bt");
314  int env = (!lua_isnone(L, 4) ? 4 : 0);  /* 'env' index or 0 if no 'env' */
315  if (s != NULL) {  /* loading a string? */
316    const char *chunkname = luaL_optstring(L, 2, s);
317    status = luaL_loadbufferx(L, s, l, chunkname, mode);
318  }
319  else {  /* loading from a reader function */
320    const char *chunkname = luaL_optstring(L, 2, "=(load)");
321    luaL_checktype(L, 1, LUA_TFUNCTION);
322    lua_settop(L, RESERVEDSLOT);  /* create reserved slot */
323    status = lua_load(L, generic_reader, NULL, chunkname, mode);
324  }
325  return load_aux(L, status, env);
326}
327
328/* }====================================================== */
329
330
331static int dofilecont (lua_State *L) {
332  return lua_gettop(L) - 1;
333}
334
335
336static int luaB_dofile (lua_State *L) {
337  const char *fname = luaL_optstring(L, 1, NULL);
338  lua_settop(L, 1);
339  if (luaL_loadfile(L, fname) != LUA_OK)
340    return lua_error(L);
341  lua_callk(L, 0, LUA_MULTRET, 0, dofilecont);
342  return dofilecont(L);
343}
344
345
346static int luaB_assert (lua_State *L) {
347  if (!lua_toboolean(L, 1))
348    return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
349  return lua_gettop(L);
350}
351
352
353static int luaB_select (lua_State *L) {
354  int n = lua_gettop(L);
355  if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
356    lua_pushinteger(L, n-1);
357    return 1;
358  }
359  else {
360    int i = luaL_checkint(L, 1);
361    if (i < 0) i = n + i;
362    else if (i > n) i = n;
363    luaL_argcheck(L, 1 <= i, 1, "index out of range");
364    return n - i;
365  }
366}
367
368
369static int finishpcall (lua_State *L, int status) {
370  if (!lua_checkstack(L, 1)) {  /* no space for extra boolean? */
371    lua_settop(L, 0);  /* create space for return values */
372    lua_pushboolean(L, 0);
373    lua_pushstring(L, "stack overflow");
374    return 2;  /* return false, msg */
375  }
376  lua_pushboolean(L, status);  /* first result (status) */
377  lua_replace(L, 1);  /* put first result in first slot */
378  return lua_gettop(L);
379}
380
381
382static int pcallcont (lua_State *L) {
383  int status = lua_getctx(L, NULL);
384  return finishpcall(L, (status == LUA_YIELD));
385}
386
387
388static int luaB_pcall (lua_State *L) {
389  int status;
390  luaL_checkany(L, 1);
391  lua_pushnil(L);
392  lua_insert(L, 1);  /* create space for status result */
393  status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont);
394  return finishpcall(L, (status == LUA_OK));
395}
396
397
398static int luaB_xpcall (lua_State *L) {
399  int status;
400  int n = lua_gettop(L);
401  luaL_argcheck(L, n >= 2, 2, "value expected");
402  lua_pushvalue(L, 1);  /* exchange function... */
403  lua_copy(L, 2, 1);  /* ...and error handler */
404  lua_replace(L, 2);
405  status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 0, pcallcont);
406  return finishpcall(L, (status == LUA_OK));
407}
408
409
410static int luaB_tostring (lua_State *L) {
411  luaL_checkany(L, 1);
412  luaL_tolstring(L, 1, NULL);
413  return 1;
414}
415
416
417static const luaL_Reg base_funcs[] = {
418  {"assert", luaB_assert},
419  {"collectgarbage", luaB_collectgarbage},
420  {"dofile", luaB_dofile},
421  {"error", luaB_error},
422  {"getmetatable", luaB_getmetatable},
423  {"ipairs", luaB_ipairs},
424  {"loadfile", luaB_loadfile},
425  {"load", luaB_load},
426#if defined(LUA_COMPAT_LOADSTRING)
427  {"loadstring", luaB_load},
428#endif
429  {"next", luaB_next},
430  {"pairs", luaB_pairs},
431  {"pcall", luaB_pcall},
432  {"print", luaB_print},
433  {"rawequal", luaB_rawequal},
434  {"rawlen", luaB_rawlen},
435  {"rawget", luaB_rawget},
436  {"rawset", luaB_rawset},
437  {"select", luaB_select},
438  {"setmetatable", luaB_setmetatable},
439  {"tonumber", luaB_tonumber},
440  {"tostring", luaB_tostring},
441  {"type", luaB_type},
442  {"xpcall", luaB_xpcall},
443  {NULL, NULL}
444};
445
446
447LUAMOD_API int luaopen_base (lua_State *L) {
448  /* set global _G */
449  lua_pushglobaltable(L);
450  lua_pushglobaltable(L);
451  lua_setfield(L, -2, "_G");
452  /* open lib into global table */
453  luaL_setfuncs(L, base_funcs, 0);
454  lua_pushliteral(L, LUA_VERSION);
455  lua_setfield(L, -2, "_VERSION");  /* set global _VERSION */
456  return 1;
457}
458
Property changes on: trunk/src/lib/lua/lbaselib.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/lopcodes.h
r0r22721
1/*
2** $Id: lopcodes.h,v 1.142 2011/07/15 12:50:29 roberto Exp $
3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lopcodes_h
8#define lopcodes_h
9
10#include "llimits.h"
11
12
13/*===========================================================================
14  We assume that instructions are unsigned numbers.
15  All instructions have an opcode in the first 6 bits.
16  Instructions can have the following fields:
17   `A' : 8 bits
18   `B' : 9 bits
19   `C' : 9 bits
20   'Ax' : 26 bits ('A', 'B', and 'C' together)
21   `Bx' : 18 bits (`B' and `C' together)
22   `sBx' : signed Bx
23
24  A signed argument is represented in excess K; that is, the number
25  value is the unsigned value minus K. K is exactly the maximum value
26  for that argument (so that -max is represented by 0, and +max is
27  represented by 2*max), which is half the maximum for the corresponding
28  unsigned argument.
29===========================================================================*/
30
31
32enum OpMode {iABC, iABx, iAsBx, iAx};  /* basic instruction format */
33
34
35/*
36** size and position of opcode arguments.
37*/
38#define SIZE_C      9
39#define SIZE_B      9
40#define SIZE_Bx      (SIZE_C + SIZE_B)
41#define SIZE_A      8
42#define SIZE_Ax      (SIZE_C + SIZE_B + SIZE_A)
43
44#define SIZE_OP      6
45
46#define POS_OP      0
47#define POS_A      (POS_OP + SIZE_OP)
48#define POS_C      (POS_A + SIZE_A)
49#define POS_B      (POS_C + SIZE_C)
50#define POS_Bx      POS_C
51#define POS_Ax      POS_A
52
53
54/*
55** limits for opcode arguments.
56** we use (signed) int to manipulate most arguments,
57** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
58*/
59#if SIZE_Bx < LUAI_BITSINT-1
60#define MAXARG_Bx        ((1<<SIZE_Bx)-1)
61#define MAXARG_sBx        (MAXARG_Bx>>1)         /* `sBx' is signed */
62#else
63#define MAXARG_Bx        MAX_INT
64#define MAXARG_sBx        MAX_INT
65#endif
66
67#if SIZE_Ax < LUAI_BITSINT-1
68#define MAXARG_Ax   ((1<<SIZE_Ax)-1)
69#else
70#define MAXARG_Ax   MAX_INT
71#endif
72
73
74#define MAXARG_A        ((1<<SIZE_A)-1)
75#define MAXARG_B        ((1<<SIZE_B)-1)
76#define MAXARG_C        ((1<<SIZE_C)-1)
77
78
79/* creates a mask with `n' 1 bits at position `p' */
80#define MASK1(n,p)   ((~((~(Instruction)0)<<(n)))<<(p))
81
82/* creates a mask with `n' 0 bits at position `p' */
83#define MASK0(n,p)   (~MASK1(n,p))
84
85/*
86** the following macros help to manipulate instructions
87*/
88
89#define GET_OPCODE(i)   (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
90#define SET_OPCODE(i,o)   ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
91      ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
92
93#define getarg(i,pos,size)   (cast(int, ((i)>>pos) & MASK1(size,0)))
94#define setarg(i,v,pos,size)   ((i) = (((i)&MASK0(size,pos)) | \
95                ((cast(Instruction, v)<<pos)&MASK1(size,pos))))
96
97#define GETARG_A(i)   getarg(i, POS_A, SIZE_A)
98#define SETARG_A(i,v)   setarg(i, v, POS_A, SIZE_A)
99
100#define GETARG_B(i)   getarg(i, POS_B, SIZE_B)
101#define SETARG_B(i,v)   setarg(i, v, POS_B, SIZE_B)
102
103#define GETARG_C(i)   getarg(i, POS_C, SIZE_C)
104#define SETARG_C(i,v)   setarg(i, v, POS_C, SIZE_C)
105
106#define GETARG_Bx(i)   getarg(i, POS_Bx, SIZE_Bx)
107#define SETARG_Bx(i,v)   setarg(i, v, POS_Bx, SIZE_Bx)
108
109#define GETARG_Ax(i)   getarg(i, POS_Ax, SIZE_Ax)
110#define SETARG_Ax(i,v)   setarg(i, v, POS_Ax, SIZE_Ax)
111
112#define GETARG_sBx(i)   (GETARG_Bx(i)-MAXARG_sBx)
113#define SETARG_sBx(i,b)   SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
114
115
116#define CREATE_ABC(o,a,b,c)   ((cast(Instruction, o)<<POS_OP) \
117         | (cast(Instruction, a)<<POS_A) \
118         | (cast(Instruction, b)<<POS_B) \
119         | (cast(Instruction, c)<<POS_C))
120
121#define CREATE_ABx(o,a,bc)   ((cast(Instruction, o)<<POS_OP) \
122         | (cast(Instruction, a)<<POS_A) \
123         | (cast(Instruction, bc)<<POS_Bx))
124
125#define CREATE_Ax(o,a)      ((cast(Instruction, o)<<POS_OP) \
126         | (cast(Instruction, a)<<POS_Ax))
127
128
129/*
130** Macros to operate RK indices
131*/
132
133/* this bit 1 means constant (0 means register) */
134#define BITRK      (1 << (SIZE_B - 1))
135
136/* test whether value is a constant */
137#define ISK(x)      ((x) & BITRK)
138
139/* gets the index of the constant */
140#define INDEXK(r)   ((int)(r) & ~BITRK)
141
142#define MAXINDEXRK   (BITRK - 1)
143
144/* code a constant index as a RK value */
145#define RKASK(x)   ((x) | BITRK)
146
147
148/*
149** invalid register that fits in 8 bits
150*/
151#define NO_REG      MAXARG_A
152
153
154/*
155** R(x) - register
156** Kst(x) - constant (in constant table)
157** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
158*/
159
160
161/*
162** grep "ORDER OP" if you change these enums
163*/
164
165typedef enum {
166/*----------------------------------------------------------------------
167name      args   description
168------------------------------------------------------------------------*/
169OP_MOVE,/*   A B   R(A) := R(B)               */
170OP_LOADK,/*   A Bx   R(A) := Kst(Bx)               */
171OP_LOADKX,/*   A    R(A) := Kst(extra arg)            */
172OP_LOADBOOL,/*   A B C   R(A) := (Bool)B; if (C) pc++         */
173OP_LOADNIL,/*   A B   R(A), R(A+1), ..., R(A+B) := nil      */
174OP_GETUPVAL,/*   A B   R(A) := UpValue[B]            */
175
176OP_GETTABUP,/*   A B C   R(A) := UpValue[B][RK(C)]         */
177OP_GETTABLE,/*   A B C   R(A) := R(B)[RK(C)]            */
178
179OP_SETTABUP,/*   A B C   UpValue[A][RK(B)] := RK(C)         */
180OP_SETUPVAL,/*   A B   UpValue[B] := R(A)            */
181OP_SETTABLE,/*   A B C   R(A)[RK(B)] := RK(C)            */
182
183OP_NEWTABLE,/*   A B C   R(A) := {} (size = B,C)            */
184
185OP_SELF,/*   A B C   R(A+1) := R(B); R(A) := R(B)[RK(C)]      */
186
187OP_ADD,/*   A B C   R(A) := RK(B) + RK(C)            */
188OP_SUB,/*   A B C   R(A) := RK(B) - RK(C)            */
189OP_MUL,/*   A B C   R(A) := RK(B) * RK(C)            */
190OP_DIV,/*   A B C   R(A) := RK(B) / RK(C)            */
191OP_MOD,/*   A B C   R(A) := RK(B) % RK(C)            */
192OP_POW,/*   A B C   R(A) := RK(B) ^ RK(C)            */
193OP_UNM,/*   A B   R(A) := -R(B)               */
194OP_NOT,/*   A B   R(A) := not R(B)            */
195OP_LEN,/*   A B   R(A) := length of R(B)            */
196
197OP_CONCAT,/*   A B C   R(A) := R(B).. ... ..R(C)         */
198
199OP_JMP,/*   A sBx   pc+=sBx; if (A) close all upvalues >= R(A) + 1   */
200OP_EQ,/*   A B C   if ((RK(B) == RK(C)) ~= A) then pc++      */
201OP_LT,/*   A B C   if ((RK(B) <  RK(C)) ~= A) then pc++      */
202OP_LE,/*   A B C   if ((RK(B) <= RK(C)) ~= A) then pc++      */
203
204OP_TEST,/*   A C   if not (R(A) <=> C) then pc++         */
205OP_TESTSET,/*   A B C   if (R(B) <=> C) then R(A) := R(B) else pc++   */
206
207OP_CALL,/*   A B C   R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
208OP_TAILCALL,/*   A B C   return R(A)(R(A+1), ... ,R(A+B-1))      */
209OP_RETURN,/*   A B   return R(A), ... ,R(A+B-2)   (see note)   */
210
211OP_FORLOOP,/*   A sBx   R(A)+=R(A+2);
212         if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
213OP_FORPREP,/*   A sBx   R(A)-=R(A+2); pc+=sBx            */
214
215OP_TFORCALL,/*   A C   R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));   */
216OP_TFORLOOP,/*   A sBx   if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/
217
218OP_SETLIST,/*   A B C   R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B   */
219
220OP_CLOSURE,/*   A Bx   R(A) := closure(KPROTO[Bx])         */
221
222OP_VARARG,/*   A B   R(A), R(A+1), ..., R(A+B-2) = vararg      */
223
224OP_EXTRAARG/*   Ax   extra (larger) argument for previous opcode   */
225} OpCode;
226
227
228#define NUM_OPCODES   (cast(int, OP_EXTRAARG) + 1)
229
230
231
232/*===========================================================================
233  Notes:
234  (*) In OP_CALL, if (B == 0) then B = top. If (C == 0), then `top' is
235  set to last_result+1, so next open instruction (OP_CALL, OP_RETURN,
236  OP_SETLIST) may use `top'.
237
238  (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
239  set top (like in OP_CALL with C == 0).
240
241  (*) In OP_RETURN, if (B == 0) then return up to `top'.
242
243  (*) In OP_SETLIST, if (B == 0) then B = `top'; if (C == 0) then next
244  'instruction' is EXTRAARG(real C).
245
246  (*) In OP_LOADKX, the next 'instruction' is always EXTRAARG.
247
248  (*) For comparisons, A specifies what condition the test should accept
249  (true or false).
250
251  (*) All `skips' (pc++) assume that next instruction is a jump.
252
253===========================================================================*/
254
255
256/*
257** masks for instruction properties. The format is:
258** bits 0-1: op mode
259** bits 2-3: C arg mode
260** bits 4-5: B arg mode
261** bit 6: instruction set register A
262** bit 7: operator is a test (next instruction must be a jump)
263*/
264
265enum OpArgMask {
266  OpArgN,  /* argument is not used */
267  OpArgU,  /* argument is used */
268  OpArgR,  /* argument is a register or a jump offset */
269  OpArgK   /* argument is a constant or register/constant */
270};
271
272LUAI_DDEC const lu_byte luaP_opmodes[NUM_OPCODES];
273
274#define getOpMode(m)   (cast(enum OpMode, luaP_opmodes[m] & 3))
275#define getBMode(m)   (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
276#define getCMode(m)   (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
277#define testAMode(m)   (luaP_opmodes[m] & (1 << 6))
278#define testTMode(m)   (luaP_opmodes[m] & (1 << 7))
279
280
281LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES+1];  /* opcode names */
282
283
284/* number of list items to accumulate before a SETLIST instruction */
285#define LFIELDS_PER_FLUSH   50
286
287
288#endif
Property changes on: trunk/src/lib/lua/lopcodes.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/lzio.c
r0r22721
1/*
2** $Id: lzio.c,v 1.35 2012/05/14 13:34:18 roberto Exp $
3** Buffered streams
4** See Copyright Notice in lua.h
5*/
6
7
8#include <string.h>
9
10#define lzio_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "llimits.h"
16#include "lmem.h"
17#include "lstate.h"
18#include "lzio.h"
19
20
21int luaZ_fill (ZIO *z) {
22  size_t size;
23  lua_State *L = z->L;
24  const char *buff;
25  lua_unlock(L);
26  buff = z->reader(L, z->data, &size);
27  lua_lock(L);
28  if (buff == NULL || size == 0)
29    return EOZ;
30  z->n = size - 1;  /* discount char being returned */
31  z->p = buff;
32  return cast_uchar(*(z->p++));
33}
34
35
36void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
37  z->L = L;
38  z->reader = reader;
39  z->data = data;
40  z->n = 0;
41  z->p = NULL;
42}
43
44
45/* --------------------------------------------------------------- read --- */
46size_t luaZ_read (ZIO *z, void *b, size_t n) {
47  while (n) {
48    size_t m;
49    if (z->n == 0) {  /* no bytes in buffer? */
50      if (luaZ_fill(z) == EOZ)  /* try to read more */
51        return n;  /* no more input; return number of missing bytes */
52      else {
53        z->n++;  /* luaZ_fill consumed first byte; put it back */
54        z->p--;
55      }
56    }
57    m = (n <= z->n) ? n : z->n;  /* min. between n and z->n */
58    memcpy(b, z->p, m);
59    z->n -= m;
60    z->p += m;
61    b = (char *)b + m;
62    n -= m;
63  }
64  return 0;
65}
66
67/* ------------------------------------------------------------------------ */
68char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) {
69  if (n > buff->buffsize) {
70    if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
71    luaZ_resizebuffer(L, buff, n);
72  }
73  return buff->buffer;
74}
75
76
Property changes on: trunk/src/lib/lua/lzio.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/ldo.c
r0r22721
1/*
2** $Id: ldo.c,v 2.108 2012/10/01 14:05:04 roberto Exp $
3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h
5*/
6
7
8#include <setjmp.h>
9#include <stdlib.h>
10#include <string.h>
11
12#define ldo_c
13#define LUA_CORE
14
15#include "lua.h"
16
17#include "lapi.h"
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** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By
45** default, Lua handles errors with exceptions when compiling as
46** C++ code, with _longjmp/_setjmp when asked to use them, and with
47** longjmp/setjmp otherwise.
48*/
49#if !defined(LUAI_THROW)
50
51#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP)
52/* C++ exceptions */
53#define LUAI_THROW(L,c)      throw(c)
54#define LUAI_TRY(L,c,a) \
55   try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; }
56#define luai_jmpbuf      int  /* dummy variable */
57
58#elif defined(LUA_USE_ULONGJMP)
59/* in Unix, try _longjmp/_setjmp (more efficient) */
60#define LUAI_THROW(L,c)      _longjmp((c)->b, 1)
61#define LUAI_TRY(L,c,a)      if (_setjmp((c)->b) == 0) { a }
62#define luai_jmpbuf      jmp_buf
63
64#else
65/* default handling with long jumps */
66#define LUAI_THROW(L,c)      longjmp((c)->b, 1)
67#define LUAI_TRY(L,c,a)      if (setjmp((c)->b) == 0) { a }
68#define luai_jmpbuf      jmp_buf
69
70#endif
71
72#endif
73
74
75
76/* chain list of long jump buffers */
77struct lua_longjmp {
78  struct lua_longjmp *previous;
79  luai_jmpbuf b;
80  volatile int status;  /* error code */
81};
82
83
84static void seterrorobj (lua_State *L, int errcode, StkId oldtop) {
85  switch (errcode) {
86    case LUA_ERRMEM: {  /* memory error? */
87      setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
88      break;
89    }
90    case LUA_ERRERR: {
91      setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
92      break;
93    }
94    default: {
95      setobjs2s(L, oldtop, L->top - 1);  /* error message on current top */
96      break;
97    }
98  }
99  L->top = oldtop + 1;
100}
101
102
103l_noret luaD_throw (lua_State *L, int errcode) {
104  if (L->errorJmp) {  /* thread has an error handler? */
105    L->errorJmp->status = errcode;  /* set status */
106    LUAI_THROW(L, L->errorJmp);  /* jump to it */
107  }
108  else {  /* thread has no error handler */
109    L->status = cast_byte(errcode);  /* mark it as dead */
110    if (G(L)->mainthread->errorJmp) {  /* main thread has a handler? */
111      setobjs2s(L, G(L)->mainthread->top++, L->top - 1);  /* copy error obj. */
112      luaD_throw(G(L)->mainthread, errcode);  /* re-throw in main thread */
113    }
114    else {  /* no handler at all; abort */
115      if (G(L)->panic) {  /* panic function? */
116        lua_unlock(L);
117        G(L)->panic(L);  /* call it (last chance to jump out) */
118      }
119      abort();
120    }
121  }
122}
123
124
125int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
126  unsigned short oldnCcalls = L->nCcalls;
127  struct lua_longjmp lj;
128  lj.status = LUA_OK;
129  lj.previous = L->errorJmp;  /* chain new error handler */
130  L->errorJmp = &lj;
131  LUAI_TRY(L, &lj,
132    (*f)(L, ud);
133  );
134  L->errorJmp = lj.previous;  /* restore old error handler */
135  L->nCcalls = oldnCcalls;
136  return lj.status;
137}
138
139/* }====================================================== */
140
141
142static void correctstack (lua_State *L, TValue *oldstack) {
143  CallInfo *ci;
144  GCObject *up;
145  L->top = (L->top - oldstack) + L->stack;
146  for (up = L->openupval; up != NULL; up = up->gch.next)
147    gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
148  for (ci = L->ci; ci != NULL; ci = ci->previous) {
149    ci->top = (ci->top - oldstack) + L->stack;
150    ci->func = (ci->func - oldstack) + L->stack;
151    if (isLua(ci))
152      ci->u.l.base = (ci->u.l.base - oldstack) + L->stack;
153  }
154}
155
156
157/* some space for error handling */
158#define ERRORSTACKSIZE   (LUAI_MAXSTACK + 200)
159
160
161void luaD_reallocstack (lua_State *L, int newsize) {
162  TValue *oldstack = L->stack;
163  int lim = L->stacksize;
164  lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
165  lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK);
166  luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue);
167  for (; lim < newsize; lim++)
168    setnilvalue(L->stack + lim); /* erase new segment */
169  L->stacksize = newsize;
170  L->stack_last = L->stack + newsize - EXTRA_STACK;
171  correctstack(L, oldstack);
172}
173
174
175void luaD_growstack (lua_State *L, int n) {
176  int size = L->stacksize;
177  if (size > LUAI_MAXSTACK)  /* error after extra size? */
178    luaD_throw(L, LUA_ERRERR);
179  else {
180    int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK;
181    int newsize = 2 * size;
182    if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK;
183    if (newsize < needed) newsize = needed;
184    if (newsize > LUAI_MAXSTACK) {  /* stack overflow? */
185      luaD_reallocstack(L, ERRORSTACKSIZE);
186      luaG_runerror(L, "stack overflow");
187    }
188    else
189      luaD_reallocstack(L, newsize);
190  }
191}
192
193
194static int stackinuse (lua_State *L) {
195  CallInfo *ci;
196  StkId lim = L->top;
197  for (ci = L->ci; ci != NULL; ci = ci->previous) {
198    lua_assert(ci->top <= L->stack_last);
199    if (lim < ci->top) lim = ci->top;
200  }
201  return cast_int(lim - L->stack) + 1;  /* part of stack in use */
202}
203
204
205void luaD_shrinkstack (lua_State *L) {
206  int inuse = stackinuse(L);
207  int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
208  if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK;
209  if (inuse > LUAI_MAXSTACK ||  /* handling stack overflow? */
210      goodsize >= L->stacksize)  /* would grow instead of shrink? */
211    condmovestack(L);  /* don't change stack (change only for debugging) */
212  else
213    luaD_reallocstack(L, goodsize);  /* shrink it */
214}
215
216
217void luaD_hook (lua_State *L, int event, int line) {
218  lua_Hook hook = L->hook;
219  if (hook && L->allowhook) {
220    CallInfo *ci = L->ci;
221    ptrdiff_t top = savestack(L, L->top);
222    ptrdiff_t ci_top = savestack(L, ci->top);
223    lua_Debug ar;
224    ar.event = event;
225    ar.currentline = line;
226    ar.i_ci = ci;
227    luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
228    ci->top = L->top + LUA_MINSTACK;
229    lua_assert(ci->top <= L->stack_last);
230    L->allowhook = 0;  /* cannot call hooks inside a hook */
231    ci->callstatus |= CIST_HOOKED;
232    lua_unlock(L);
233    (*hook)(L, &ar);
234    lua_lock(L);
235    lua_assert(!L->allowhook);
236    L->allowhook = 1;
237    ci->top = restorestack(L, ci_top);
238    L->top = restorestack(L, top);
239    ci->callstatus &= ~CIST_HOOKED;
240  }
241}
242
243
244static void callhook (lua_State *L, CallInfo *ci) {
245  int hook = LUA_HOOKCALL;
246  ci->u.l.savedpc++;  /* hooks assume 'pc' is already incremented */
247  if (isLua(ci->previous) &&
248      GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) {
249    ci->callstatus |= CIST_TAIL;
250    hook = LUA_HOOKTAILCALL;
251  }
252  luaD_hook(L, hook, -1);
253  ci->u.l.savedpc--;  /* correct 'pc' */
254}
255
256
257static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
258  int i;
259  int nfixargs = p->numparams;
260  StkId base, fixed;
261  lua_assert(actual >= nfixargs);
262  /* move fixed parameters to final position */
263  fixed = L->top - actual;  /* first fixed argument */
264  base = L->top;  /* final position of first argument */
265  for (i=0; i<nfixargs; i++) {
266    setobjs2s(L, L->top++, fixed + i);
267    setnilvalue(fixed + i);
268  }
269  return base;
270}
271
272
273static StkId tryfuncTM (lua_State *L, StkId func) {
274  const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
275  StkId p;
276  ptrdiff_t funcr = savestack(L, func);
277  if (!ttisfunction(tm))
278    luaG_typeerror(L, func, "call");
279  /* Open a hole inside the stack at `func' */
280  for (p = L->top; p > func; p--) setobjs2s(L, p, p-1);
281  incr_top(L);
282  func = restorestack(L, funcr);  /* previous call may change stack */
283  setobj2s(L, func, tm);  /* tag method is the new function to be called */
284  return func;
285}
286
287
288
289#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))
290
291
292/*
293** returns true if function has been executed (C function)
294*/
295int luaD_precall (lua_State *L, StkId func, int nresults) {
296  lua_CFunction f;
297  CallInfo *ci;
298  int n;  /* number of arguments (Lua) or returns (C) */
299  ptrdiff_t funcr = savestack(L, func);
300  switch (ttype(func)) {
301    case LUA_TLCF:  /* light C function */
302      f = fvalue(func);
303      goto Cfunc;
304    case LUA_TCCL: {  /* C closure */
305      f = clCvalue(func)->f;
306     Cfunc:
307      luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
308      ci = next_ci(L);  /* now 'enter' new function */
309      ci->nresults = nresults;
310      ci->func = restorestack(L, funcr);
311      ci->top = L->top + LUA_MINSTACK;
312      lua_assert(ci->top <= L->stack_last);
313      ci->callstatus = 0;
314      luaC_checkGC(L);  /* stack grow uses memory */
315      if (L->hookmask & LUA_MASKCALL)
316        luaD_hook(L, LUA_HOOKCALL, -1);
317      lua_unlock(L);
318      n = (*f)(L);  /* do the actual call */
319      lua_lock(L);
320      api_checknelems(L, n);
321      luaD_poscall(L, L->top - n);
322      return 1;
323    }
324    case LUA_TLCL: {  /* Lua function: prepare its call */
325      StkId base;
326      Proto *p = clLvalue(func)->p;
327      luaD_checkstack(L, p->maxstacksize);
328      func = restorestack(L, funcr);
329      n = cast_int(L->top - func) - 1;  /* number of real arguments */
330      for (; n < p->numparams; n++)
331        setnilvalue(L->top++);  /* complete missing arguments */
332      base = (!p->is_vararg) ? func + 1 : adjust_varargs(L, p, n);
333      ci = next_ci(L);  /* now 'enter' new function */
334      ci->nresults = nresults;
335      ci->func = func;
336      ci->u.l.base = base;
337      ci->top = base + p->maxstacksize;
338      lua_assert(ci->top <= L->stack_last);
339      ci->u.l.savedpc = p->code;  /* starting point */
340      ci->callstatus = CIST_LUA;
341      L->top = ci->top;
342      luaC_checkGC(L);  /* stack grow uses memory */
343      if (L->hookmask & LUA_MASKCALL)
344        callhook(L, ci);
345      return 0;
346    }
347    default: {  /* not a function */
348      func = tryfuncTM(L, func);  /* retry with 'function' tag method */
349      return luaD_precall(L, func, nresults);  /* now it must be a function */
350    }
351  }
352}
353
354
355int luaD_poscall (lua_State *L, StkId firstResult) {
356  StkId res;
357  int wanted, i;
358  CallInfo *ci = L->ci;
359  if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
360    if (L->hookmask & LUA_MASKRET) {
361      ptrdiff_t fr = savestack(L, firstResult);  /* hook may change stack */
362      luaD_hook(L, LUA_HOOKRET, -1);
363      firstResult = restorestack(L, fr);
364    }
365    L->oldpc = ci->previous->u.l.savedpc;  /* 'oldpc' for caller function */
366  }
367  res = ci->func;  /* res == final position of 1st result */
368  wanted = ci->nresults;
369  L->ci = ci = ci->previous;  /* back to caller */
370  /* move results to correct place */
371  for (i = wanted; i != 0 && firstResult < L->top; i--)
372    setobjs2s(L, res++, firstResult++);
373  while (i-- > 0)
374    setnilvalue(res++);
375  L->top = res;
376  return (wanted - LUA_MULTRET);  /* 0 iff wanted == LUA_MULTRET */
377}
378
379
380/*
381** Call a function (C or Lua). The function to be called is at *func.
382** The arguments are on the stack, right after the function.
383** When returns, all the results are on the stack, starting at the original
384** function position.
385*/
386void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) {
387  if (++L->nCcalls >= LUAI_MAXCCALLS) {
388    if (L->nCcalls == LUAI_MAXCCALLS)
389      luaG_runerror(L, "C stack overflow");
390    else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
391      luaD_throw(L, LUA_ERRERR);  /* error while handing stack error */
392  }
393  if (!allowyield) L->nny++;
394  if (!luaD_precall(L, func, nResults))  /* is a Lua function? */
395    luaV_execute(L);  /* call it */
396  if (!allowyield) L->nny--;
397  L->nCcalls--;
398}
399
400
401static void finishCcall (lua_State *L) {
402  CallInfo *ci = L->ci;
403  int n;
404  lua_assert(ci->u.c.k != NULL);  /* must have a continuation */
405  lua_assert(L->nny == 0);
406  if (ci->callstatus & CIST_YPCALL) {  /* was inside a pcall? */
407    ci->callstatus &= ~CIST_YPCALL;  /* finish 'lua_pcall' */
408    L->errfunc = ci->u.c.old_errfunc;
409  }
410  /* finish 'lua_callk'/'lua_pcall' */
411  adjustresults(L, ci->nresults);
412  /* call continuation function */
413  if (!(ci->callstatus & CIST_STAT))  /* no call status? */
414    ci->u.c.status = LUA_YIELD;  /* 'default' status */
415  lua_assert(ci->u.c.status != LUA_OK);
416  ci->callstatus = (ci->callstatus & ~(CIST_YPCALL | CIST_STAT)) | CIST_YIELDED;
417  lua_unlock(L);
418  n = (*ci->u.c.k)(L);
419  lua_lock(L);
420  api_checknelems(L, n);
421  /* finish 'luaD_precall' */
422  luaD_poscall(L, L->top - n);
423}
424
425
426static void unroll (lua_State *L, void *ud) {
427  UNUSED(ud);
428  for (;;) {
429    if (L->ci == &L->base_ci)  /* stack is empty? */
430      return;  /* coroutine finished normally */
431    if (!isLua(L->ci))  /* C function? */
432      finishCcall(L);
433    else {  /* Lua function */
434      luaV_finishOp(L);  /* finish interrupted instruction */
435      luaV_execute(L);  /* execute down to higher C 'boundary' */
436    }
437  }
438}
439
440
441/*
442** check whether thread has a suspended protected call
443*/
444static CallInfo *findpcall (lua_State *L) {
445  CallInfo *ci;
446  for (ci = L->ci; ci != NULL; ci = ci->previous) {  /* search for a pcall */
447    if (ci->callstatus & CIST_YPCALL)
448      return ci;
449  }
450  return NULL;  /* no pending pcall */
451}
452
453
454static int recover (lua_State *L, int status) {
455  StkId oldtop;
456  CallInfo *ci = findpcall(L);
457  if (ci == NULL) return 0;  /* no recovery point */
458  /* "finish" luaD_pcall */
459  oldtop = restorestack(L, ci->extra);
460  luaF_close(L, oldtop);
461  seterrorobj(L, status, oldtop);
462  L->ci = ci;
463  L->allowhook = ci->u.c.old_allowhook;
464  L->nny = 0;  /* should be zero to be yieldable */
465  luaD_shrinkstack(L);
466  L->errfunc = ci->u.c.old_errfunc;
467  ci->callstatus |= CIST_STAT;  /* call has error status */
468  ci->u.c.status = status;  /* (here it is) */
469  return 1;  /* continue running the coroutine */
470}
471
472
473/*
474** signal an error in the call to 'resume', not in the execution of the
475** coroutine itself. (Such errors should not be handled by any coroutine
476** error handler and should not kill the coroutine.)
477*/
478static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
479  L->top = firstArg;  /* remove args from the stack */
480  setsvalue2s(L, L->top, luaS_new(L, msg));  /* push error message */
481  api_incr_top(L);
482  luaD_throw(L, -1);  /* jump back to 'lua_resume' */
483}
484
485
486/*
487** do the work for 'lua_resume' in protected mode
488*/
489static void resume (lua_State *L, void *ud) {
490  int nCcalls = L->nCcalls;
491  StkId firstArg = cast(StkId, ud);
492  CallInfo *ci = L->ci;
493  if (nCcalls >= LUAI_MAXCCALLS)
494    resume_error(L, "C stack overflow", firstArg);
495  if (L->status == LUA_OK) {  /* may be starting a coroutine */
496    if (ci != &L->base_ci)  /* not in base level? */
497      resume_error(L, "cannot resume non-suspended coroutine", firstArg);
498    /* coroutine is in base level; start running it */
499    if (!luaD_precall(L, firstArg - 1, LUA_MULTRET))  /* Lua function? */
500      luaV_execute(L);  /* call it */
501  }
502  else if (L->status != LUA_YIELD)
503    resume_error(L, "cannot resume dead coroutine", firstArg);
504  else {  /* resuming from previous yield */
505    L->status = LUA_OK;
506    ci->func = restorestack(L, ci->extra);
507    if (isLua(ci))  /* yielded inside a hook? */
508      luaV_execute(L);  /* just continue running Lua code */
509    else {  /* 'common' yield */
510      if (ci->u.c.k != NULL) {  /* does it have a continuation? */
511        int n;
512        ci->u.c.status = LUA_YIELD;  /* 'default' status */
513        ci->callstatus |= CIST_YIELDED;
514        lua_unlock(L);
515        n = (*ci->u.c.k)(L);  /* call continuation */
516        lua_lock(L);
517        api_checknelems(L, n);
518        firstArg = L->top - n;  /* yield results come from continuation */
519      }
520      luaD_poscall(L, firstArg);  /* finish 'luaD_precall' */
521    }
522    unroll(L, NULL);
523  }
524  lua_assert(nCcalls == L->nCcalls);
525}
526
527
528LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
529  int status;
530  lua_lock(L);
531  luai_userstateresume(L, nargs);
532  L->nCcalls = (from) ? from->nCcalls + 1 : 1;
533  L->nny = 0;  /* allow yields */
534  api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
535  status = luaD_rawrunprotected(L, resume, L->top - nargs);
536  if (status == -1)  /* error calling 'lua_resume'? */
537    status = LUA_ERRRUN;
538  else {  /* yield or regular error */
539    while (status != LUA_OK && status != LUA_YIELD) {  /* error? */
540      if (recover(L, status))  /* recover point? */
541        status = luaD_rawrunprotected(L, unroll, NULL);  /* run continuation */
542      else {  /* unrecoverable error */
543        L->status = cast_byte(status);  /* mark thread as `dead' */
544        seterrorobj(L, status, L->top);
545        L->ci->top = L->top;
546        break;
547      }
548    }
549    lua_assert(status == L->status);
550  }
551  L->nny = 1;  /* do not allow yields */
552  L->nCcalls--;
553  lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0));
554  lua_unlock(L);
555  return status;
556}
557
558
559LUA_API int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k) {
560  CallInfo *ci = L->ci;
561  luai_userstateyield(L, nresults);
562  lua_lock(L);
563  api_checknelems(L, nresults);
564  if (L->nny > 0) {
565    if (L != G(L)->mainthread)
566      luaG_runerror(L, "attempt to yield across a C-call boundary");
567    else
568      luaG_runerror(L, "attempt to yield from outside a coroutine");
569  }
570  L->status = LUA_YIELD;
571  ci->extra = savestack(L, ci->func);  /* save current 'func' */
572  if (isLua(ci)) {  /* inside a hook? */
573    api_check(L, k == NULL, "hooks cannot continue after yielding");
574  }
575  else {
576    if ((ci->u.c.k = k) != NULL)  /* is there a continuation? */
577      ci->u.c.ctx = ctx;  /* save context */
578    ci->func = L->top - nresults - 1;  /* protect stack below results */
579    luaD_throw(L, LUA_YIELD);
580  }
581  lua_assert(ci->callstatus & CIST_HOOKED);  /* must be inside a hook */
582  lua_unlock(L);
583  return 0;  /* return to 'luaD_hook' */
584}
585
586
587int luaD_pcall (lua_State *L, Pfunc func, void *u,
588                ptrdiff_t old_top, ptrdiff_t ef) {
589  int status;
590  CallInfo *old_ci = L->ci;
591  lu_byte old_allowhooks = L->allowhook;
592  unsigned short old_nny = L->nny;
593  ptrdiff_t old_errfunc = L->errfunc;
594  L->errfunc = ef;
595  status = luaD_rawrunprotected(L, func, u);
596  if (status != LUA_OK) {  /* an error occurred? */
597    StkId oldtop = restorestack(L, old_top);
598    luaF_close(L, oldtop);  /* close possible pending closures */
599    seterrorobj(L, status, oldtop);
600    L->ci = old_ci;
601    L->allowhook = old_allowhooks;
602    L->nny = old_nny;
603    luaD_shrinkstack(L);
604  }
605  L->errfunc = old_errfunc;
606  return status;
607}
608
609
610
611/*
612** Execute a protected parser.
613*/
614struct SParser {  /* data to `f_parser' */
615  ZIO *z;
616  Mbuffer buff;  /* dynamic structure used by the scanner */
617  Dyndata dyd;  /* dynamic structures used by the parser */
618  const char *mode;
619  const char *name;
620};
621
622
623static void checkmode (lua_State *L, const char *mode, const char *x) {
624  if (mode && strchr(mode, x[0]) == NULL) {
625    luaO_pushfstring(L,
626       "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode);
627    luaD_throw(L, LUA_ERRSYNTAX);
628  }
629}
630
631
632static void f_parser (lua_State *L, void *ud) {
633  int i;
634  Closure *cl;
635  struct SParser *p = cast(struct SParser *, ud);
636  int c = zgetc(p->z);  /* read first character */
637  if (c == LUA_SIGNATURE[0]) {
638    checkmode(L, p->mode, "binary");
639    cl = luaU_undump(L, p->z, &p->buff, p->name);
640  }
641  else {
642    checkmode(L, p->mode, "text");
643    cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
644  }
645  lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues);
646  for (i = 0; i < cl->l.nupvalues; i++) {  /* initialize upvalues */
647    UpVal *up = luaF_newupval(L);
648    cl->l.upvals[i] = up;
649    luaC_objbarrier(L, cl, up);
650  }
651}
652
653
654int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
655                                        const char *mode) {
656  struct SParser p;
657  int status;
658  L->nny++;  /* cannot yield during parsing */
659  p.z = z; p.name = name; p.mode = mode;
660  p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0;
661  p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
662  p.dyd.label.arr = NULL; p.dyd.label.size = 0;
663  luaZ_initbuffer(L, &p.buff);
664  status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
665  luaZ_freebuffer(L, &p.buff);
666  luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size);
667  luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size);
668  luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size);
669  L->nny--;
670  return status;
671}
672
673
Property changes on: trunk/src/lib/lua/ldo.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lbitlib.c
r0r22721
1/*
2** $Id: lbitlib.c,v 1.18 2013/03/19 13:19:12 roberto Exp $
3** Standard library for bitwise operations
4** See Copyright Notice in lua.h
5*/
6
7#define lbitlib_c
8#define LUA_LIB
9
10#include "lua.h"
11
12#include "lauxlib.h"
13#include "lualib.h"
14
15
16/* number of bits to consider in a number */
17#if !defined(LUA_NBITS)
18#define LUA_NBITS   32
19#endif
20
21
22#define ALLONES      (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
23
24/* macro to trim extra bits */
25#define trim(x)      ((x) & ALLONES)
26
27
28/* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */
29#define mask(n)      (~((ALLONES << 1) << ((n) - 1)))
30
31
32typedef lua_Unsigned b_uint;
33
34
35
36static b_uint andaux (lua_State *L) {
37  int i, n = lua_gettop(L);
38  b_uint r = ~(b_uint)0;
39  for (i = 1; i <= n; i++)
40    r &= luaL_checkunsigned(L, i);
41  return trim(r);
42}
43
44
45static int b_and (lua_State *L) {
46  b_uint r = andaux(L);
47  lua_pushunsigned(L, r);
48  return 1;
49}
50
51
52static int b_test (lua_State *L) {
53  b_uint r = andaux(L);
54  lua_pushboolean(L, r != 0);
55  return 1;
56}
57
58
59static int b_or (lua_State *L) {
60  int i, n = lua_gettop(L);
61  b_uint r = 0;
62  for (i = 1; i <= n; i++)
63    r |= luaL_checkunsigned(L, i);
64  lua_pushunsigned(L, trim(r));
65  return 1;
66}
67
68
69static int b_xor (lua_State *L) {
70  int i, n = lua_gettop(L);
71  b_uint r = 0;
72  for (i = 1; i <= n; i++)
73    r ^= luaL_checkunsigned(L, i);
74  lua_pushunsigned(L, trim(r));
75  return 1;
76}
77
78
79static int b_not (lua_State *L) {
80  b_uint r = ~luaL_checkunsigned(L, 1);
81  lua_pushunsigned(L, trim(r));
82  return 1;
83}
84
85
86static int b_shift (lua_State *L, b_uint r, int i) {
87  if (i < 0) {  /* shift right? */
88    i = -i;
89    r = trim(r);
90    if (i >= LUA_NBITS) r = 0;
91    else r >>= i;
92  }
93  else {  /* shift left */
94    if (i >= LUA_NBITS) r = 0;
95    else r <<= i;
96    r = trim(r);
97  }
98  lua_pushunsigned(L, r);
99  return 1;
100}
101
102
103static int b_lshift (lua_State *L) {
104  return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2));
105}
106
107
108static int b_rshift (lua_State *L) {
109  return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2));
110}
111
112
113static int b_arshift (lua_State *L) {
114  b_uint r = luaL_checkunsigned(L, 1);
115  int i = luaL_checkint(L, 2);
116  if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1))))
117    return b_shift(L, r, -i);
118  else {  /* arithmetic shift for 'negative' number */
119    if (i >= LUA_NBITS) r = ALLONES;
120    else
121      r = trim((r >> i) | ~(~(b_uint)0 >> i));  /* add signal bit */
122    lua_pushunsigned(L, r);
123    return 1;
124  }
125}
126
127
128static int b_rot (lua_State *L, int i) {
129  b_uint r = luaL_checkunsigned(L, 1);
130  i &= (LUA_NBITS - 1);  /* i = i % NBITS */
131  r = trim(r);
132  r = (r << i) | (r >> (LUA_NBITS - i));
133  lua_pushunsigned(L, trim(r));
134  return 1;
135}
136
137
138static int b_lrot (lua_State *L) {
139  return b_rot(L, luaL_checkint(L, 2));
140}
141
142
143static int b_rrot (lua_State *L) {
144  return b_rot(L, -luaL_checkint(L, 2));
145}
146
147
148/*
149** get field and width arguments for field-manipulation functions,
150** checking whether they are valid.
151** ('luaL_error' called without 'return' to avoid later warnings about
152** 'width' being used uninitialized.)
153*/
154static int fieldargs (lua_State *L, int farg, int *width) {
155  int f = luaL_checkint(L, farg);
156  int w = luaL_optint(L, farg + 1, 1);
157  luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
158  luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
159  if (f + w > LUA_NBITS)
160    luaL_error(L, "trying to access non-existent bits");
161  *width = w;
162  return f;
163}
164
165
166static int b_extract (lua_State *L) {
167  int w;
168  b_uint r = luaL_checkunsigned(L, 1);
169  int f = fieldargs(L, 2, &w);
170  r = (r >> f) & mask(w);
171  lua_pushunsigned(L, r);
172  return 1;
173}
174
175
176static int b_replace (lua_State *L) {
177  int w;
178  b_uint r = luaL_checkunsigned(L, 1);
179  b_uint v = luaL_checkunsigned(L, 2);
180  int f = fieldargs(L, 3, &w);
181  int m = mask(w);
182  v &= m;  /* erase bits outside given width */
183  r = (r & ~(m << f)) | (v << f);
184  lua_pushunsigned(L, r);
185  return 1;
186}
187
188
189static const luaL_Reg bitlib[] = {
190  {"arshift", b_arshift},
191  {"band", b_and},
192  {"bnot", b_not},
193  {"bor", b_or},
194  {"bxor", b_xor},
195  {"btest", b_test},
196  {"extract", b_extract},
197  {"lrotate", b_lrot},
198  {"lshift", b_lshift},
199  {"replace", b_replace},
200  {"rrotate", b_rrot},
201  {"rshift", b_rshift},
202  {NULL, NULL}
203};
204
205
206
207LUAMOD_API int luaopen_bit32 (lua_State *L) {
208  luaL_newlib(L, bitlib);
209  return 1;
210}
211
Property changes on: trunk/src/lib/lua/lbitlib.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/ldump.c
r0r22721
1/*
2** $Id: ldump.c,v 2.17 2012/01/23 23:02:10 roberto Exp $
3** save precompiled Lua chunks
4** See Copyright Notice in lua.h
5*/
6
7#include <stddef.h>
8
9#define ldump_c
10#define LUA_CORE
11
12#include "lua.h"
13
14#include "lobject.h"
15#include "lstate.h"
16#include "lundump.h"
17
18typedef struct {
19 lua_State* L;
20 lua_Writer writer;
21 void* data;
22 int strip;
23 int status;
24} DumpState;
25
26#define DumpMem(b,n,size,D)   DumpBlock(b,(n)*(size),D)
27#define DumpVar(x,D)      DumpMem(&x,1,sizeof(x),D)
28
29static void DumpBlock(const void* b, size_t size, DumpState* D)
30{
31 if (D->status==0)
32 {
33  lua_unlock(D->L);
34  D->status=(*D->writer)(D->L,b,size,D->data);
35  lua_lock(D->L);
36 }
37}
38
39static void DumpChar(int y, DumpState* D)
40{
41 char x=(char)y;
42 DumpVar(x,D);
43}
44
45static void DumpInt(int x, DumpState* D)
46{
47 DumpVar(x,D);
48}
49
50static void DumpNumber(lua_Number x, DumpState* D)
51{
52 DumpVar(x,D);
53}
54
55static void DumpVector(const void* b, int n, size_t size, DumpState* D)
56{
57 DumpInt(n,D);
58 DumpMem(b,n,size,D);
59}
60
61static void DumpString(const TString* s, DumpState* D)
62{
63 if (s==NULL)
64 {
65  size_t size=0;
66  DumpVar(size,D);
67 }
68 else
69 {
70  size_t size=s->tsv.len+1;      /* include trailing '\0' */
71  DumpVar(size,D);
72  DumpBlock(getstr(s),size*sizeof(char),D);
73 }
74}
75
76#define DumpCode(f,D)    DumpVector(f->code,f->sizecode,sizeof(Instruction),D)
77
78static void DumpFunction(const Proto* f, DumpState* D);
79
80static void DumpConstants(const Proto* f, DumpState* D)
81{
82 int i,n=f->sizek;
83 DumpInt(n,D);
84 for (i=0; i<n; i++)
85 {
86  const TValue* o=&f->k[i];
87  DumpChar(ttypenv(o),D);
88  switch (ttypenv(o))
89  {
90   case LUA_TNIL:
91   break;
92   case LUA_TBOOLEAN:
93   DumpChar(bvalue(o),D);
94   break;
95   case LUA_TNUMBER:
96   DumpNumber(nvalue(o),D);
97   break;
98   case LUA_TSTRING:
99   DumpString(rawtsvalue(o),D);
100   break;
101    default: lua_assert(0);
102  }
103 }
104 n=f->sizep;
105 DumpInt(n,D);
106 for (i=0; i<n; i++) DumpFunction(f->p[i],D);
107}
108
109static void DumpUpvalues(const Proto* f, DumpState* D)
110{
111 int i,n=f->sizeupvalues;
112 DumpInt(n,D);
113 for (i=0; i<n; i++)
114 {
115  DumpChar(f->upvalues[i].instack,D);
116  DumpChar(f->upvalues[i].idx,D);
117 }
118}
119
120static void DumpDebug(const Proto* f, DumpState* D)
121{
122 int i,n;
123 DumpString((D->strip) ? NULL : f->source,D);
124 n= (D->strip) ? 0 : f->sizelineinfo;
125 DumpVector(f->lineinfo,n,sizeof(int),D);
126 n= (D->strip) ? 0 : f->sizelocvars;
127 DumpInt(n,D);
128 for (i=0; i<n; i++)
129 {
130  DumpString(f->locvars[i].varname,D);
131  DumpInt(f->locvars[i].startpc,D);
132  DumpInt(f->locvars[i].endpc,D);
133 }
134 n= (D->strip) ? 0 : f->sizeupvalues;
135 DumpInt(n,D);
136 for (i=0; i<n; i++) DumpString(f->upvalues[i].name,D);
137}
138
139static void DumpFunction(const Proto* f, DumpState* D)
140{
141 DumpInt(f->linedefined,D);
142 DumpInt(f->lastlinedefined,D);
143 DumpChar(f->numparams,D);
144 DumpChar(f->is_vararg,D);
145 DumpChar(f->maxstacksize,D);
146 DumpCode(f,D);
147 DumpConstants(f,D);
148 DumpUpvalues(f,D);
149 DumpDebug(f,D);
150}
151
152static void DumpHeader(DumpState* D)
153{
154 lu_byte h[LUAC_HEADERSIZE];
155 luaU_header(h);
156 DumpBlock(h,LUAC_HEADERSIZE,D);
157}
158
159/*
160** dump Lua function as precompiled chunk
161*/
162int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
163{
164 DumpState D;
165 D.L=L;
166 D.writer=w;
167 D.data=data;
168 D.strip=strip;
169 D.status=0;
170 DumpHeader(&D);
171 DumpFunction(f,&D);
172 return D.status;
173}
Property changes on: trunk/src/lib/lua/ldump.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lzio.h
r0r22721
1/*
2** $Id: lzio.h,v 1.26 2011/07/15 12:48:03 roberto Exp $
3** Buffered streams
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lzio_h
9#define lzio_h
10
11#include "lua.h"
12
13#include "lmem.h"
14
15
16#define EOZ   (-1)         /* end of stream */
17
18typedef struct Zio ZIO;
19
20#define zgetc(z)  (((z)->n--)>0 ?  cast_uchar(*(z)->p++) : luaZ_fill(z))
21
22
23typedef struct Mbuffer {
24  char *buffer;
25  size_t n;
26  size_t buffsize;
27} Mbuffer;
28
29#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
30
31#define luaZ_buffer(buff)   ((buff)->buffer)
32#define luaZ_sizebuffer(buff)   ((buff)->buffsize)
33#define luaZ_bufflen(buff)   ((buff)->n)
34
35#define luaZ_resetbuffer(buff) ((buff)->n = 0)
36
37
38#define luaZ_resizebuffer(L, buff, size) \
39   (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \
40   (buff)->buffsize = size)
41
42#define luaZ_freebuffer(L, buff)   luaZ_resizebuffer(L, buff, 0)
43
44
45LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
46LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
47                                        void *data);
48LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n);   /* read next n bytes */
49
50
51
52/* --------- Private Part ------------------ */
53
54struct Zio {
55  size_t n;         /* bytes still unread */
56  const char *p;      /* current position in buffer */
57  lua_Reader reader;      /* reader function */
58  void* data;         /* additional data */
59  lua_State *L;         /* Lua state (for reader) */
60};
61
62
63LUAI_FUNC int luaZ_fill (ZIO *z);
64
65#endif
Property changes on: trunk/src/lib/lua/lzio.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/ldo.h
r0r22721
1/*
2** $Id: ldo.h,v 2.20 2011/11/29 15:55:08 roberto Exp $
3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h
5*/
6
7#ifndef ldo_h
8#define ldo_h
9
10
11#include "lobject.h"
12#include "lstate.h"
13#include "lzio.h"
14
15
16#define luaD_checkstack(L,n)   if (L->stack_last - L->top <= (n)) \
17                luaD_growstack(L, n); else condmovestack(L);
18
19
20#define incr_top(L) {L->top++; luaD_checkstack(L,0);}
21
22#define savestack(L,p)      ((char *)(p) - (char *)L->stack)
23#define restorestack(L,n)   ((TValue *)((char *)L->stack + (n)))
24
25
26/* type of protected functions, to be ran by `runprotected' */
27typedef void (*Pfunc) (lua_State *L, void *ud);
28
29LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
30                                                  const char *mode);
31LUAI_FUNC void luaD_hook (lua_State *L, int event, int line);
32LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
33LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults,
34                                        int allowyield);
35LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
36                                        ptrdiff_t oldtop, ptrdiff_t ef);
37LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
38LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
39LUAI_FUNC void luaD_growstack (lua_State *L, int n);
40LUAI_FUNC void luaD_shrinkstack (lua_State *L);
41
42LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode);
43LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
44
45#endif
46
Property changes on: trunk/src/lib/lua/ldo.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lundump.c
r0r22721
1/*
2** $Id: lundump.c,v 2.22 2012/05/08 13:53:33 roberto Exp $
3** load precompiled Lua chunks
4** See Copyright Notice in lua.h
5*/
6
7#include <string.h>
8
9#define lundump_c
10#define LUA_CORE
11
12#include "lua.h"
13
14#include "ldebug.h"
15#include "ldo.h"
16#include "lfunc.h"
17#include "lmem.h"
18#include "lobject.h"
19#include "lstring.h"
20#include "lundump.h"
21#include "lzio.h"
22
23typedef struct {
24 lua_State* L;
25 ZIO* Z;
26 Mbuffer* b;
27 const char* name;
28} LoadState;
29
30static l_noret error(LoadState* S, const char* why)
31{
32 luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why);
33 luaD_throw(S->L,LUA_ERRSYNTAX);
34}
35
36#define LoadMem(S,b,n,size)   LoadBlock(S,b,(n)*(size))
37#define LoadByte(S)      (lu_byte)LoadChar(S)
38#define LoadVar(S,x)      LoadMem(S,&x,1,sizeof(x))
39#define LoadVector(S,b,n,size)   LoadMem(S,b,n,size)
40
41#if !defined(luai_verifycode)
42#define luai_verifycode(L,b,f)   /* empty */
43#endif
44
45static void LoadBlock(LoadState* S, void* b, size_t size)
46{
47 if (luaZ_read(S->Z,b,size)!=0) error(S,"truncated");
48}
49
50static int LoadChar(LoadState* S)
51{
52 char x;
53 LoadVar(S,x);
54 return x;
55}
56
57static int LoadInt(LoadState* S)
58{
59 int x;
60 LoadVar(S,x);
61 if (x<0) error(S,"corrupted");
62 return x;
63}
64
65static lua_Number LoadNumber(LoadState* S)
66{
67 lua_Number x;
68 LoadVar(S,x);
69 return x;
70}
71
72static TString* LoadString(LoadState* S)
73{
74 size_t size;
75 LoadVar(S,size);
76 if (size==0)
77  return NULL;
78 else
79 {
80  char* s=luaZ_openspace(S->L,S->b,size);
81  LoadBlock(S,s,size*sizeof(char));
82  return luaS_newlstr(S->L,s,size-1);      /* remove trailing '\0' */
83 }
84}
85
86static void LoadCode(LoadState* S, Proto* f)
87{
88 int n=LoadInt(S);
89 f->code=luaM_newvector(S->L,n,Instruction);
90 f->sizecode=n;
91 LoadVector(S,f->code,n,sizeof(Instruction));
92}
93
94static void LoadFunction(LoadState* S, Proto* f);
95
96static void LoadConstants(LoadState* S, Proto* f)
97{
98 int i,n;
99 n=LoadInt(S);
100 f->k=luaM_newvector(S->L,n,TValue);
101 f->sizek=n;
102 for (i=0; i<n; i++) setnilvalue(&f->k[i]);
103 for (i=0; i<n; i++)
104 {
105  TValue* o=&f->k[i];
106  int t=LoadChar(S);
107  switch (t)
108  {
109   case LUA_TNIL:
110   setnilvalue(o);
111   break;
112   case LUA_TBOOLEAN:
113   setbvalue(o,LoadChar(S));
114   break;
115   case LUA_TNUMBER:
116   setnvalue(o,LoadNumber(S));
117   break;
118   case LUA_TSTRING:
119   setsvalue2n(S->L,o,LoadString(S));
120   break;
121    default: lua_assert(0);
122  }
123 }
124 n=LoadInt(S);
125 f->p=luaM_newvector(S->L,n,Proto*);
126 f->sizep=n;
127 for (i=0; i<n; i++) f->p[i]=NULL;
128 for (i=0; i<n; i++)
129 {
130  f->p[i]=luaF_newproto(S->L);
131  LoadFunction(S,f->p[i]);
132 }
133}
134
135static void LoadUpvalues(LoadState* S, Proto* f)
136{
137 int i,n;
138 n=LoadInt(S);
139 f->upvalues=luaM_newvector(S->L,n,Upvaldesc);
140 f->sizeupvalues=n;
141 for (i=0; i<n; i++) f->upvalues[i].name=NULL;
142 for (i=0; i<n; i++)
143 {
144  f->upvalues[i].instack=LoadByte(S);
145  f->upvalues[i].idx=LoadByte(S);
146 }
147}
148
149static void LoadDebug(LoadState* S, Proto* f)
150{
151 int i,n;
152 f->source=LoadString(S);
153 n=LoadInt(S);
154 f->lineinfo=luaM_newvector(S->L,n,int);
155 f->sizelineinfo=n;
156 LoadVector(S,f->lineinfo,n,sizeof(int));
157 n=LoadInt(S);
158 f->locvars=luaM_newvector(S->L,n,LocVar);
159 f->sizelocvars=n;
160 for (i=0; i<n; i++) f->locvars[i].varname=NULL;
161 for (i=0; i<n; i++)
162 {
163  f->locvars[i].varname=LoadString(S);
164  f->locvars[i].startpc=LoadInt(S);
165  f->locvars[i].endpc=LoadInt(S);
166 }
167 n=LoadInt(S);
168 for (i=0; i<n; i++) f->upvalues[i].name=LoadString(S);
169}
170
171static void LoadFunction(LoadState* S, Proto* f)
172{
173 f->linedefined=LoadInt(S);
174 f->lastlinedefined=LoadInt(S);
175 f->numparams=LoadByte(S);
176 f->is_vararg=LoadByte(S);
177 f->maxstacksize=LoadByte(S);
178 LoadCode(S,f);
179 LoadConstants(S,f);
180 LoadUpvalues(S,f);
181 LoadDebug(S,f);
182}
183
184/* the code below must be consistent with the code in luaU_header */
185#define N0   LUAC_HEADERSIZE
186#define N1   (sizeof(LUA_SIGNATURE)-sizeof(char))
187#define N2   N1+2
188#define N3   N2+6
189
190static void LoadHeader(LoadState* S)
191{
192 lu_byte h[LUAC_HEADERSIZE];
193 lu_byte s[LUAC_HEADERSIZE];
194 luaU_header(h);
195 memcpy(s,h,sizeof(char));         /* first char already read */
196 LoadBlock(S,s+sizeof(char),LUAC_HEADERSIZE-sizeof(char));
197 if (memcmp(h,s,N0)==0) return;
198 if (memcmp(h,s,N1)!=0) error(S,"not a");
199 if (memcmp(h,s,N2)!=0) error(S,"version mismatch in");
200 if (memcmp(h,s,N3)!=0) error(S,"incompatible"); else error(S,"corrupted");
201}
202
203/*
204** load precompiled chunk
205*/
206Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
207{
208 LoadState S;
209 Closure* cl;
210 if (*name=='@' || *name=='=')
211  S.name=name+1;
212 else if (*name==LUA_SIGNATURE[0])
213  S.name="binary string";
214 else
215  S.name=name;
216 S.L=L;
217 S.Z=Z;
218 S.b=buff;
219 LoadHeader(&S);
220 cl=luaF_newLclosure(L,1);
221 setclLvalue(L,L->top,cl); incr_top(L);
222 cl->l.p=luaF_newproto(L);
223 LoadFunction(&S,cl->l.p);
224 if (cl->l.p->sizeupvalues != 1)
225 {
226  Proto* p=cl->l.p;
227  cl=luaF_newLclosure(L,cl->l.p->sizeupvalues);
228  cl->l.p=p;
229  setclLvalue(L,L->top-1,cl);
230 }
231 luai_verifycode(L,buff,cl->l.p);
232 return cl;
233}
234
235#define MYINT(s)   (s[0]-'0')
236#define VERSION      MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)
237#define FORMAT      0      /* this is the official format */
238
239/*
240* make header for precompiled chunks
241* if you change the code below be sure to update LoadHeader and FORMAT above
242* and LUAC_HEADERSIZE in lundump.h
243*/
244void luaU_header (lu_byte* h)
245{
246 int x=1;
247 memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-sizeof(char));
248 h+=sizeof(LUA_SIGNATURE)-sizeof(char);
249 *h++=cast_byte(VERSION);
250 *h++=cast_byte(FORMAT);
251 *h++=cast_byte(*(char*)&x);         /* endianness */
252 *h++=cast_byte(sizeof(int));
253 *h++=cast_byte(sizeof(size_t));
254 *h++=cast_byte(sizeof(Instruction));
255 *h++=cast_byte(sizeof(lua_Number));
256 *h++=cast_byte(((lua_Number)0.5)==0);      /* is lua_Number integral? */
257 memcpy(h,LUAC_TAIL,sizeof(LUAC_TAIL)-sizeof(char));
258}
Property changes on: trunk/src/lib/lua/lundump.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/lapi.c
r0r22721
1/*
2** $Id: lapi.c,v 2.171 2013/03/16 21:10:18 roberto Exp $
3** Lua API
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdarg.h>
9#include <string.h>
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
32const 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/* test for pseudo index */
44#define ispseudo(i)      ((i) <= LUA_REGISTRYINDEX)
45
46/* test for valid but not pseudo index */
47#define isstackindex(i, o)   (isvalid(o) && !ispseudo(i))
48
49#define api_checkvalidindex(L, o)  api_check(L, isvalid(o), "invalid index")
50
51#define api_checkstackindex(L, i, o)  \
52   api_check(L, isstackindex(i, o), "index not in the stack")
53
54
55static TValue *index2addr (lua_State *L, int idx) {
56  CallInfo *ci = L->ci;
57  if (idx > 0) {
58    TValue *o = ci->func + idx;
59    api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
60    if (o >= L->top) return NONVALIDVALUE;
61    else return o;
62  }
63  else if (!ispseudo(idx)) {  /* negative index */
64    api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
65    return L->top + idx;
66  }
67  else if (idx == LUA_REGISTRYINDEX)
68    return &G(L)->l_registry;
69  else {  /* upvalues */
70    idx = LUA_REGISTRYINDEX - idx;
71    api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
72    if (ttislcf(ci->func))  /* light C function? */
73      return NONVALIDVALUE;  /* it has no upvalues */
74    else {
75      CClosure *func = clCvalue(ci->func);
76      return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE;
77    }
78  }
79}
80
81
82/*
83** to be called by 'lua_checkstack' in protected mode, to grow stack
84** capturing memory errors
85*/
86static void growstack (lua_State *L, void *ud) {
87  int size = *(int *)ud;
88  luaD_growstack(L, size);
89}
90
91
92LUA_API int lua_checkstack (lua_State *L, int size) {
93  int res;
94  CallInfo *ci = L->ci;
95  lua_lock(L);
96  if (L->stack_last - L->top > size)  /* stack large enough? */
97    res = 1;  /* yes; check is OK */
98  else {  /* no; need to grow stack */
99    int inuse = cast_int(L->top - L->stack) + EXTRA_STACK;
100    if (inuse > LUAI_MAXSTACK - size)  /* can grow without overflow? */
101      res = 0;  /* no */
102    else  /* try to grow stack */
103      res = (luaD_rawrunprotected(L, &growstack, &size) == LUA_OK);
104  }
105  if (res && ci->top < L->top + size)
106    ci->top = L->top + size;  /* adjust frame top */
107  lua_unlock(L);
108  return res;
109}
110
111
112LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
113  int i;
114  if (from == to) return;
115  lua_lock(to);
116  api_checknelems(from, n);
117  api_check(from, G(from) == G(to), "moving among independent states");
118  api_check(from, to->ci->top - to->top >= n, "not enough elements to move");
119  from->top -= n;
120  for (i = 0; i < n; i++) {
121    setobj2s(to, to->top++, from->top + i);
122  }
123  lua_unlock(to);
124}
125
126
127LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
128  lua_CFunction old;
129  lua_lock(L);
130  old = G(L)->panic;
131  G(L)->panic = panicf;
132  lua_unlock(L);
133  return old;
134}
135
136
137LUA_API const lua_Number *lua_version (lua_State *L) {
138  static const lua_Number version = LUA_VERSION_NUM;
139  if (L == NULL) return &version;
140  else return G(L)->version;
141}
142
143
144
145/*
146** basic stack manipulation
147*/
148
149
150/*
151** convert an acceptable stack index into an absolute index
152*/
153LUA_API int lua_absindex (lua_State *L, int idx) {
154  return (idx > 0 || ispseudo(idx))
155         ? idx
156         : cast_int(L->top - L->ci->func + idx);
157}
158
159
160LUA_API int lua_gettop (lua_State *L) {
161  return cast_int(L->top - (L->ci->func + 1));
162}
163
164
165LUA_API void lua_settop (lua_State *L, int idx) {
166  StkId func = L->ci->func;
167  lua_lock(L);
168  if (idx >= 0) {
169    api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
170    while (L->top < (func + 1) + idx)
171      setnilvalue(L->top++);
172    L->top = (func + 1) + idx;
173  }
174  else {
175    api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
176    L->top += idx+1;  /* `subtract' index (index is negative) */
177  }
178  lua_unlock(L);
179}
180
181
182LUA_API void lua_remove (lua_State *L, int idx) {
183  StkId p;
184  lua_lock(L);
185  p = index2addr(L, idx);
186  api_checkstackindex(L, idx, p);
187  while (++p < L->top) setobjs2s(L, p-1, p);
188  L->top--;
189  lua_unlock(L);
190}
191
192
193LUA_API void lua_insert (lua_State *L, int idx) {
194  StkId p;
195  StkId q;
196  lua_lock(L);
197  p = index2addr(L, idx);
198  api_checkstackindex(L, idx, p);
199  for (q = L->top; q > p; q--)  /* use L->top as a temporary */
200    setobjs2s(L, q, q - 1);
201  setobjs2s(L, p, L->top);
202  lua_unlock(L);
203}
204
205
206static void moveto (lua_State *L, TValue *fr, int idx) {
207  TValue *to = index2addr(L, idx);
208  api_checkvalidindex(L, to);
209  setobj(L, to, fr);
210  if (idx < LUA_REGISTRYINDEX)  /* function upvalue? */
211    luaC_barrier(L, clCvalue(L->ci->func), fr);
212  /* LUA_REGISTRYINDEX does not need gc barrier
213     (collector revisits it before finishing collection) */
214}
215
216
217LUA_API void lua_replace (lua_State *L, int idx) {
218  lua_lock(L);
219  api_checknelems(L, 1);
220  moveto(L, L->top - 1, idx);
221  L->top--;
222  lua_unlock(L);
223}
224
225
226LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
227  TValue *fr;
228  lua_lock(L);
229  fr = index2addr(L, fromidx);
230  moveto(L, fr, toidx);
231  lua_unlock(L);
232}
233
234
235LUA_API void lua_pushvalue (lua_State *L, int idx) {
236  lua_lock(L);
237  setobj2s(L, L->top, index2addr(L, idx));
238  api_incr_top(L);
239  lua_unlock(L);
240}
241
242
243
244/*
245** access functions (stack -> C)
246*/
247
248
249LUA_API int lua_type (lua_State *L, int idx) {
250  StkId o = index2addr(L, idx);
251  return (isvalid(o) ? ttypenv(o) : LUA_TNONE);
252}
253
254
255LUA_API const char *lua_typename (lua_State *L, int t) {
256  UNUSED(L);
257  return ttypename(t);
258}
259
260
261LUA_API int lua_iscfunction (lua_State *L, int idx) {
262  StkId o = index2addr(L, idx);
263  return (ttislcf(o) || (ttisCclosure(o)));
264}
265
266
267LUA_API int lua_isnumber (lua_State *L, int idx) {
268  TValue n;
269  const TValue *o = index2addr(L, idx);
270  return tonumber(o, &n);
271}
272
273
274LUA_API int lua_isstring (lua_State *L, int idx) {
275  int t = lua_type(L, idx);
276  return (t == LUA_TSTRING || t == LUA_TNUMBER);
277}
278
279
280LUA_API int lua_isuserdata (lua_State *L, int idx) {
281  const TValue *o = index2addr(L, idx);
282  return (ttisuserdata(o) || ttislightuserdata(o));
283}
284
285
286LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
287  StkId o1 = index2addr(L, index1);
288  StkId o2 = index2addr(L, index2);
289  return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0;
290}
291
292
293LUA_API void lua_arith (lua_State *L, int op) {
294  StkId o1;  /* 1st operand */
295  StkId o2;  /* 2nd operand */
296  lua_lock(L);
297  if (op != LUA_OPUNM) /* all other operations expect two operands */
298    api_checknelems(L, 2);
299  else {  /* for unary minus, add fake 2nd operand */
300    api_checknelems(L, 1);
301    setobjs2s(L, L->top, L->top - 1);
302    L->top++;
303  }
304  o1 = L->top - 2;
305  o2 = L->top - 1;
306  if (ttisnumber(o1) && ttisnumber(o2)) {
307    setnvalue(o1, luaO_arith(op, nvalue(o1), nvalue(o2)));
308  }
309  else
310    luaV_arith(L, o1, o1, o2, cast(TMS, op - LUA_OPADD + TM_ADD));
311  L->top--;
312  lua_unlock(L);
313}
314
315
316LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
317  StkId o1, o2;
318  int i = 0;
319  lua_lock(L);  /* may call tag method */
320  o1 = index2addr(L, index1);
321  o2 = index2addr(L, index2);
322  if (isvalid(o1) && isvalid(o2)) {
323    switch (op) {
324      case LUA_OPEQ: i = equalobj(L, o1, o2); break;
325      case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
326      case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
327      default: api_check(L, 0, "invalid option");
328    }
329  }
330  lua_unlock(L);
331  return i;
332}
333
334
335LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum) {
336  TValue n;
337  const TValue *o = index2addr(L, idx);
338  if (tonumber(o, &n)) {
339    if (isnum) *isnum = 1;
340    return nvalue(o);
341  }
342  else {
343    if (isnum) *isnum = 0;
344    return 0;
345  }
346}
347
348
349LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) {
350  TValue n;
351  const TValue *o = index2addr(L, idx);
352  if (tonumber(o, &n)) {
353    lua_Integer res;
354    lua_Number num = nvalue(o);
355    lua_number2integer(res, num);
356    if (isnum) *isnum = 1;
357    return res;
358  }
359  else {
360    if (isnum) *isnum = 0;
361    return 0;
362  }
363}
364
365
366LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) {
367  TValue n;
368  const TValue *o = index2addr(L, idx);
369  if (tonumber(o, &n)) {
370    lua_Unsigned res;
371    lua_Number num = nvalue(o);
372    lua_number2unsigned(res, num);
373    if (isnum) *isnum = 1;
374    return res;
375  }
376  else {
377    if (isnum) *isnum = 0;
378    return 0;
379  }
380}
381
382
383LUA_API int lua_toboolean (lua_State *L, int idx) {
384  const TValue *o = index2addr(L, idx);
385  return !l_isfalse(o);
386}
387
388
389LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
390  StkId o = index2addr(L, idx);
391  if (!ttisstring(o)) {
392    lua_lock(L);  /* `luaV_tostring' may create a new string */
393    if (!luaV_tostring(L, o)) {  /* conversion failed? */
394      if (len != NULL) *len = 0;
395      lua_unlock(L);
396      return NULL;
397    }
398    luaC_checkGC(L);
399    o = index2addr(L, idx);  /* previous call may reallocate the stack */
400    lua_unlock(L);
401  }
402  if (len != NULL) *len = tsvalue(o)->len;
403  return svalue(o);
404}
405
406
407LUA_API size_t lua_rawlen (lua_State *L, int idx) {
408  StkId o = index2addr(L, idx);
409  switch (ttypenv(o)) {
410    case LUA_TSTRING: return tsvalue(o)->len;
411    case LUA_TUSERDATA: return uvalue(o)->len;
412    case LUA_TTABLE: return luaH_getn(hvalue(o));
413    default: return 0;
414  }
415}
416
417
418LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
419  StkId o = index2addr(L, idx);
420  if (ttislcf(o)) return fvalue(o);
421  else if (ttisCclosure(o))
422    return clCvalue(o)->f;
423  else return NULL;  /* not a C function */
424}
425
426
427LUA_API void *lua_touserdata (lua_State *L, int idx) {
428  StkId o = index2addr(L, idx);
429  switch (ttypenv(o)) {
430    case LUA_TUSERDATA: return (rawuvalue(o) + 1);
431    case LUA_TLIGHTUSERDATA: return pvalue(o);
432    default: return NULL;
433  }
434}
435
436
437LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
438  StkId o = index2addr(L, idx);
439  return (!ttisthread(o)) ? NULL : thvalue(o);
440}
441
442
443LUA_API const void *lua_topointer (lua_State *L, int idx) {
444  StkId o = index2addr(L, idx);
445  switch (ttype(o)) {
446    case LUA_TTABLE: return hvalue(o);
447    case LUA_TLCL: return clLvalue(o);
448    case LUA_TCCL: return clCvalue(o);
449    case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
450    case LUA_TTHREAD: return thvalue(o);
451    case LUA_TUSERDATA:
452    case LUA_TLIGHTUSERDATA:
453      return lua_touserdata(L, idx);
454    default: return NULL;
455  }
456}
457
458
459
460/*
461** push functions (C -> stack)
462*/
463
464
465LUA_API void lua_pushnil (lua_State *L) {
466  lua_lock(L);
467  setnilvalue(L->top);
468  api_incr_top(L);
469  lua_unlock(L);
470}
471
472
473LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
474  lua_lock(L);
475  setnvalue(L->top, n);
476  luai_checknum(L, L->top,
477    luaG_runerror(L, "C API - attempt to push a signaling NaN"));
478  api_incr_top(L);
479  lua_unlock(L);
480}
481
482
483LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
484  lua_lock(L);
485  setnvalue(L->top, cast_num(n));
486  api_incr_top(L);
487  lua_unlock(L);
488}
489
490
491LUA_API void lua_pushunsigned (lua_State *L, lua_Unsigned u) {
492  lua_Number n;
493  lua_lock(L);
494  n = lua_unsigned2number(u);
495  setnvalue(L->top, n);
496  api_incr_top(L);
497  lua_unlock(L);
498}
499
500
501LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
502  TString *ts;
503  lua_lock(L);
504  luaC_checkGC(L);
505  ts = luaS_newlstr(L, s, len);
506  setsvalue2s(L, L->top, ts);
507  api_incr_top(L);
508  lua_unlock(L);
509  return getstr(ts);
510}
511
512
513LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
514  if (s == NULL) {
515    lua_pushnil(L);
516    return NULL;
517  }
518  else {
519    TString *ts;
520    lua_lock(L);
521    luaC_checkGC(L);
522    ts = luaS_new(L, s);
523    setsvalue2s(L, L->top, ts);
524    api_incr_top(L);
525    lua_unlock(L);
526    return getstr(ts);
527  }
528}
529
530
531LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
532                                      va_list argp) {
533  const char *ret;
534  lua_lock(L);
535  luaC_checkGC(L);
536  ret = luaO_pushvfstring(L, fmt, argp);
537  lua_unlock(L);
538  return ret;
539}
540
541
542LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
543  const char *ret;
544  va_list argp;
545  lua_lock(L);
546  luaC_checkGC(L);
547  va_start(argp, fmt);
548  ret = luaO_pushvfstring(L, fmt, argp);
549  va_end(argp);
550  lua_unlock(L);
551  return ret;
552}
553
554
555LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
556  lua_lock(L);
557  if (n == 0) {
558    setfvalue(L->top, fn);
559  }
560  else {
561    Closure *cl;
562    api_checknelems(L, n);
563    api_check(L, n <= MAXUPVAL, "upvalue index too large");
564    luaC_checkGC(L);
565    cl = luaF_newCclosure(L, n);
566    cl->c.f = fn;
567    L->top -= n;
568    while (n--)
569      setobj2n(L, &cl->c.upvalue[n], L->top + n);
570    setclCvalue(L, L->top, cl);
571  }
572  api_incr_top(L);
573  lua_unlock(L);
574}
575
576
577LUA_API void lua_pushboolean (lua_State *L, int b) {
578  lua_lock(L);
579  setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
580  api_incr_top(L);
581  lua_unlock(L);
582}
583
584
585LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
586  lua_lock(L);
587  setpvalue(L->top, p);
588  api_incr_top(L);
589  lua_unlock(L);
590}
591
592
593LUA_API int lua_pushthread (lua_State *L) {
594  lua_lock(L);
595  setthvalue(L, L->top, L);
596  api_incr_top(L);
597  lua_unlock(L);
598  return (G(L)->mainthread == L);
599}
600
601
602
603/*
604** get functions (Lua -> stack)
605*/
606
607
608LUA_API void lua_getglobal (lua_State *L, const char *var) {
609  Table *reg = hvalue(&G(L)->l_registry);
610  const TValue *gt;  /* global table */
611  lua_lock(L);
612  gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
613  setsvalue2s(L, L->top++, luaS_new(L, var));
614  luaV_gettable(L, gt, L->top - 1, L->top - 1);
615  lua_unlock(L);
616}
617
618
619LUA_API void lua_gettable (lua_State *L, int idx) {
620  StkId t;
621  lua_lock(L);
622  t = index2addr(L, idx);
623  luaV_gettable(L, t, L->top - 1, L->top - 1);
624  lua_unlock(L);
625}
626
627
628LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
629  StkId t;
630  lua_lock(L);
631  t = index2addr(L, idx);
632  setsvalue2s(L, L->top, luaS_new(L, k));
633  api_incr_top(L);
634  luaV_gettable(L, t, L->top - 1, L->top - 1);
635  lua_unlock(L);
636}
637
638
639LUA_API void lua_rawget (lua_State *L, int idx) {
640  StkId t;
641  lua_lock(L);
642  t = index2addr(L, idx);
643  api_check(L, ttistable(t), "table expected");
644  setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
645  lua_unlock(L);
646}
647
648
649LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
650  StkId t;
651  lua_lock(L);
652  t = index2addr(L, idx);
653  api_check(L, ttistable(t), "table expected");
654  setobj2s(L, L->top, luaH_getint(hvalue(t), n));
655  api_incr_top(L);
656  lua_unlock(L);
657}
658
659
660LUA_API void lua_rawgetp (lua_State *L, int idx, const void *p) {
661  StkId t;
662  TValue k;
663  lua_lock(L);
664  t = index2addr(L, idx);
665  api_check(L, ttistable(t), "table expected");
666  setpvalue(&k, cast(void *, p));
667  setobj2s(L, L->top, luaH_get(hvalue(t), &k));
668  api_incr_top(L);
669  lua_unlock(L);
670}
671
672
673LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
674  Table *t;
675  lua_lock(L);
676  luaC_checkGC(L);
677  t = luaH_new(L);
678  sethvalue(L, L->top, t);
679  api_incr_top(L);
680  if (narray > 0 || nrec > 0)
681    luaH_resize(L, t, narray, nrec);
682  lua_unlock(L);
683}
684
685
686LUA_API int lua_getmetatable (lua_State *L, int objindex) {
687  const TValue *obj;
688  Table *mt = NULL;
689  int res;
690  lua_lock(L);
691  obj = index2addr(L, objindex);
692  switch (ttypenv(obj)) {
693    case LUA_TTABLE:
694      mt = hvalue(obj)->metatable;
695      break;
696    case LUA_TUSERDATA:
697      mt = uvalue(obj)->metatable;
698      break;
699    default:
700      mt = G(L)->mt[ttypenv(obj)];
701      break;
702  }
703  if (mt == NULL)
704    res = 0;
705  else {
706    sethvalue(L, L->top, mt);
707    api_incr_top(L);
708    res = 1;
709  }
710  lua_unlock(L);
711  return res;
712}
713
714
715LUA_API void lua_getuservalue (lua_State *L, int idx) {
716  StkId o;
717  lua_lock(L);
718  o = index2addr(L, idx);
719  api_check(L, ttisuserdata(o), "userdata expected");
720  if (uvalue(o)->env) {
721    sethvalue(L, L->top, uvalue(o)->env);
722  } else
723    setnilvalue(L->top);
724  api_incr_top(L);
725  lua_unlock(L);
726}
727
728
729/*
730** set functions (stack -> Lua)
731*/
732
733
734LUA_API void lua_setglobal (lua_State *L, const char *var) {
735  Table *reg = hvalue(&G(L)->l_registry);
736  const TValue *gt;  /* global table */
737  lua_lock(L);
738  api_checknelems(L, 1);
739  gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
740  setsvalue2s(L, L->top++, luaS_new(L, var));
741  luaV_settable(L, gt, L->top - 1, L->top - 2);
742  L->top -= 2;  /* pop value and key */
743  lua_unlock(L);
744}
745
746
747LUA_API void lua_settable (lua_State *L, int idx) {
748  StkId t;
749  lua_lock(L);
750  api_checknelems(L, 2);
751  t = index2addr(L, idx);
752  luaV_settable(L, t, L->top - 2, L->top - 1);
753  L->top -= 2;  /* pop index and value */
754  lua_unlock(L);
755}
756
757
758LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
759  StkId t;
760  lua_lock(L);
761  api_checknelems(L, 1);
762  t = index2addr(L, idx);
763  setsvalue2s(L, L->top++, luaS_new(L, k));
764  luaV_settable(L, t, L->top - 1, L->top - 2);
765  L->top -= 2;  /* pop value and key */
766  lua_unlock(L);
767}
768
769
770LUA_API void lua_rawset (lua_State *L, int idx) {
771  StkId t;
772  lua_lock(L);
773  api_checknelems(L, 2);
774  t = index2addr(L, idx);
775  api_check(L, ttistable(t), "table expected");
776  setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
777  invalidateTMcache(hvalue(t));
778  luaC_barrierback(L, gcvalue(t), L->top-1);
779  L->top -= 2;
780  lua_unlock(L);
781}
782
783
784LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
785  StkId t;
786  lua_lock(L);
787  api_checknelems(L, 1);
788  t = index2addr(L, idx);
789  api_check(L, ttistable(t), "table expected");
790  luaH_setint(L, hvalue(t), n, L->top - 1);
791  luaC_barrierback(L, gcvalue(t), L->top-1);
792  L->top--;
793  lua_unlock(L);
794}
795
796
797LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
798  StkId t;
799  TValue k;
800  lua_lock(L);
801  api_checknelems(L, 1);
802  t = index2addr(L, idx);
803  api_check(L, ttistable(t), "table expected");
804  setpvalue(&k, cast(void *, p));
805  setobj2t(L, luaH_set(L, hvalue(t), &k), L->top - 1);
806  luaC_barrierback(L, gcvalue(t), L->top - 1);
807  L->top--;
808  lua_unlock(L);
809}
810
811
812LUA_API int lua_setmetatable (lua_State *L, int objindex) {
813  TValue *obj;
814  Table *mt;
815  lua_lock(L);
816  api_checknelems(L, 1);
817  obj = index2addr(L, objindex);
818  if (ttisnil(L->top - 1))
819    mt = NULL;
820  else {
821    api_check(L, ttistable(L->top - 1), "table expected");
822    mt = hvalue(L->top - 1);
823  }
824  switch (ttypenv(obj)) {
825    case LUA_TTABLE: {
826      hvalue(obj)->metatable = mt;
827      if (mt) {
828        luaC_objbarrierback(L, gcvalue(obj), mt);
829        luaC_checkfinalizer(L, gcvalue(obj), mt);
830      }
831      break;
832    }
833    case LUA_TUSERDATA: {
834      uvalue(obj)->metatable = mt;
835      if (mt) {
836        luaC_objbarrier(L, rawuvalue(obj), mt);
837        luaC_checkfinalizer(L, gcvalue(obj), mt);
838      }
839      break;
840    }
841    default: {
842      G(L)->mt[ttypenv(obj)] = mt;
843      break;
844    }
845  }
846  L->top--;
847  lua_unlock(L);
848  return 1;
849}
850
851
852LUA_API void lua_setuservalue (lua_State *L, int idx) {
853  StkId o;
854  lua_lock(L);
855  api_checknelems(L, 1);
856  o = index2addr(L, idx);
857  api_check(L, ttisuserdata(o), "userdata expected");
858  if (ttisnil(L->top - 1))
859    uvalue(o)->env = NULL;
860  else {
861    api_check(L, ttistable(L->top - 1), "table expected");
862    uvalue(o)->env = hvalue(L->top - 1);
863    luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
864  }
865  L->top--;
866  lua_unlock(L);
867}
868
869
870/*
871** `load' and `call' functions (run Lua code)
872*/
873
874
875#define checkresults(L,na,nr) \
876     api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
877   "results from function overflow current stack size")
878
879
880LUA_API int lua_getctx (lua_State *L, int *ctx) {
881  if (L->ci->callstatus & CIST_YIELDED) {
882    if (ctx) *ctx = L->ci->u.c.ctx;
883    return L->ci->u.c.status;
884  }
885  else return LUA_OK;
886}
887
888
889LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx,
890                        lua_CFunction k) {
891  StkId func;
892  lua_lock(L);
893  api_check(L, k == NULL || !isLua(L->ci),
894    "cannot use continuations inside hooks");
895  api_checknelems(L, nargs+1);
896  api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
897  checkresults(L, nargs, nresults);
898  func = L->top - (nargs+1);
899  if (k != NULL && L->nny == 0) {  /* need to prepare continuation? */
900    L->ci->u.c.k = k;  /* save continuation */
901    L->ci->u.c.ctx = ctx;  /* save context */
902    luaD_call(L, func, nresults, 1);  /* do the call */
903  }
904  else  /* no continuation or no yieldable */
905    luaD_call(L, func, nresults, 0);  /* just do the call */
906  adjustresults(L, nresults);
907  lua_unlock(L);
908}
909
910
911
912/*
913** Execute a protected call.
914*/
915struct CallS {  /* data to `f_call' */
916  StkId func;
917  int nresults;
918};
919
920
921static void f_call (lua_State *L, void *ud) {
922  struct CallS *c = cast(struct CallS *, ud);
923  luaD_call(L, c->func, c->nresults, 0);
924}
925
926
927
928LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
929                        int ctx, lua_CFunction k) {
930  struct CallS c;
931  int status;
932  ptrdiff_t func;
933  lua_lock(L);
934  api_check(L, k == NULL || !isLua(L->ci),
935    "cannot use continuations inside hooks");
936  api_checknelems(L, nargs+1);
937  api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
938  checkresults(L, nargs, nresults);
939  if (errfunc == 0)
940    func = 0;
941  else {
942    StkId o = index2addr(L, errfunc);
943    api_checkstackindex(L, errfunc, o);
944    func = savestack(L, o);
945  }
946  c.func = L->top - (nargs+1);  /* function to be called */
947  if (k == NULL || L->nny > 0) {  /* no continuation or no yieldable? */
948    c.nresults = nresults;  /* do a 'conventional' protected call */
949    status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
950  }
951  else {  /* prepare continuation (call is already protected by 'resume') */
952    CallInfo *ci = L->ci;
953    ci->u.c.k = k;  /* save continuation */
954    ci->u.c.ctx = ctx;  /* save context */
955    /* save information for error recovery */
956    ci->extra = savestack(L, c.func);
957    ci->u.c.old_allowhook = L->allowhook;
958    ci->u.c.old_errfunc = L->errfunc;
959    L->errfunc = func;
960    /* mark that function may do error recovery */
961    ci->callstatus |= CIST_YPCALL;
962    luaD_call(L, c.func, nresults, 1);  /* do the call */
963    ci->callstatus &= ~CIST_YPCALL;
964    L->errfunc = ci->u.c.old_errfunc;
965    status = LUA_OK;  /* if it is here, there were no errors */
966  }
967  adjustresults(L, nresults);
968  lua_unlock(L);
969  return status;
970}
971
972
973LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
974                      const char *chunkname, const char *mode) {
975  ZIO z;
976  int status;
977  lua_lock(L);
978  if (!chunkname) chunkname = "?";
979  luaZ_init(L, &z, reader, data);
980  status = luaD_protectedparser(L, &z, chunkname, mode);
981  if (status == LUA_OK) {  /* no errors? */
982    LClosure *f = clLvalue(L->top - 1);  /* get newly created function */
983    if (f->nupvalues == 1) {  /* does it have one upvalue? */
984      /* get global table from registry */
985      Table *reg = hvalue(&G(L)->l_registry);
986      const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
987      /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
988      setobj(L, f->upvals[0]->v, gt);
989      luaC_barrier(L, f->upvals[0], gt);
990    }
991  }
992  lua_unlock(L);
993  return status;
994}
995
996
997LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
998  int status;
999  TValue *o;
1000  lua_lock(L);
1001  api_checknelems(L, 1);
1002  o = L->top - 1;
1003  if (isLfunction(o))
1004    status = luaU_dump(L, getproto(o), writer, data, 0);
1005  else
1006    status = 1;
1007  lua_unlock(L);
1008  return status;
1009}
1010
1011
1012LUA_API int lua_status (lua_State *L) {
1013  return L->status;
1014}
1015
1016
1017/*
1018** Garbage-collection function
1019*/
1020
1021LUA_API int lua_gc (lua_State *L, int what, int data) {
1022  int res = 0;
1023  global_State *g;
1024  lua_lock(L);
1025  g = G(L);
1026  switch (what) {
1027    case LUA_GCSTOP: {
1028      g->gcrunning = 0;
1029      break;
1030    }
1031    case LUA_GCRESTART: {
1032      luaE_setdebt(g, 0);
1033      g->gcrunning = 1;
1034      break;
1035    }
1036    case LUA_GCCOLLECT: {
1037      luaC_fullgc(L, 0);
1038      break;
1039    }
1040    case LUA_GCCOUNT: {
1041      /* GC values are expressed in Kbytes: #bytes/2^10 */
1042      res = cast_int(gettotalbytes(g) >> 10);
1043      break;
1044    }
1045    case LUA_GCCOUNTB: {
1046      res = cast_int(gettotalbytes(g) & 0x3ff);
1047      break;
1048    }
1049    case LUA_GCSTEP: {
1050      if (g->gckind == KGC_GEN) {  /* generational mode? */
1051        res = (g->GCestimate == 0);  /* true if it will do major collection */
1052        luaC_forcestep(L);  /* do a single step */
1053      }
1054      else {
1055       lu_mem debt = cast(lu_mem, data) * 1024 - GCSTEPSIZE;
1056       if (g->gcrunning)
1057         debt += g->GCdebt;  /* include current debt */
1058       luaE_setdebt(g, debt);
1059       luaC_forcestep(L);
1060       if (g->gcstate == GCSpause)  /* end of cycle? */
1061         res = 1;  /* signal it */
1062      }
1063      break;
1064    }
1065    case LUA_GCSETPAUSE: {
1066      res = g->gcpause;
1067      g->gcpause = data;
1068      break;
1069    }
1070    case LUA_GCSETMAJORINC: {
1071      res = g->gcmajorinc;
1072      g->gcmajorinc = data;
1073      break;
1074    }
1075    case LUA_GCSETSTEPMUL: {
1076      res = g->gcstepmul;
1077      g->gcstepmul = data;
1078      break;
1079    }
1080    case LUA_GCISRUNNING: {
1081      res = g->gcrunning;
1082      break;
1083    }
1084    case LUA_GCGEN: {  /* change collector to generational mode */
1085      luaC_changemode(L, KGC_GEN);
1086      break;
1087    }
1088    case LUA_GCINC: {  /* change collector to incremental mode */
1089      luaC_changemode(L, KGC_NORMAL);
1090      break;
1091    }
1092    default: res = -1;  /* invalid option */
1093  }
1094  lua_unlock(L);
1095  return res;
1096}
1097
1098
1099
1100/*
1101** miscellaneous functions
1102*/
1103
1104
1105LUA_API int lua_error (lua_State *L) {
1106  lua_lock(L);
1107  api_checknelems(L, 1);
1108  luaG_errormsg(L);
1109  /* code unreachable; will unlock when control actually leaves the kernel */
1110  return 0;  /* to avoid warnings */
1111}
1112
1113
1114LUA_API int lua_next (lua_State *L, int idx) {
1115  StkId t;
1116  int more;
1117  lua_lock(L);
1118  t = index2addr(L, idx);
1119  api_check(L, ttistable(t), "table expected");
1120  more = luaH_next(L, hvalue(t), L->top - 1);
1121  if (more) {
1122    api_incr_top(L);
1123  }
1124  else  /* no more elements */
1125    L->top -= 1;  /* remove key */
1126  lua_unlock(L);
1127  return more;
1128}
1129
1130
1131LUA_API void lua_concat (lua_State *L, int n) {
1132  lua_lock(L);
1133  api_checknelems(L, n);
1134  if (n >= 2) {
1135    luaC_checkGC(L);
1136    luaV_concat(L, n);
1137  }
1138  else if (n == 0) {  /* push empty string */
1139    setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
1140    api_incr_top(L);
1141  }
1142  /* else n == 1; nothing to do */
1143  lua_unlock(L);
1144}
1145
1146
1147LUA_API void lua_len (lua_State *L, int idx) {
1148  StkId t;
1149  lua_lock(L);
1150  t = index2addr(L, idx);
1151  luaV_objlen(L, L->top, t);
1152  api_incr_top(L);
1153  lua_unlock(L);
1154}
1155
1156
1157LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
1158  lua_Alloc f;
1159  lua_lock(L);
1160  if (ud) *ud = G(L)->ud;
1161  f = G(L)->frealloc;
1162  lua_unlock(L);
1163  return f;
1164}
1165
1166
1167LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
1168  lua_lock(L);
1169  G(L)->ud = ud;
1170  G(L)->frealloc = f;
1171  lua_unlock(L);
1172}
1173
1174
1175LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
1176  Udata *u;
1177  lua_lock(L);
1178  luaC_checkGC(L);
1179  u = luaS_newudata(L, size, NULL);
1180  setuvalue(L, L->top, u);
1181  api_incr_top(L);
1182  lua_unlock(L);
1183  return u + 1;
1184}
1185
1186
1187
1188static const char *aux_upvalue (StkId fi, int n, TValue **val,
1189                                GCObject **owner) {
1190  switch (ttype(fi)) {
1191    case LUA_TCCL: {  /* C closure */
1192      CClosure *f = clCvalue(fi);
1193      if (!(1 <= n && n <= f->nupvalues)) return NULL;
1194      *val = &f->upvalue[n-1];
1195      if (owner) *owner = obj2gco(f);
1196      return "";
1197    }
1198    case LUA_TLCL: {  /* Lua closure */
1199      LClosure *f = clLvalue(fi);
1200      TString *name;
1201      Proto *p = f->p;
1202      if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
1203      *val = f->upvals[n-1]->v;
1204      if (owner) *owner = obj2gco(f->upvals[n - 1]);
1205      name = p->upvalues[n-1].name;
1206      return (name == NULL) ? "" : getstr(name);
1207    }
1208    default: return NULL;  /* not a closure */
1209  }
1210}
1211
1212
1213LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
1214  const char *name;
1215  TValue *val = NULL;  /* to avoid warnings */
1216  lua_lock(L);
1217  name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL);
1218  if (name) {
1219    setobj2s(L, L->top, val);
1220    api_incr_top(L);
1221  }
1222  lua_unlock(L);
1223  return name;
1224}
1225
1226
1227LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
1228  const char *name;
1229  TValue *val = NULL;  /* to avoid warnings */
1230  GCObject *owner = NULL;  /* to avoid warnings */
1231  StkId fi;
1232  lua_lock(L);
1233  fi = index2addr(L, funcindex);
1234  api_checknelems(L, 1);
1235  name = aux_upvalue(fi, n, &val, &owner);
1236  if (name) {
1237    L->top--;
1238    setobj(L, val, L->top);
1239    luaC_barrier(L, owner, L->top);
1240  }
1241  lua_unlock(L);
1242  return name;
1243}
1244
1245
1246static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
1247  LClosure *f;
1248  StkId fi = index2addr(L, fidx);
1249  api_check(L, ttisLclosure(fi), "Lua function expected");
1250  f = clLvalue(fi);
1251  api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
1252  if (pf) *pf = f;
1253  return &f->upvals[n - 1];  /* get its upvalue pointer */
1254}
1255
1256
1257LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
1258  StkId fi = index2addr(L, fidx);
1259  switch (ttype(fi)) {
1260    case LUA_TLCL: {  /* lua closure */
1261      return *getupvalref(L, fidx, n, NULL);
1262    }
1263    case LUA_TCCL: {  /* C closure */
1264      CClosure *f = clCvalue(fi);
1265      api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index");
1266      return &f->upvalue[n - 1];
1267    }
1268    default: {
1269      api_check(L, 0, "closure expected");
1270      return NULL;
1271    }
1272  }
1273}
1274
1275
1276LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
1277                                            int fidx2, int n2) {
1278  LClosure *f1;
1279  UpVal **up1 = getupvalref(L, fidx1, n1, &f1);
1280  UpVal **up2 = getupvalref(L, fidx2, n2, NULL);
1281  *up1 = *up2;
1282  luaC_objbarrier(L, f1, *up2);
1283}
1284
Property changes on: trunk/src/lib/lua/lapi.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/lua.hpp
r0r22721
1// lua.hpp
2// Lua header files for C++
3// <<extern "C">> not supplied automatically because Lua also compiles as C++
4
5extern "C" {
6#include "lua.h"
7#include "lualib.h"
8#include "lauxlib.h"
9}
Property changes on: trunk/src/lib/lua/lua.hpp
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/lundump.h
r0r22721
1/*
2** $Id: lundump.h,v 1.39 2012/05/08 13:53:33 roberto Exp $
3** load precompiled Lua chunks
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lundump_h
8#define lundump_h
9
10#include "lobject.h"
11#include "lzio.h"
12
13/* load one chunk; from lundump.c */
14LUAI_FUNC Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
15
16/* make header; from lundump.c */
17LUAI_FUNC void luaU_header (lu_byte* h);
18
19/* dump one chunk; from ldump.c */
20LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
21
22/* data to catch conversion errors */
23#define LUAC_TAIL      "\x19\x93\r\n\x1a\n"
24
25/* size in bytes of header of binary files */
26#define LUAC_HEADERSIZE      (sizeof(LUA_SIGNATURE)-sizeof(char)+2+6+sizeof(LUAC_TAIL)-sizeof(char))
27
28#endif
Property changes on: trunk/src/lib/lua/lundump.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lapi.h
r0r22721
1/*
2** $Id: lapi.h,v 2.7 2009/11/27 15:37:59 roberto Exp $
3** Auxiliary functions from Lua API
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lapi_h
8#define lapi_h
9
10
11#include "llimits.h"
12#include "lstate.h"
13
14#define api_incr_top(L)   {L->top++; api_check(L, L->top <= L->ci->top, \
15            "stack overflow");}
16
17#define adjustresults(L,nres) \
18    { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
19
20#define api_checknelems(L,n)   api_check(L, (n) < (L->top - L->ci->func), \
21              "not enough elements in the stack")
22
23
24#endif
Property changes on: trunk/src/lib/lua/lapi.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/ltm.c
r0r22721
1/*
2** $Id: ltm.c,v 2.14 2011/06/02 19:31:40 roberto Exp $
3** Tag methods
4** See Copyright Notice in lua.h
5*/
6
7
8#include <string.h>
9
10#define ltm_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "lobject.h"
16#include "lstate.h"
17#include "lstring.h"
18#include "ltable.h"
19#include "ltm.h"
20
21
22static const char udatatypename[] = "userdata";
23
24LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = {
25  "no value",
26  "nil", "boolean", udatatypename, "number",
27  "string", "table", "function", udatatypename, "thread",
28  "proto", "upval"  /* these last two cases are used for tests only */
29};
30
31
32void luaT_init (lua_State *L) {
33  static const char *const luaT_eventname[] = {  /* ORDER TM */
34    "__index", "__newindex",
35    "__gc", "__mode", "__len", "__eq",
36    "__add", "__sub", "__mul", "__div", "__mod",
37    "__pow", "__unm", "__lt", "__le",
38    "__concat", "__call"
39  };
40  int i;
41  for (i=0; i<TM_N; i++) {
42    G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
43    luaS_fix(G(L)->tmname[i]);  /* never collect these names */
44  }
45}
46
47
48/*
49** function to be used with macro "fasttm": optimized for absence of
50** tag methods
51*/
52const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
53  const TValue *tm = luaH_getstr(events, ename);
54  lua_assert(event <= TM_EQ);
55  if (ttisnil(tm)) {  /* no tag method? */
56    events->flags |= cast_byte(1u<<event);  /* cache this fact */
57    return NULL;
58  }
59  else return tm;
60}
61
62
63const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
64  Table *mt;
65  switch (ttypenv(o)) {
66    case LUA_TTABLE:
67      mt = hvalue(o)->metatable;
68      break;
69    case LUA_TUSERDATA:
70      mt = uvalue(o)->metatable;
71      break;
72    default:
73      mt = G(L)->mt[ttypenv(o)];
74  }
75  return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
76}
77
Property changes on: trunk/src/lib/lua/ltm.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/lvm.c
r0r22721
1/*
2** $Id: lvm.c,v 2.155 2013/03/16 21:10:18 roberto Exp $
3** Lua virtual machine
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#define lvm_c
13#define LUA_CORE
14
15#include "lua.h"
16
17#include "ldebug.h"
18#include "ldo.h"
19#include "lfunc.h"
20#include "lgc.h"
21#include "lobject.h"
22#include "lopcodes.h"
23#include "lstate.h"
24#include "lstring.h"
25#include "ltable.h"
26#include "ltm.h"
27#include "lvm.h"
28
29
30
31/* limit for table tag-method chains (to avoid loops) */
32#define MAXTAGLOOP   100
33
34
35const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
36  lua_Number num;
37  if (ttisnumber(obj)) return obj;
38  if (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, &num)) {
39    setnvalue(n, num);
40    return n;
41  }
42  else
43    return NULL;
44}
45
46
47int luaV_tostring (lua_State *L, StkId obj) {
48  if (!ttisnumber(obj))
49    return 0;
50  else {
51    char s[LUAI_MAXNUMBER2STR];
52    lua_Number n = nvalue(obj);
53    int l = lua_number2str(s, n);
54    setsvalue2s(L, obj, luaS_newlstr(L, s, l));
55    return 1;
56  }
57}
58
59
60static void traceexec (lua_State *L) {
61  CallInfo *ci = L->ci;
62  lu_byte mask = L->hookmask;
63  int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0);
64  if (counthook)
65    resethookcount(L);  /* reset count */
66  if (ci->callstatus & CIST_HOOKYIELD) {  /* called hook last time? */
67    ci->callstatus &= ~CIST_HOOKYIELD;  /* erase mark */
68    return;  /* do not call hook again (VM yielded, so it did not move) */
69  }
70  if (counthook)
71    luaD_hook(L, LUA_HOOKCOUNT, -1);  /* call count hook */
72  if (mask & LUA_MASKLINE) {
73    Proto *p = ci_func(ci)->p;
74    int npc = pcRel(ci->u.l.savedpc, p);
75    int newline = getfuncline(p, npc);
76    if (npc == 0 ||  /* call linehook when enter a new function, */
77        ci->u.l.savedpc <= L->oldpc ||  /* when jump back (loop), or when */
78        newline != getfuncline(p, pcRel(L->oldpc, p)))  /* enter a new line */
79      luaD_hook(L, LUA_HOOKLINE, newline);  /* call line hook */
80  }
81  L->oldpc = ci->u.l.savedpc;
82  if (L->status == LUA_YIELD) {  /* did hook yield? */
83    if (counthook)
84      L->hookcount = 1;  /* undo decrement to zero */
85    ci->u.l.savedpc--;  /* undo increment (resume will increment it again) */
86    ci->callstatus |= CIST_HOOKYIELD;  /* mark that it yielded */
87    ci->func = L->top - 1;  /* protect stack below results */
88    luaD_throw(L, LUA_YIELD);
89  }
90}
91
92
93static void callTM (lua_State *L, const TValue *f, const TValue *p1,
94                    const TValue *p2, TValue *p3, int hasres) {
95  ptrdiff_t result = savestack(L, p3);
96  setobj2s(L, L->top++, f);  /* push function */
97  setobj2s(L, L->top++, p1);  /* 1st argument */
98  setobj2s(L, L->top++, p2);  /* 2nd argument */
99  if (!hasres)  /* no result? 'p3' is third argument */
100    setobj2s(L, L->top++, p3);  /* 3rd argument */
101  /* metamethod may yield only when called from Lua code */
102  luaD_call(L, L->top - (4 - hasres), hasres, isLua(L->ci));
103  if (hasres) {  /* if has result, move it to its place */
104    p3 = restorestack(L, result);
105    setobjs2s(L, p3, --L->top);
106  }
107}
108
109
110void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
111  int loop;
112  for (loop = 0; loop < MAXTAGLOOP; loop++) {
113    const TValue *tm;
114    if (ttistable(t)) {  /* `t' is a table? */
115      Table *h = hvalue(t);
116      const TValue *res = luaH_get(h, key); /* do a primitive get */
117      if (!ttisnil(res) ||  /* result is not nil? */
118          (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
119        setobj2s(L, val, res);
120        return;
121      }
122      /* else will try the tag method */
123    }
124    else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
125      luaG_typeerror(L, t, "index");
126    if (ttisfunction(tm)) {
127      callTM(L, tm, t, key, val, 1);
128      return;
129    }
130    t = tm;  /* else repeat with 'tm' */
131  }
132  luaG_runerror(L, "loop in gettable");
133}
134
135
136void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
137  int loop;
138  for (loop = 0; loop < MAXTAGLOOP; loop++) {
139    const TValue *tm;
140    if (ttistable(t)) {  /* `t' is a table? */
141      Table *h = hvalue(t);
142      TValue *oldval = cast(TValue *, luaH_get(h, key));
143      /* if previous value is not nil, there must be a previous entry
144         in the table; moreover, a metamethod has no relevance */
145      if (!ttisnil(oldval) ||
146         /* previous value is nil; must check the metamethod */
147         ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL &&
148         /* no metamethod; is there a previous entry in the table? */
149         (oldval != luaO_nilobject ||
150         /* no previous entry; must create one. (The next test is
151            always true; we only need the assignment.) */
152         (oldval = luaH_newkey(L, h, key), 1)))) {
153        /* no metamethod and (now) there is an entry with given key */
154        setobj2t(L, oldval, val);  /* assign new value to that entry */
155        invalidateTMcache(h);
156        luaC_barrierback(L, obj2gco(h), val);
157        return;
158      }
159      /* else will try the metamethod */
160    }
161    else  /* not a table; check metamethod */
162      if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
163        luaG_typeerror(L, t, "index");
164    /* there is a metamethod */
165    if (ttisfunction(tm)) {
166      callTM(L, tm, t, key, val, 0);
167      return;
168    }
169    t = tm;  /* else repeat with 'tm' */
170  }
171  luaG_runerror(L, "loop in settable");
172}
173
174
175static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
176                       StkId res, TMS event) {
177  const TValue *tm = luaT_gettmbyobj(L, p1, event);  /* try first operand */
178  if (ttisnil(tm))
179    tm = luaT_gettmbyobj(L, p2, event);  /* try second operand */
180  if (ttisnil(tm)) return 0;
181  callTM(L, tm, p1, p2, res, 1);
182  return 1;
183}
184
185
186static const TValue *get_equalTM (lua_State *L, Table *mt1, Table *mt2,
187                                  TMS event) {
188  const TValue *tm1 = fasttm(L, mt1, event);
189  const TValue *tm2;
190  if (tm1 == NULL) return NULL;  /* no metamethod */
191  if (mt1 == mt2) return tm1;  /* same metatables => same metamethods */
192  tm2 = fasttm(L, mt2, event);
193  if (tm2 == NULL) return NULL;  /* no metamethod */
194  if (luaV_rawequalobj(tm1, tm2))  /* same metamethods? */
195    return tm1;
196  return NULL;
197}
198
199
200static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
201                         TMS event) {
202  if (!call_binTM(L, p1, p2, L->top, event))
203    return -1;  /* no metamethod */
204  else
205    return !l_isfalse(L->top);
206}
207
208
209static int l_strcmp (const TString *ls, const TString *rs) {
210  const char *l = getstr(ls);
211  size_t ll = ls->tsv.len;
212  const char *r = getstr(rs);
213  size_t lr = rs->tsv.len;
214  for (;;) {
215    int temp = strcoll(l, r);
216    if (temp != 0) return temp;
217    else {  /* strings are equal up to a `\0' */
218      size_t len = strlen(l);  /* index of first `\0' in both strings */
219      if (len == lr)  /* r is finished? */
220        return (len == ll) ? 0 : 1;
221      else if (len == ll)  /* l is finished? */
222        return -1;  /* l is smaller than r (because r is not finished) */
223      /* both strings longer than `len'; go on comparing (after the `\0') */
224      len++;
225      l += len; ll -= len; r += len; lr -= len;
226    }
227  }
228}
229
230
231int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
232  int res;
233  if (ttisnumber(l) && ttisnumber(r))
234    return luai_numlt(L, nvalue(l), nvalue(r));
235  else if (ttisstring(l) && ttisstring(r))
236    return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
237  else if ((res = call_orderTM(L, l, r, TM_LT)) < 0)
238    luaG_ordererror(L, l, r);
239  return res;
240}
241
242
243int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
244  int res;
245  if (ttisnumber(l) && ttisnumber(r))
246    return luai_numle(L, nvalue(l), nvalue(r));
247  else if (ttisstring(l) && ttisstring(r))
248    return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
249  else if ((res = call_orderTM(L, l, r, TM_LE)) >= 0)  /* first try `le' */
250    return res;
251  else if ((res = call_orderTM(L, r, l, TM_LT)) < 0)  /* else try `lt' */
252    luaG_ordererror(L, l, r);
253  return !res;
254}
255
256
257/*
258** equality of Lua values. L == NULL means raw equality (no metamethods)
259*/
260int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2) {
261  const TValue *tm;
262  lua_assert(ttisequal(t1, t2));
263  switch (ttype(t1)) {
264    case LUA_TNIL: return 1;
265    case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
266    case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2);  /* true must be 1 !! */
267    case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
268    case LUA_TLCF: return fvalue(t1) == fvalue(t2);
269    case LUA_TSHRSTR: return eqshrstr(rawtsvalue(t1), rawtsvalue(t2));
270    case LUA_TLNGSTR: return luaS_eqlngstr(rawtsvalue(t1), rawtsvalue(t2));
271    case LUA_TUSERDATA: {
272      if (uvalue(t1) == uvalue(t2)) return 1;
273      else if (L == NULL) return 0;
274      tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ);
275      break;  /* will try TM */
276    }
277    case LUA_TTABLE: {
278      if (hvalue(t1) == hvalue(t2)) return 1;
279      else if (L == NULL) return 0;
280      tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
281      break;  /* will try TM */
282    }
283    default:
284      lua_assert(iscollectable(t1));
285      return gcvalue(t1) == gcvalue(t2);
286  }
287  if (tm == NULL) return 0;  /* no TM? */
288  callTM(L, tm, t1, t2, L->top, 1);  /* call TM */
289  return !l_isfalse(L->top);
290}
291
292
293void luaV_concat (lua_State *L, int total) {
294  lua_assert(total >= 2);
295  do {
296    StkId top = L->top;
297    int n = 2;  /* number of elements handled in this pass (at least 2) */
298    if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
299      if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
300        luaG_concaterror(L, top-2, top-1);
301    }
302    else if (tsvalue(top-1)->len == 0)  /* second operand is empty? */
303      (void)tostring(L, top - 2);  /* result is first operand */
304    else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) {
305      setobjs2s(L, top - 2, top - 1);  /* result is second op. */
306    }
307    else {
308      /* at least two non-empty string values; get as many as possible */
309      size_t tl = tsvalue(top-1)->len;
310      char *buffer;
311      int i;
312      /* collect total length */
313      for (i = 1; i < total && tostring(L, top-i-1); i++) {
314        size_t l = tsvalue(top-i-1)->len;
315        if (l >= (MAX_SIZET/sizeof(char)) - tl)
316          luaG_runerror(L, "string length overflow");
317        tl += l;
318      }
319      buffer = luaZ_openspace(L, &G(L)->buff, tl);
320      tl = 0;
321      n = i;
322      do {  /* concat all strings */
323        size_t l = tsvalue(top-i)->len;
324        memcpy(buffer+tl, svalue(top-i), l * sizeof(char));
325        tl += l;
326      } while (--i > 0);
327      setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
328    }
329    total -= n-1;  /* got 'n' strings to create 1 new */
330    L->top -= n-1;  /* popped 'n' strings and pushed one */
331  } while (total > 1);  /* repeat until only 1 result left */
332}
333
334
335void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
336  const TValue *tm;
337  switch (ttypenv(rb)) {
338    case LUA_TTABLE: {
339      Table *h = hvalue(rb);
340      tm = fasttm(L, h->metatable, TM_LEN);
341      if (tm) break;  /* metamethod? break switch to call it */
342      setnvalue(ra, cast_num(1.0*luaH_getn(h)));  /* else primitive len */
343      return;
344    }
345    case LUA_TSTRING: {
346      setnvalue(ra, cast_num(tsvalue(rb)->len));
347      return;
348    }
349    default: {  /* try metamethod */
350      tm = luaT_gettmbyobj(L, rb, TM_LEN);
351      if (ttisnil(tm))  /* no metamethod? */
352        luaG_typeerror(L, rb, "get length of");
353      break;
354    }
355  }
356  callTM(L, tm, rb, rb, ra, 1);
357}
358
359
360void luaV_arith (lua_State *L, StkId ra, const TValue *rb,
361                 const TValue *rc, TMS op) {
362  TValue tempb, tempc;
363  const TValue *b, *c;
364  if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
365      (c = luaV_tonumber(rc, &tempc)) != NULL) {
366    lua_Number res = luaO_arith(op - TM_ADD + LUA_OPADD, nvalue(b), nvalue(c));
367    setnvalue(ra, res);
368  }
369  else if (!call_binTM(L, rb, rc, ra, op))
370    luaG_aritherror(L, rb, rc);
371}
372
373
374/*
375** check whether cached closure in prototype 'p' may be reused, that is,
376** whether there is a cached closure with the same upvalues needed by
377** new closure to be created.
378*/
379static Closure *getcached (Proto *p, UpVal **encup, StkId base) {
380  Closure *c = p->cache;
381  if (c != NULL) {  /* is there a cached closure? */
382    int nup = p->sizeupvalues;
383    Upvaldesc *uv = p->upvalues;
384    int i;
385    for (i = 0; i < nup; i++) {  /* check whether it has right upvalues */
386      TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v;
387      if (c->l.upvals[i]->v != v)
388        return NULL;  /* wrong upvalue; cannot reuse closure */
389    }
390  }
391  return c;  /* return cached closure (or NULL if no cached closure) */
392}
393
394
395/*
396** create a new Lua closure, push it in the stack, and initialize
397** its upvalues. Note that the call to 'luaC_barrierproto' must come
398** before the assignment to 'p->cache', as the function needs the
399** original value of that field.
400*/
401static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
402                         StkId ra) {
403  int nup = p->sizeupvalues;
404  Upvaldesc *uv = p->upvalues;
405  int i;
406  Closure *ncl = luaF_newLclosure(L, nup);
407  ncl->l.p = p;
408  setclLvalue(L, ra, ncl);  /* anchor new closure in stack */
409  for (i = 0; i < nup; i++) {  /* fill in its upvalues */
410    if (uv[i].instack)  /* upvalue refers to local variable? */
411      ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx);
412    else  /* get upvalue from enclosing function */
413      ncl->l.upvals[i] = encup[uv[i].idx];
414  }
415  luaC_barrierproto(L, p, ncl);
416  p->cache = ncl;  /* save it on cache for reuse */
417}
418
419
420/*
421** finish execution of an opcode interrupted by an yield
422*/
423void luaV_finishOp (lua_State *L) {
424  CallInfo *ci = L->ci;
425  StkId base = ci->u.l.base;
426  Instruction inst = *(ci->u.l.savedpc - 1);  /* interrupted instruction */
427  OpCode op = GET_OPCODE(inst);
428  switch (op) {  /* finish its execution */
429    case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV:
430    case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN:
431    case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: {
432      setobjs2s(L, base + GETARG_A(inst), --L->top);
433      break;
434    }
435    case OP_LE: case OP_LT: case OP_EQ: {
436      int res = !l_isfalse(L->top - 1);
437      L->top--;
438      /* metamethod should not be called when operand is K */
439      lua_assert(!ISK(GETARG_B(inst)));
440      if (op == OP_LE &&  /* "<=" using "<" instead? */
441          ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE)))
442        res = !res;  /* invert result */
443      lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
444      if (res != GETARG_A(inst))  /* condition failed? */
445        ci->u.l.savedpc++;  /* skip jump instruction */
446      break;
447    }
448    case OP_CONCAT: {
449      StkId top = L->top - 1;  /* top when 'call_binTM' was called */
450      int b = GETARG_B(inst);      /* first element to concatenate */
451      int total = cast_int(top - 1 - (base + b));  /* yet to concatenate */
452      setobj2s(L, top - 2, top);  /* put TM result in proper position */
453      if (total > 1) {  /* are there elements to concat? */
454        L->top = top - 1;  /* top is one after last element (at top-2) */
455        luaV_concat(L, total);  /* concat them (may yield again) */
456      }
457      /* move final result to final position */
458      setobj2s(L, ci->u.l.base + GETARG_A(inst), L->top - 1);
459      L->top = ci->top;  /* restore top */
460      break;
461    }
462    case OP_TFORCALL: {
463      lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP);
464      L->top = ci->top;  /* correct top */
465      break;
466    }
467    case OP_CALL: {
468      if (GETARG_C(inst) - 1 >= 0)  /* nresults >= 0? */
469        L->top = ci->top;  /* adjust results */
470      break;
471    }
472    case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE:
473      break;
474    default: lua_assert(0);
475  }
476}
477
478
479
480/*
481** some macros for common tasks in `luaV_execute'
482*/
483
484#if !defined luai_runtimecheck
485#define luai_runtimecheck(L, c)      /* void */
486#endif
487
488
489#define RA(i)   (base+GETARG_A(i))
490/* to be used after possible stack reallocation */
491#define RB(i)   check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
492#define RC(i)   check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
493#define RKB(i)   check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
494   ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
495#define RKC(i)   check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
496   ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
497#define KBx(i)  \
498  (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++)))
499
500
501/* execute a jump instruction */
502#define dojump(ci,i,e) \
503  { int a = GETARG_A(i); \
504    if (a > 0) luaF_close(L, ci->u.l.base + a - 1); \
505    ci->u.l.savedpc += GETARG_sBx(i) + e; }
506
507/* for test instructions, execute the jump instruction that follows it */
508#define donextjump(ci)   { i = *ci->u.l.savedpc; dojump(ci, i, 1); }
509
510
511#define Protect(x)   { {x;}; base = ci->u.l.base; }
512
513#define checkGC(L,c)  \
514  Protect( luaC_condGC(L,{L->top = (c);  /* limit of live values */ \
515                          luaC_step(L); \
516                          L->top = ci->top;})  /* restore top */ \
517           luai_threadyield(L); )
518
519
520#define arith_op(op,tm) { \
521        TValue *rb = RKB(i); \
522        TValue *rc = RKC(i); \
523        if (ttisnumber(rb) && ttisnumber(rc)) { \
524          lua_Number nb = nvalue(rb), nc = nvalue(rc); \
525          setnvalue(ra, op(L, nb, nc)); \
526        } \
527        else { Protect(luaV_arith(L, ra, rb, rc, tm)); } }
528
529
530#define vmdispatch(o)   switch(o)
531#define vmcase(l,b)   case l: {b}  break;
532#define vmcasenb(l,b)   case l: {b}      /* nb = no break */
533
534void luaV_execute (lua_State *L) {
535  CallInfo *ci = L->ci;
536  LClosure *cl;
537  TValue *k;
538  StkId base;
539 newframe:  /* reentry point when frame changes (call/return) */
540  lua_assert(ci == L->ci);
541  cl = clLvalue(ci->func);
542  k = cl->p->k;
543  base = ci->u.l.base;
544  /* main loop of interpreter */
545  for (;;) {
546    Instruction i = *(ci->u.l.savedpc++);
547    StkId ra;
548    if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
549        (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
550      Protect(traceexec(L));
551    }
552    /* WARNING: several calls may realloc the stack and invalidate `ra' */
553    ra = RA(i);
554    lua_assert(base == ci->u.l.base);
555    lua_assert(base <= L->top && L->top < L->stack + L->stacksize);
556    vmdispatch (GET_OPCODE(i)) {
557      vmcase(OP_MOVE,
558        setobjs2s(L, ra, RB(i));
559      )
560      vmcase(OP_LOADK,
561        TValue *rb = k + GETARG_Bx(i);
562        setobj2s(L, ra, rb);
563      )
564      vmcase(OP_LOADKX,
565        TValue *rb;
566        lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG);
567        rb = k + GETARG_Ax(*ci->u.l.savedpc++);
568        setobj2s(L, ra, rb);
569      )
570      vmcase(OP_LOADBOOL,
571        setbvalue(ra, GETARG_B(i));
572        if (GETARG_C(i)) ci->u.l.savedpc++;  /* skip next instruction (if C) */
573      )
574      vmcase(OP_LOADNIL,
575        int b = GETARG_B(i);
576        do {
577          setnilvalue(ra++);
578        } while (b--);
579      )
580      vmcase(OP_GETUPVAL,
581        int b = GETARG_B(i);
582        setobj2s(L, ra, cl->upvals[b]->v);
583      )
584      vmcase(OP_GETTABUP,
585        int b = GETARG_B(i);
586        Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra));
587      )
588      vmcase(OP_GETTABLE,
589        Protect(luaV_gettable(L, RB(i), RKC(i), ra));
590      )
591      vmcase(OP_SETTABUP,
592        int a = GETARG_A(i);
593        Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i)));
594      )
595      vmcase(OP_SETUPVAL,
596        UpVal *uv = cl->upvals[GETARG_B(i)];
597        setobj(L, uv->v, ra);
598        luaC_barrier(L, uv, ra);
599      )
600      vmcase(OP_SETTABLE,
601        Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
602      )
603      vmcase(OP_NEWTABLE,
604        int b = GETARG_B(i);
605        int c = GETARG_C(i);
606        Table *t = luaH_new(L);
607        sethvalue(L, ra, t);
608        if (b != 0 || c != 0)
609          luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c));
610        checkGC(L, ra + 1);
611      )
612      vmcase(OP_SELF,
613        StkId rb = RB(i);
614        setobjs2s(L, ra+1, rb);
615        Protect(luaV_gettable(L, rb, RKC(i), ra));
616      )
617      vmcase(OP_ADD,
618        arith_op(luai_numadd, TM_ADD);
619      )
620      vmcase(OP_SUB,
621        arith_op(luai_numsub, TM_SUB);
622      )
623      vmcase(OP_MUL,
624        arith_op(luai_nummul, TM_MUL);
625      )
626      vmcase(OP_DIV,
627        arith_op(luai_numdiv, TM_DIV);
628      )
629      vmcase(OP_MOD,
630        arith_op(luai_nummod, TM_MOD);
631      )
632      vmcase(OP_POW,
633        arith_op(luai_numpow, TM_POW);
634      )
635      vmcase(OP_UNM,
636        TValue *rb = RB(i);
637        if (ttisnumber(rb)) {
638          lua_Number nb = nvalue(rb);
639          setnvalue(ra, luai_numunm(L, nb));
640        }
641        else {
642          Protect(luaV_arith(L, ra, rb, rb, TM_UNM));
643        }
644      )
645      vmcase(OP_NOT,
646        TValue *rb = RB(i);
647        int res = l_isfalse(rb);  /* next assignment may change this value */
648        setbvalue(ra, res);
649      )
650      vmcase(OP_LEN,
651        Protect(luaV_objlen(L, ra, RB(i)));
652      )
653      vmcase(OP_CONCAT,
654        int b = GETARG_B(i);
655        int c = GETARG_C(i);
656        StkId rb;
657        L->top = base + c + 1;  /* mark the end of concat operands */
658        Protect(luaV_concat(L, c - b + 1));
659        ra = RA(i);  /* 'luav_concat' may invoke TMs and move the stack */
660        rb = b + base;
661        setobjs2s(L, ra, rb);
662        checkGC(L, (ra >= rb ? ra + 1 : rb));
663        L->top = ci->top;  /* restore top */
664      )
665      vmcase(OP_JMP,
666        dojump(ci, i, 0);
667      )
668      vmcase(OP_EQ,
669        TValue *rb = RKB(i);
670        TValue *rc = RKC(i);
671        Protect(
672          if (cast_int(equalobj(L, rb, rc)) != GETARG_A(i))
673            ci->u.l.savedpc++;
674          else
675            donextjump(ci);
676        )
677      )
678      vmcase(OP_LT,
679        Protect(
680          if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i))
681            ci->u.l.savedpc++;
682          else
683            donextjump(ci);
684        )
685      )
686      vmcase(OP_LE,
687        Protect(
688          if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i))
689            ci->u.l.savedpc++;
690          else
691            donextjump(ci);
692        )
693      )
694      vmcase(OP_TEST,
695        if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra))
696            ci->u.l.savedpc++;
697          else
698          donextjump(ci);
699      )
700      vmcase(OP_TESTSET,
701        TValue *rb = RB(i);
702        if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb))
703          ci->u.l.savedpc++;
704        else {
705          setobjs2s(L, ra, rb);
706          donextjump(ci);
707        }
708      )
709      vmcase(OP_CALL,
710        int b = GETARG_B(i);
711        int nresults = GETARG_C(i) - 1;
712        if (b != 0) L->top = ra+b;  /* else previous instruction set top */
713        if (luaD_precall(L, ra, nresults)) {  /* C function? */
714          if (nresults >= 0) L->top = ci->top;  /* adjust results */
715          base = ci->u.l.base;
716        }
717        else {  /* Lua function */
718          ci = L->ci;
719          ci->callstatus |= CIST_REENTRY;
720          goto newframe;  /* restart luaV_execute over new Lua function */
721        }
722      )
723      vmcase(OP_TAILCALL,
724        int b = GETARG_B(i);
725        if (b != 0) L->top = ra+b;  /* else previous instruction set top */
726        lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
727        if (luaD_precall(L, ra, LUA_MULTRET))  /* C function? */
728          base = ci->u.l.base;
729        else {
730          /* tail call: put called frame (n) in place of caller one (o) */
731          CallInfo *nci = L->ci;  /* called frame */
732          CallInfo *oci = nci->previous;  /* caller frame */
733          StkId nfunc = nci->func;  /* called function */
734          StkId ofunc = oci->func;  /* caller function */
735          /* last stack slot filled by 'precall' */
736          StkId lim = nci->u.l.base + getproto(nfunc)->numparams;
737          int aux;
738          /* close all upvalues from previous call */
739          if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base);
740          /* move new frame into old one */
741          for (aux = 0; nfunc + aux < lim; aux++)
742            setobjs2s(L, ofunc + aux, nfunc + aux);
743          oci->u.l.base = ofunc + (nci->u.l.base - nfunc);  /* correct base */
744          oci->top = L->top = ofunc + (L->top - nfunc);  /* correct top */
745          oci->u.l.savedpc = nci->u.l.savedpc;
746          oci->callstatus |= CIST_TAIL;  /* function was tail called */
747          ci = L->ci = oci;  /* remove new frame */
748          lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize);
749          goto newframe;  /* restart luaV_execute over new Lua function */
750        }
751      )
752      vmcasenb(OP_RETURN,
753        int b = GETARG_B(i);
754        if (b != 0) L->top = ra+b-1;
755        if (cl->p->sizep > 0) luaF_close(L, base);
756        b = luaD_poscall(L, ra);
757        if (!(ci->callstatus & CIST_REENTRY))  /* 'ci' still the called one */
758          return;  /* external invocation: return */
759        else {  /* invocation via reentry: continue execution */
760          ci = L->ci;
761          if (b) L->top = ci->top;
762          lua_assert(isLua(ci));
763          lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL);
764          goto newframe;  /* restart luaV_execute over new Lua function */
765        }
766      )
767      vmcase(OP_FORLOOP,
768        lua_Number step = nvalue(ra+2);
769        lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */
770        lua_Number limit = nvalue(ra+1);
771        if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit)
772                                   : luai_numle(L, limit, idx)) {
773          ci->u.l.savedpc += GETARG_sBx(i);  /* jump back */
774          setnvalue(ra, idx);  /* update internal index... */
775          setnvalue(ra+3, idx);  /* ...and external index */
776        }
777      )
778      vmcase(OP_FORPREP,
779        const TValue *init = ra;
780        const TValue *plimit = ra+1;
781        const TValue *pstep = ra+2;
782        if (!tonumber(init, ra))
783          luaG_runerror(L, LUA_QL("for") " initial value must be a number");
784        else if (!tonumber(plimit, ra+1))
785          luaG_runerror(L, LUA_QL("for") " limit must be a number");
786        else if (!tonumber(pstep, ra+2))
787          luaG_runerror(L, LUA_QL("for") " step must be a number");
788        setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep)));
789        ci->u.l.savedpc += GETARG_sBx(i);
790      )
791      vmcasenb(OP_TFORCALL,
792        StkId cb = ra + 3;  /* call base */
793        setobjs2s(L, cb+2, ra+2);
794        setobjs2s(L, cb+1, ra+1);
795        setobjs2s(L, cb, ra);
796        L->top = cb + 3;  /* func. + 2 args (state and index) */
797        Protect(luaD_call(L, cb, GETARG_C(i), 1));
798        L->top = ci->top;
799        i = *(ci->u.l.savedpc++);  /* go to next instruction */
800        ra = RA(i);
801        lua_assert(GET_OPCODE(i) == OP_TFORLOOP);
802        goto l_tforloop;
803      )
804      vmcase(OP_TFORLOOP,
805        l_tforloop:
806        if (!ttisnil(ra + 1)) {  /* continue loop? */
807          setobjs2s(L, ra, ra + 1);  /* save control variable */
808           ci->u.l.savedpc += GETARG_sBx(i);  /* jump back */
809        }
810      )
811      vmcase(OP_SETLIST,
812        int n = GETARG_B(i);
813        int c = GETARG_C(i);
814        int last;
815        Table *h;
816        if (n == 0) n = cast_int(L->top - ra) - 1;
817        if (c == 0) {
818          lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG);
819          c = GETARG_Ax(*ci->u.l.savedpc++);
820        }
821        luai_runtimecheck(L, ttistable(ra));
822        h = hvalue(ra);
823        last = ((c-1)*LFIELDS_PER_FLUSH) + n;
824        if (last > h->sizearray)  /* needs more space? */
825          luaH_resizearray(L, h, last);  /* pre-allocate it at once */
826        for (; n > 0; n--) {
827          TValue *val = ra+n;
828          luaH_setint(L, h, last--, val);
829          luaC_barrierback(L, obj2gco(h), val);
830        }
831        L->top = ci->top;  /* correct top (in case of previous open call) */
832      )
833      vmcase(OP_CLOSURE,
834        Proto *p = cl->p->p[GETARG_Bx(i)];
835        Closure *ncl = getcached(p, cl->upvals, base);  /* cached closure */
836        if (ncl == NULL)  /* no match? */
837          pushclosure(L, p, cl->upvals, base, ra);  /* create a new one */
838        else
839          setclLvalue(L, ra, ncl);  /* push cashed closure */
840        checkGC(L, ra + 1);
841      )
842      vmcase(OP_VARARG,
843        int b = GETARG_B(i) - 1;
844        int j;
845        int n = cast_int(base - ci->func) - cl->p->numparams - 1;
846        if (b < 0) {  /* B == 0? */
847          b = n;  /* get all var. arguments */
848          Protect(luaD_checkstack(L, n));
849          ra = RA(i);  /* previous call may change the stack */
850          L->top = ra + n;
851        }
852        for (j = 0; j < b; j++) {
853          if (j < n) {
854            setobjs2s(L, ra + j, base - n + j);
855          }
856          else {
857            setnilvalue(ra + j);
858          }
859        }
860      )
861      vmcase(OP_EXTRAARG,
862        lua_assert(0);
863      )
864    }
865  }
866}
867
Property changes on: trunk/src/lib/lua/lvm.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/ltm.h
r0r22721
1/*
2** $Id: ltm.h,v 2.11 2011/02/28 17:32:10 roberto Exp $
3** Tag methods
4** See Copyright Notice in lua.h
5*/
6
7#ifndef ltm_h
8#define ltm_h
9
10
11#include "lobject.h"
12
13
14/*
15* WARNING: if you change the order of this enumeration,
16* grep "ORDER TM"
17*/
18typedef enum {
19  TM_INDEX,
20  TM_NEWINDEX,
21  TM_GC,
22  TM_MODE,
23  TM_LEN,
24  TM_EQ,  /* last tag method with `fast' access */
25  TM_ADD,
26  TM_SUB,
27  TM_MUL,
28  TM_DIV,
29  TM_MOD,
30  TM_POW,
31  TM_UNM,
32  TM_LT,
33  TM_LE,
34  TM_CONCAT,
35  TM_CALL,
36  TM_N      /* number of elements in the enum */
37} TMS;
38
39
40
41#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
42  ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
43
44#define fasttm(l,et,e)   gfasttm(G(l), et, e)
45
46#define ttypename(x)   luaT_typenames_[(x) + 1]
47#define objtypename(x)   ttypename(ttypenv(x))
48
49LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS];
50
51
52LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
53LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
54                                                       TMS event);
55LUAI_FUNC void luaT_init (lua_State *L);
56
57#endif
Property changes on: trunk/src/lib/lua/ltm.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/ldebug.c
r0r22721
1/*
2** $Id: ldebug.c,v 2.90 2012/08/16 17:34:28 roberto Exp $
3** Debug Interface
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdarg.h>
9#include <stddef.h>
10#include <string.h>
11
12
13#define ldebug_c
14#define LUA_CORE
15
16#include "lua.h"
17
18#include "lapi.h"
19#include "lcode.h"
20#include "ldebug.h"
21#include "ldo.h"
22#include "lfunc.h"
23#include "lobject.h"
24#include "lopcodes.h"
25#include "lstate.h"
26#include "lstring.h"
27#include "ltable.h"
28#include "ltm.h"
29#include "lvm.h"
30
31
32
33#define noLuaClosure(f)      ((f) == NULL || (f)->c.tt == LUA_TCCL)
34
35
36static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
37
38
39static int currentpc (CallInfo *ci) {
40  lua_assert(isLua(ci));
41  return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
42}
43
44
45static int currentline (CallInfo *ci) {
46  return getfuncline(ci_func(ci)->p, currentpc(ci));
47}
48
49
50/*
51** this function can be called asynchronous (e.g. during a signal)
52*/
53LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
54  if (func == NULL || mask == 0) {  /* turn off hooks? */
55    mask = 0;
56    func = NULL;
57  }
58  if (isLua(L->ci))
59    L->oldpc = L->ci->u.l.savedpc;
60  L->hook = func;
61  L->basehookcount = count;
62  resethookcount(L);
63  L->hookmask = cast_byte(mask);
64  return 1;
65}
66
67
68LUA_API lua_Hook lua_gethook (lua_State *L) {
69  return L->hook;
70}
71
72
73LUA_API int lua_gethookmask (lua_State *L) {
74  return L->hookmask;
75}
76
77
78LUA_API int lua_gethookcount (lua_State *L) {
79  return L->basehookcount;
80}
81
82
83LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
84  int status;
85  CallInfo *ci;
86  if (level < 0) return 0;  /* invalid (negative) level */
87  lua_lock(L);
88  for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous)
89    level--;
90  if (level == 0 && ci != &L->base_ci) {  /* level found? */
91    status = 1;
92    ar->i_ci = ci;
93  }
94  else status = 0;  /* no such level */
95  lua_unlock(L);
96  return status;
97}
98
99
100static const char *upvalname (Proto *p, int uv) {
101  TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
102  if (s == NULL) return "?";
103  else return getstr(s);
104}
105
106
107static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
108  int nparams = clLvalue(ci->func)->p->numparams;
109  if (n >= ci->u.l.base - ci->func - nparams)
110    return NULL;  /* no such vararg */
111  else {
112    *pos = ci->func + nparams + n;
113    return "(*vararg)";  /* generic name for any vararg */
114  }
115}
116
117
118static const char *findlocal (lua_State *L, CallInfo *ci, int n,
119                              StkId *pos) {
120  const char *name = NULL;
121  StkId base;
122  if (isLua(ci)) {
123    if (n < 0)  /* access to vararg values? */
124      return findvararg(ci, -n, pos);
125    else {
126      base = ci->u.l.base;
127      name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
128    }
129  }
130  else
131    base = ci->func + 1;
132  if (name == NULL) {  /* no 'standard' name? */
133    StkId limit = (ci == L->ci) ? L->top : ci->next->func;
134    if (limit - base >= n && n > 0)  /* is 'n' inside 'ci' stack? */
135      name = "(*temporary)";  /* generic name for any valid slot */
136    else
137      return NULL;  /* no name */
138  }
139  *pos = base + (n - 1);
140  return name;
141}
142
143
144LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
145  const char *name;
146  lua_lock(L);
147  if (ar == NULL) {  /* information about non-active function? */
148    if (!isLfunction(L->top - 1))  /* not a Lua function? */
149      name = NULL;
150    else  /* consider live variables at function start (parameters) */
151      name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
152  }
153  else {  /* active function; get information through 'ar' */
154    StkId pos = 0;  /* to avoid warnings */
155    name = findlocal(L, ar->i_ci, n, &pos);
156    if (name) {
157      setobj2s(L, L->top, pos);
158      api_incr_top(L);
159    }
160  }
161  lua_unlock(L);
162  return name;
163}
164
165
166LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
167  StkId pos = 0;  /* to avoid warnings */
168  const char *name = findlocal(L, ar->i_ci, n, &pos);
169  lua_lock(L);
170  if (name)
171    setobjs2s(L, pos, L->top - 1);
172  L->top--;  /* pop value */
173  lua_unlock(L);
174  return name;
175}
176
177
178static void funcinfo (lua_Debug *ar, Closure *cl) {
179  if (noLuaClosure(cl)) {
180    ar->source = "=[C]";
181    ar->linedefined = -1;
182    ar->lastlinedefined = -1;
183    ar->what = "C";
184  }
185  else {
186    Proto *p = cl->l.p;
187    ar->source = p->source ? getstr(p->source) : "=?";
188    ar->linedefined = p->linedefined;
189    ar->lastlinedefined = p->lastlinedefined;
190    ar->what = (ar->linedefined == 0) ? "main" : "Lua";
191  }
192  luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
193}
194
195
196static void collectvalidlines (lua_State *L, Closure *f) {
197  if (noLuaClosure(f)) {
198    setnilvalue(L->top);
199    api_incr_top(L);
200  }
201  else {
202    int i;
203    TValue v;
204    int *lineinfo = f->l.p->lineinfo;
205    Table *t = luaH_new(L);  /* new table to store active lines */
206    sethvalue(L, L->top, t);  /* push it on stack */
207    api_incr_top(L);
208    setbvalue(&v, 1);  /* boolean 'true' to be the value of all indices */
209    for (i = 0; i < f->l.p->sizelineinfo; i++)  /* for all lines with code */
210      luaH_setint(L, t, lineinfo[i], &v);  /* table[line] = true */
211  }
212}
213
214
215static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
216                       Closure *f, CallInfo *ci) {
217  int status = 1;
218  for (; *what; what++) {
219    switch (*what) {
220      case 'S': {
221        funcinfo(ar, f);
222        break;
223      }
224      case 'l': {
225        ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1;
226        break;
227      }
228      case 'u': {
229        ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
230        if (noLuaClosure(f)) {
231          ar->isvararg = 1;
232          ar->nparams = 0;
233        }
234        else {
235          ar->isvararg = f->l.p->is_vararg;
236          ar->nparams = f->l.p->numparams;
237        }
238        break;
239      }
240      case 't': {
241        ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0;
242        break;
243      }
244      case 'n': {
245        /* calling function is a known Lua function? */
246        if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
247          ar->namewhat = getfuncname(L, ci->previous, &ar->name);
248        else
249          ar->namewhat = NULL;
250        if (ar->namewhat == NULL) {
251          ar->namewhat = "";  /* not found */
252          ar->name = NULL;
253        }
254        break;
255      }
256      case 'L':
257      case 'f':  /* handled by lua_getinfo */
258        break;
259      default: status = 0;  /* invalid option */
260    }
261  }
262  return status;
263}
264
265
266LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
267  int status;
268  Closure *cl;
269  CallInfo *ci;
270  StkId func;
271  lua_lock(L);
272  if (*what == '>') {
273    ci = NULL;
274    func = L->top - 1;
275    api_check(L, ttisfunction(func), "function expected");
276    what++;  /* skip the '>' */
277    L->top--;  /* pop function */
278  }
279  else {
280    ci = ar->i_ci;
281    func = ci->func;
282    lua_assert(ttisfunction(ci->func));
283  }
284  cl = ttisclosure(func) ? clvalue(func) : NULL;
285  status = auxgetinfo(L, what, ar, cl, ci);
286  if (strchr(what, 'f')) {
287    setobjs2s(L, L->top, func);
288    api_incr_top(L);
289  }
290  if (strchr(what, 'L'))
291    collectvalidlines(L, cl);
292  lua_unlock(L);
293  return status;
294}
295
296
297/*
298** {======================================================
299** Symbolic Execution
300** =======================================================
301*/
302
303static const char *getobjname (Proto *p, int lastpc, int reg,
304                               const char **name);
305
306
307/*
308** find a "name" for the RK value 'c'
309*/
310static void kname (Proto *p, int pc, int c, const char **name) {
311  if (ISK(c)) {  /* is 'c' a constant? */
312    TValue *kvalue = &p->k[INDEXK(c)];
313    if (ttisstring(kvalue)) {  /* literal constant? */
314      *name = svalue(kvalue);  /* it is its own name */
315      return;
316    }
317    /* else no reasonable name found */
318  }
319  else {  /* 'c' is a register */
320    const char *what = getobjname(p, pc, c, name); /* search for 'c' */
321    if (what && *what == 'c') {  /* found a constant name? */
322      return;  /* 'name' already filled */
323    }
324    /* else no reasonable name found */
325  }
326  *name = "?";  /* no reasonable name found */
327}
328
329
330/*
331** try to find last instruction before 'lastpc' that modified register 'reg'
332*/
333static int findsetreg (Proto *p, int lastpc, int reg) {
334  int pc;
335  int setreg = -1;  /* keep last instruction that changed 'reg' */
336  for (pc = 0; pc < lastpc; pc++) {
337    Instruction i = p->code[pc];
338    OpCode op = GET_OPCODE(i);
339    int a = GETARG_A(i);
340    switch (op) {
341      case OP_LOADNIL: {
342        int b = GETARG_B(i);
343        if (a <= reg && reg <= a + b)  /* set registers from 'a' to 'a+b' */
344          setreg = pc;
345        break;
346      }
347      case OP_TFORCALL: {
348        if (reg >= a + 2) setreg = pc;  /* affect all regs above its base */
349        break;
350      }
351      case OP_CALL:
352      case OP_TAILCALL: {
353        if (reg >= a) setreg = pc;  /* affect all registers above base */
354        break;
355      }
356      case OP_JMP: {
357        int b = GETARG_sBx(i);
358        int dest = pc + 1 + b;
359        /* jump is forward and do not skip `lastpc'? */
360        if (pc < dest && dest <= lastpc)
361          pc += b;  /* do the jump */
362        break;
363      }
364      case OP_TEST: {
365        if (reg == a) setreg = pc;  /* jumped code can change 'a' */
366        break;
367      }
368      default:
369        if (testAMode(op) && reg == a)  /* any instruction that set A */
370          setreg = pc;
371        break;
372    }
373  }
374  return setreg;
375}
376
377
378static const char *getobjname (Proto *p, int lastpc, int reg,
379                               const char **name) {
380  int pc;
381  *name = luaF_getlocalname(p, reg + 1, lastpc);
382  if (*name)  /* is a local? */
383    return "local";
384  /* else try symbolic execution */
385  pc = findsetreg(p, lastpc, reg);
386  if (pc != -1) {  /* could find instruction? */
387    Instruction i = p->code[pc];
388    OpCode op = GET_OPCODE(i);
389    switch (op) {
390      case OP_MOVE: {
391        int b = GETARG_B(i);  /* move from 'b' to 'a' */
392        if (b < GETARG_A(i))
393          return getobjname(p, pc, b, name);  /* get name for 'b' */
394        break;
395      }
396      case OP_GETTABUP:
397      case OP_GETTABLE: {
398        int k = GETARG_C(i);  /* key index */
399        int t = GETARG_B(i);  /* table index */
400        const char *vn = (op == OP_GETTABLE)  /* name of indexed variable */
401                         ? luaF_getlocalname(p, t + 1, pc)
402                         : upvalname(p, t);
403        kname(p, pc, k, name);
404        return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
405      }
406      case OP_GETUPVAL: {
407        *name = upvalname(p, GETARG_B(i));
408        return "upvalue";
409      }
410      case OP_LOADK:
411      case OP_LOADKX: {
412        int b = (op == OP_LOADK) ? GETARG_Bx(i)
413                                 : GETARG_Ax(p->code[pc + 1]);
414        if (ttisstring(&p->k[b])) {
415          *name = svalue(&p->k[b]);
416          return "constant";
417        }
418        break;
419      }
420      case OP_SELF: {
421        int k = GETARG_C(i);  /* key index */
422        kname(p, pc, k, name);
423        return "method";
424      }
425      default: break;  /* go through to return NULL */
426    }
427  }
428  return NULL;  /* could not find reasonable name */
429}
430
431
432static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
433  TMS tm;
434  Proto *p = ci_func(ci)->p;  /* calling function */
435  int pc = currentpc(ci);  /* calling instruction index */
436  Instruction i = p->code[pc];  /* calling instruction */
437  switch (GET_OPCODE(i)) {
438    case OP_CALL:
439    case OP_TAILCALL:  /* get function name */
440      return getobjname(p, pc, GETARG_A(i), name);
441    case OP_TFORCALL: {  /* for iterator */
442      *name = "for iterator";
443       return "for iterator";
444    }
445    /* all other instructions can call only through metamethods */
446    case OP_SELF:
447    case OP_GETTABUP:
448    case OP_GETTABLE: tm = TM_INDEX; break;
449    case OP_SETTABUP:
450    case OP_SETTABLE: tm = TM_NEWINDEX; break;
451    case OP_EQ: tm = TM_EQ; break;
452    case OP_ADD: tm = TM_ADD; break;
453    case OP_SUB: tm = TM_SUB; break;
454    case OP_MUL: tm = TM_MUL; break;
455    case OP_DIV: tm = TM_DIV; break;
456    case OP_MOD: tm = TM_MOD; break;
457    case OP_POW: tm = TM_POW; break;
458    case OP_UNM: tm = TM_UNM; break;
459    case OP_LEN: tm = TM_LEN; break;
460    case OP_LT: tm = TM_LT; break;
461    case OP_LE: tm = TM_LE; break;
462    case OP_CONCAT: tm = TM_CONCAT; break;
463    default:
464      return NULL;  /* else no useful name can be found */
465  }
466  *name = getstr(G(L)->tmname[tm]);
467  return "metamethod";
468}
469
470/* }====================================================== */
471
472
473
474/*
475** only ANSI way to check whether a pointer points to an array
476** (used only for error messages, so efficiency is not a big concern)
477*/
478static int isinstack (CallInfo *ci, const TValue *o) {
479  StkId p;
480  for (p = ci->u.l.base; p < ci->top; p++)
481    if (o == p) return 1;
482  return 0;
483}
484
485
486static const char *getupvalname (CallInfo *ci, const TValue *o,
487                                 const char **name) {
488  LClosure *c = ci_func(ci);
489  int i;
490  for (i = 0; i < c->nupvalues; i++) {
491    if (c->upvals[i]->v == o) {
492      *name = upvalname(c->p, i);
493      return "upvalue";
494    }
495  }
496  return NULL;
497}
498
499
500l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
501  CallInfo *ci = L->ci;
502  const char *name = NULL;
503  const char *t = objtypename(o);
504  const char *kind = NULL;
505  if (isLua(ci)) {
506    kind = getupvalname(ci, o, &name);  /* check whether 'o' is an upvalue */
507    if (!kind && isinstack(ci, o))  /* no? try a register */
508      kind = getobjname(ci_func(ci)->p, currentpc(ci),
509                        cast_int(o - ci->u.l.base), &name);
510  }
511  if (kind)
512    luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
513                op, kind, name, t);
514  else
515    luaG_runerror(L, "attempt to %s a %s value", op, t);
516}
517
518
519l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
520  if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
521  lua_assert(!ttisstring(p1) && !ttisnumber(p2));
522  luaG_typeerror(L, p1, "concatenate");
523}
524
525
526l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
527  TValue temp;
528  if (luaV_tonumber(p1, &temp) == NULL)
529    p2 = p1;  /* first operand is wrong */
530  luaG_typeerror(L, p2, "perform arithmetic on");
531}
532
533
534l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
535  const char *t1 = objtypename(p1);
536  const char *t2 = objtypename(p2);
537  if (t1 == t2)
538    luaG_runerror(L, "attempt to compare two %s values", t1);
539  else
540    luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
541}
542
543
544static void addinfo (lua_State *L, const char *msg) {
545  CallInfo *ci = L->ci;
546  if (isLua(ci)) {  /* is Lua code? */
547    char buff[LUA_IDSIZE];  /* add file:line information */
548    int line = currentline(ci);
549    TString *src = ci_func(ci)->p->source;
550    if (src)
551      luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
552    else {  /* no source available; use "?" instead */
553      buff[0] = '?'; buff[1] = '\0';
554    }
555    luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
556  }
557}
558
559
560l_noret luaG_errormsg (lua_State *L) {
561  if (L->errfunc != 0) {  /* is there an error handling function? */
562    StkId errfunc = restorestack(L, L->errfunc);
563    if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
564    setobjs2s(L, L->top, L->top - 1);  /* move argument */
565    setobjs2s(L, L->top - 1, errfunc);  /* push function */
566    L->top++;
567    luaD_call(L, L->top - 2, 1, 0);  /* call it */
568  }
569  luaD_throw(L, LUA_ERRRUN);
570}
571
572
573l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
574  va_list argp;
575  va_start(argp, fmt);
576  addinfo(L, luaO_pushvfstring(L, fmt, argp));
577  va_end(argp);
578  luaG_errormsg(L);
579}
580
Property changes on: trunk/src/lib/lua/ldebug.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lvm.h
r0r22721
1/*
2** $Id: lvm.h,v 2.18 2013/01/08 14:06:55 roberto Exp $
3** Lua virtual machine
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lvm_h
8#define lvm_h
9
10
11#include "ldo.h"
12#include "lobject.h"
13#include "ltm.h"
14
15
16#define tostring(L,o) (ttisstring(o) || (luaV_tostring(L, o)))
17
18#define tonumber(o,n)   (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL))
19
20#define equalobj(L,o1,o2)  (ttisequal(o1, o2) && luaV_equalobj_(L, o1, o2))
21
22#define luaV_rawequalobj(o1,o2)      equalobj(NULL,o1,o2)
23
24
25/* not to called directly */
26LUAI_FUNC int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2);
27
28
29LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
30LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
31LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
32LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
33LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
34                                            StkId val);
35LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
36                                            StkId val);
37LUAI_FUNC void luaV_finishOp (lua_State *L);
38LUAI_FUNC void luaV_execute (lua_State *L);
39LUAI_FUNC void luaV_concat (lua_State *L, int total);
40LUAI_FUNC void luaV_arith (lua_State *L, StkId ra, const TValue *rb,
41                           const TValue *rc, TMS op);
42LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);
43
44#endif
Property changes on: trunk/src/lib/lua/lvm.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lgc.c
r0r22721
1/*
2** $Id: lgc.c,v 2.140 2013/03/16 21:10:18 roberto Exp $
3** Garbage Collector
4** See Copyright Notice in lua.h
5*/
6
7#include <string.h>
8
9#define lgc_c
10#define LUA_CORE
11
12#include "lua.h"
13
14#include "ldebug.h"
15#include "ldo.h"
16#include "lfunc.h"
17#include "lgc.h"
18#include "lmem.h"
19#include "lobject.h"
20#include "lstate.h"
21#include "lstring.h"
22#include "ltable.h"
23#include "ltm.h"
24
25
26
27/*
28** cost of sweeping one element (the size of a small object divided
29** by some adjust for the sweep speed)
30*/
31#define GCSWEEPCOST   ((sizeof(TString) + 4) / 4)
32
33/* maximum number of elements to sweep in each single step */
34#define GCSWEEPMAX   (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4))
35
36/* maximum number of finalizers to call in each GC step */
37#define GCFINALIZENUM   4
38
39
40/*
41** macro to adjust 'stepmul': 'stepmul' is actually used like
42** 'stepmul / STEPMULADJ' (value chosen by tests)
43*/
44#define STEPMULADJ      200
45
46
47/*
48** macro to adjust 'pause': 'pause' is actually used like
49** 'pause / PAUSEADJ' (value chosen by tests)
50*/
51#define PAUSEADJ      100
52
53
54/*
55** 'makewhite' erases all color bits plus the old bit and then
56** sets only the current white bit
57*/
58#define maskcolors   (~(bit2mask(BLACKBIT, OLDBIT) | WHITEBITS))
59#define makewhite(g,x)   \
60 (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g)))
61
62#define white2gray(x)   resetbits(gch(x)->marked, WHITEBITS)
63#define black2gray(x)   resetbit(gch(x)->marked, BLACKBIT)
64
65
66#define isfinalized(x)      testbit(gch(x)->marked, FINALIZEDBIT)
67
68#define checkdeadkey(n)   lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n)))
69
70
71#define checkconsistency(obj)  \
72  lua_longassert(!iscollectable(obj) || righttt(obj))
73
74
75#define markvalue(g,o) { checkconsistency(o); \
76  if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
77
78#define markobject(g,t) { if ((t) && iswhite(obj2gco(t))) \
79      reallymarkobject(g, obj2gco(t)); }
80
81static void reallymarkobject (global_State *g, GCObject *o);
82
83
84/*
85** {======================================================
86** Generic functions
87** =======================================================
88*/
89
90
91/*
92** one after last element in a hash array
93*/
94#define gnodelast(h)   gnode(h, cast(size_t, sizenode(h)))
95
96
97/*
98** link table 'h' into list pointed by 'p'
99*/
100#define linktable(h,p)   ((h)->gclist = *(p), *(p) = obj2gco(h))
101
102
103/*
104** if key is not marked, mark its entry as dead (therefore removing it
105** from the table)
106*/
107static void removeentry (Node *n) {
108  lua_assert(ttisnil(gval(n)));
109  if (valiswhite(gkey(n)))
110    setdeadvalue(gkey(n));  /* unused and unmarked key; remove it */
111}
112
113
114/*
115** tells whether a key or value can be cleared from a weak
116** table. Non-collectable objects are never removed from weak
117** tables. Strings behave as `values', so are never removed too. for
118** other objects: if really collected, cannot keep them; for objects
119** being finalized, keep them in keys, but not in values
120*/
121static int iscleared (global_State *g, const TValue *o) {
122  if (!iscollectable(o)) return 0;
123  else if (ttisstring(o)) {
124    markobject(g, rawtsvalue(o));  /* strings are `values', so are never weak */
125    return 0;
126  }
127  else return iswhite(gcvalue(o));
128}
129
130
131/*
132** barrier that moves collector forward, that is, mark the white object
133** being pointed by a black object.
134*/
135void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
136  global_State *g = G(L);
137  lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
138  lua_assert(g->gcstate != GCSpause);
139  lua_assert(gch(o)->tt != LUA_TTABLE);
140  if (keepinvariantout(g))  /* must keep invariant? */
141    reallymarkobject(g, v);  /* restore invariant */
142  else {  /* sweep phase */
143    lua_assert(issweepphase(g));
144    makewhite(g, o);  /* mark main obj. as white to avoid other barriers */
145  }
146}
147
148
149/*
150** barrier that moves collector backward, that is, mark the black object
151** pointing to a white object as gray again. (Current implementation
152** only works for tables; access to 'gclist' is not uniform across
153** different types.)
154*/
155void luaC_barrierback_ (lua_State *L, GCObject *o) {
156  global_State *g = G(L);
157  lua_assert(isblack(o) && !isdead(g, o) && gch(o)->tt == LUA_TTABLE);
158  black2gray(o);  /* make object gray (again) */
159  gco2t(o)->gclist = g->grayagain;
160  g->grayagain = o;
161}
162
163
164/*
165** barrier for prototypes. When creating first closure (cache is
166** NULL), use a forward barrier; this may be the only closure of the
167** prototype (if it is a "regular" function, with a single instance)
168** and the prototype may be big, so it is better to avoid traversing
169** it again. Otherwise, use a backward barrier, to avoid marking all
170** possible instances.
171*/
172LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c) {
173  global_State *g = G(L);
174  lua_assert(isblack(obj2gco(p)));
175  if (p->cache == NULL) {  /* first time? */
176    luaC_objbarrier(L, p, c);
177  }
178  else {  /* use a backward barrier */
179    black2gray(obj2gco(p));  /* make prototype gray (again) */
180    p->gclist = g->grayagain;
181    g->grayagain = obj2gco(p);
182  }
183}
184
185
186/*
187** check color (and invariants) for an upvalue that was closed,
188** i.e., moved into the 'allgc' list
189*/
190void luaC_checkupvalcolor (global_State *g, UpVal *uv) {
191  GCObject *o = obj2gco(uv);
192  lua_assert(!isblack(o));  /* open upvalues are never black */
193  if (isgray(o)) {
194    if (keepinvariant(g)) {
195      resetoldbit(o);  /* see MOVE OLD rule */
196      gray2black(o);  /* it is being visited now */
197      markvalue(g, uv->v);
198    }
199    else {
200      lua_assert(issweepphase(g));
201      makewhite(g, o);
202    }
203  }
204}
205
206
207/*
208** create a new collectable object (with given type and size) and link
209** it to '*list'. 'offset' tells how many bytes to allocate before the
210** object itself (used only by states).
211*/
212GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list,
213                       int offset) {
214  global_State *g = G(L);
215  char *raw = cast(char *, luaM_newobject(L, novariant(tt), sz));
216  GCObject *o = obj2gco(raw + offset);
217  if (list == NULL)
218    list = &g->allgc;  /* standard list for collectable objects */
219  gch(o)->marked = luaC_white(g);
220  gch(o)->tt = tt;
221  gch(o)->next = *list;
222  *list = o;
223  return o;
224}
225
226/* }====================================================== */
227
228
229
230/*
231** {======================================================
232** Mark functions
233** =======================================================
234*/
235
236
237/*
238** mark an object. Userdata, strings, and closed upvalues are visited
239** and turned black here. Other objects are marked gray and added
240** to appropriate list to be visited (and turned black) later. (Open
241** upvalues are already linked in 'headuv' list.)
242*/
243static void reallymarkobject (global_State *g, GCObject *o) {
244  lu_mem size;
245  white2gray(o);
246  switch (gch(o)->tt) {
247    case LUA_TSHRSTR:
248    case LUA_TLNGSTR: {
249      size = sizestring(gco2ts(o));
250      break;  /* nothing else to mark; make it black */
251    }
252    case LUA_TUSERDATA: {
253      Table *mt = gco2u(o)->metatable;
254      markobject(g, mt);
255      markobject(g, gco2u(o)->env);
256      size = sizeudata(gco2u(o));
257      break;
258    }
259    case LUA_TUPVAL: {
260      UpVal *uv = gco2uv(o);
261      markvalue(g, uv->v);
262      if (uv->v != &uv->u.value)  /* open? */
263        return;  /* open upvalues remain gray */
264      size = sizeof(UpVal);
265      break;
266    }
267    case LUA_TLCL: {
268      gco2lcl(o)->gclist = g->gray;
269      g->gray = o;
270      return;
271    }
272    case LUA_TCCL: {
273      gco2ccl(o)->gclist = g->gray;
274      g->gray = o;
275      return;
276    }
277    case LUA_TTABLE: {
278      linktable(gco2t(o), &g->gray);
279      return;
280    }
281    case LUA_TTHREAD: {
282      gco2th(o)->gclist = g->gray;
283      g->gray = o;
284      return;
285    }
286    case LUA_TPROTO: {
287      gco2p(o)->gclist = g->gray;
288      g->gray = o;
289      return;
290    }
291    default: lua_assert(0); return;
292  }
293  gray2black(o);
294  g->GCmemtrav += size;
295}
296
297
298/*
299** mark metamethods for basic types
300*/
301static void markmt (global_State *g) {
302  int i;
303  for (i=0; i < LUA_NUMTAGS; i++)
304    markobject(g, g->mt[i]);
305}
306
307
308/*
309** mark all objects in list of being-finalized
310*/
311static void markbeingfnz (global_State *g) {
312  GCObject *o;
313  for (o = g->tobefnz; o != NULL; o = gch(o)->next) {
314    makewhite(g, o);
315    reallymarkobject(g, o);
316  }
317}
318
319
320/*
321** mark all values stored in marked open upvalues. (See comment in
322** 'lstate.h'.)
323*/
324static void remarkupvals (global_State *g) {
325  UpVal *uv;
326  for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
327    if (isgray(obj2gco(uv)))
328      markvalue(g, uv->v);
329  }
330}
331
332
333/*
334** mark root set and reset all gray lists, to start a new
335** incremental (or full) collection
336*/
337static void restartcollection (global_State *g) {
338  g->gray = g->grayagain = NULL;
339  g->weak = g->allweak = g->ephemeron = NULL;
340  markobject(g, g->mainthread);
341  markvalue(g, &g->l_registry);
342  markmt(g);
343  markbeingfnz(g);  /* mark any finalizing object left from previous cycle */
344}
345
346/* }====================================================== */
347
348
349/*
350** {======================================================
351** Traverse functions
352** =======================================================
353*/
354
355static void traverseweakvalue (global_State *g, Table *h) {
356  Node *n, *limit = gnodelast(h);
357  /* if there is array part, assume it may have white values (do not
358     traverse it just to check) */
359  int hasclears = (h->sizearray > 0);
360  for (n = gnode(h, 0); n < limit; n++) {
361    checkdeadkey(n);
362    if (ttisnil(gval(n)))  /* entry is empty? */
363      removeentry(n);  /* remove it */
364    else {
365      lua_assert(!ttisnil(gkey(n)));
366      markvalue(g, gkey(n));  /* mark key */
367      if (!hasclears && iscleared(g, gval(n)))  /* is there a white value? */
368        hasclears = 1;  /* table will have to be cleared */
369    }
370  }
371  if (hasclears)
372    linktable(h, &g->weak);  /* has to be cleared later */
373  else  /* no white values */
374    linktable(h, &g->grayagain);  /* no need to clean */
375}
376
377
378static int traverseephemeron (global_State *g, Table *h) {
379  int marked = 0;  /* true if an object is marked in this traversal */
380  int hasclears = 0;  /* true if table has white keys */
381  int prop = 0;  /* true if table has entry "white-key -> white-value" */
382  Node *n, *limit = gnodelast(h);
383  int i;
384  /* traverse array part (numeric keys are 'strong') */
385  for (i = 0; i < h->sizearray; i++) {
386    if (valiswhite(&h->array[i])) {
387      marked = 1;
388      reallymarkobject(g, gcvalue(&h->array[i]));
389    }
390  }
391  /* traverse hash part */
392  for (n = gnode(h, 0); n < limit; n++) {
393    checkdeadkey(n);
394    if (ttisnil(gval(n)))  /* entry is empty? */
395      removeentry(n);  /* remove it */
396    else if (iscleared(g, gkey(n))) {  /* key is not marked (yet)? */
397      hasclears = 1;  /* table must be cleared */
398      if (valiswhite(gval(n)))  /* value not marked yet? */
399        prop = 1;  /* must propagate again */
400    }
401    else if (valiswhite(gval(n))) {  /* value not marked yet? */
402      marked = 1;
403      reallymarkobject(g, gcvalue(gval(n)));  /* mark it now */
404    }
405  }
406  if (prop)
407    linktable(h, &g->ephemeron);  /* have to propagate again */
408  else if (hasclears)  /* does table have white keys? */
409    linktable(h, &g->allweak);  /* may have to clean white keys */
410  else  /* no white keys */
411    linktable(h, &g->grayagain);  /* no need to clean */
412  return marked;
413}
414
415
416static void traversestrongtable (global_State *g, Table *h) {
417  Node *n, *limit = gnodelast(h);
418  int i;
419  for (i = 0; i < h->sizearray; i++)  /* traverse array part */
420    markvalue(g, &h->array[i]);
421  for (n = gnode(h, 0); n < limit; n++) {  /* traverse hash part */
422    checkdeadkey(n);
423    if (ttisnil(gval(n)))  /* entry is empty? */
424      removeentry(n);  /* remove it */
425    else {
426      lua_assert(!ttisnil(gkey(n)));
427      markvalue(g, gkey(n));  /* mark key */
428      markvalue(g, gval(n));  /* mark value */
429    }
430  }
431}
432
433
434static lu_mem traversetable (global_State *g, Table *h) {
435  const char *weakkey, *weakvalue;
436  const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
437  markobject(g, h->metatable);
438  if (mode && ttisstring(mode) &&  /* is there a weak mode? */
439      ((weakkey = strchr(svalue(mode), 'k')),
440       (weakvalue = strchr(svalue(mode), 'v')),
441       (weakkey || weakvalue))) {  /* is really weak? */
442    black2gray(obj2gco(h));  /* keep table gray */
443    if (!weakkey)  /* strong keys? */
444      traverseweakvalue(g, h);
445    else if (!weakvalue)  /* strong values? */
446      traverseephemeron(g, h);
447    else  /* all weak */
448      linktable(h, &g->allweak);  /* nothing to traverse now */
449  }
450  else  /* not weak */
451    traversestrongtable(g, h);
452  return sizeof(Table) + sizeof(TValue) * h->sizearray +
453                         sizeof(Node) * cast(size_t, sizenode(h));
454}
455
456
457static int traverseproto (global_State *g, Proto *f) {
458  int i;
459  if (f->cache && iswhite(obj2gco(f->cache)))
460    f->cache = NULL;  /* allow cache to be collected */
461  markobject(g, f->source);
462  for (i = 0; i < f->sizek; i++)  /* mark literals */
463    markvalue(g, &f->k[i]);
464  for (i = 0; i < f->sizeupvalues; i++)  /* mark upvalue names */
465    markobject(g, f->upvalues[i].name);
466  for (i = 0; i < f->sizep; i++)  /* mark nested protos */
467    markobject(g, f->p[i]);
468  for (i = 0; i < f->sizelocvars; i++)  /* mark local-variable names */
469    markobject(g, f->locvars[i].varname);
470  return sizeof(Proto) + sizeof(Instruction) * f->sizecode +
471                         sizeof(Proto *) * f->sizep +
472                         sizeof(TValue) * f->sizek +
473                         sizeof(int) * f->sizelineinfo +
474                         sizeof(LocVar) * f->sizelocvars +
475                         sizeof(Upvaldesc) * f->sizeupvalues;
476}
477
478
479static lu_mem traverseCclosure (global_State *g, CClosure *cl) {
480  int i;
481  for (i = 0; i < cl->nupvalues; i++)  /* mark its upvalues */
482    markvalue(g, &cl->upvalue[i]);
483  return sizeCclosure(cl->nupvalues);
484}
485
486static lu_mem traverseLclosure (global_State *g, LClosure *cl) {
487  int i;
488  markobject(g, cl->p);  /* mark its prototype */
489  for (i = 0; i < cl->nupvalues; i++)  /* mark its upvalues */
490    markobject(g, cl->upvals[i]);
491  return sizeLclosure(cl->nupvalues);
492}
493
494
495static lu_mem traversestack (global_State *g, lua_State *th) {
496  StkId o = th->stack;
497  if (o == NULL)
498    return 1;  /* stack not completely built yet */
499  for (; o < th->top; o++)
500    markvalue(g, o);
501  if (g->gcstate == GCSatomic) {  /* final traversal? */
502    StkId lim = th->stack + th->stacksize;  /* real end of stack */
503    for (; o < lim; o++)  /* clear not-marked stack slice */
504      setnilvalue(o);
505  }
506  return sizeof(lua_State) + sizeof(TValue) * th->stacksize;
507}
508
509
510/*
511** traverse one gray object, turning it to black (except for threads,
512** which are always gray).
513*/
514static void propagatemark (global_State *g) {
515  lu_mem size;
516  GCObject *o = g->gray;
517  lua_assert(isgray(o));
518  gray2black(o);
519  switch (gch(o)->tt) {
520    case LUA_TTABLE: {
521      Table *h = gco2t(o);
522      g->gray = h->gclist;  /* remove from 'gray' list */
523      size = traversetable(g, h);
524      break;
525    }
526    case LUA_TLCL: {
527      LClosure *cl = gco2lcl(o);
528      g->gray = cl->gclist;  /* remove from 'gray' list */
529      size = traverseLclosure(g, cl);
530      break;
531    }
532    case LUA_TCCL: {
533      CClosure *cl = gco2ccl(o);
534      g->gray = cl->gclist;  /* remove from 'gray' list */
535      size = traverseCclosure(g, cl);
536      break;
537    }
538    case LUA_TTHREAD: {
539      lua_State *th = gco2th(o);
540      g->gray = th->gclist;  /* remove from 'gray' list */
541      th->gclist = g->grayagain;
542      g->grayagain = o;  /* insert into 'grayagain' list */
543      black2gray(o);
544      size = traversestack(g, th);
545      break;
546    }
547    case LUA_TPROTO: {
548      Proto *p = gco2p(o);
549      g->gray = p->gclist;  /* remove from 'gray' list */
550      size = traverseproto(g, p);
551      break;
552    }
553    default: lua_assert(0); return;
554  }
555  g->GCmemtrav += size;
556}
557
558
559static void propagateall (global_State *g) {
560  while (g->gray) propagatemark(g);
561}
562
563
564static void propagatelist (global_State *g, GCObject *l) {
565  lua_assert(g->gray == NULL);  /* no grays left */
566  g->gray = l;
567  propagateall(g);  /* traverse all elements from 'l' */
568}
569
570/*
571** retraverse all gray lists. Because tables may be reinserted in other
572** lists when traversed, traverse the original lists to avoid traversing
573** twice the same table (which is not wrong, but inefficient)
574*/
575static void retraversegrays (global_State *g) {
576  GCObject *weak = g->weak;  /* save original lists */
577  GCObject *grayagain = g->grayagain;
578  GCObject *ephemeron = g->ephemeron;
579  g->weak = g->grayagain = g->ephemeron = NULL;
580  propagateall(g);  /* traverse main gray list */
581  propagatelist(g, grayagain);
582  propagatelist(g, weak);
583  propagatelist(g, ephemeron);
584}
585
586
587static void convergeephemerons (global_State *g) {
588  int changed;
589  do {
590    GCObject *w;
591    GCObject *next = g->ephemeron;  /* get ephemeron list */
592    g->ephemeron = NULL;  /* tables will return to this list when traversed */
593    changed = 0;
594    while ((w = next) != NULL) {
595      next = gco2t(w)->gclist;
596      if (traverseephemeron(g, gco2t(w))) {  /* traverse marked some value? */
597        propagateall(g);  /* propagate changes */
598        changed = 1;  /* will have to revisit all ephemeron tables */
599      }
600    }
601  } while (changed);
602}
603
604/* }====================================================== */
605
606
607/*
608** {======================================================
609** Sweep Functions
610** =======================================================
611*/
612
613
614/*
615** clear entries with unmarked keys from all weaktables in list 'l' up
616** to element 'f'
617*/
618static void clearkeys (global_State *g, GCObject *l, GCObject *f) {
619  for (; l != f; l = gco2t(l)->gclist) {
620    Table *h = gco2t(l);
621    Node *n, *limit = gnodelast(h);
622    for (n = gnode(h, 0); n < limit; n++) {
623      if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) {
624        setnilvalue(gval(n));  /* remove value ... */
625        removeentry(n);  /* and remove entry from table */
626      }
627    }
628  }
629}
630
631
632/*
633** clear entries with unmarked values from all weaktables in list 'l' up
634** to element 'f'
635*/
636static void clearvalues (global_State *g, GCObject *l, GCObject *f) {
637  for (; l != f; l = gco2t(l)->gclist) {
638    Table *h = gco2t(l);
639    Node *n, *limit = gnodelast(h);
640    int i;
641    for (i = 0; i < h->sizearray; i++) {
642      TValue *o = &h->array[i];
643      if (iscleared(g, o))  /* value was collected? */
644        setnilvalue(o);  /* remove value */
645    }
646    for (n = gnode(h, 0); n < limit; n++) {
647      if (!ttisnil(gval(n)) && iscleared(g, gval(n))) {
648        setnilvalue(gval(n));  /* remove value ... */
649        removeentry(n);  /* and remove entry from table */
650      }
651    }
652  }
653}
654
655
656static void freeobj (lua_State *L, GCObject *o) {
657  switch (gch(o)->tt) {
658    case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
659    case LUA_TLCL: {
660      luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues));
661      break;
662    }
663    case LUA_TCCL: {
664      luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues));
665      break;
666    }
667    case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
668    case LUA_TTABLE: luaH_free(L, gco2t(o)); break;
669    case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
670    case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
671    case LUA_TSHRSTR:
672      G(L)->strt.nuse--;
673      /* go through */
674    case LUA_TLNGSTR: {
675      luaM_freemem(L, o, sizestring(gco2ts(o)));
676      break;
677    }
678    default: lua_assert(0);
679  }
680}
681
682
683#define sweepwholelist(L,p)   sweeplist(L,p,MAX_LUMEM)
684static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count);
685
686
687/*
688** sweep the (open) upvalues of a thread and resize its stack and
689** list of call-info structures.
690*/
691static void sweepthread (lua_State *L, lua_State *L1) {
692  if (L1->stack == NULL) return;  /* stack not completely built yet */
693  sweepwholelist(L, &L1->openupval);  /* sweep open upvalues */
694  luaE_freeCI(L1);  /* free extra CallInfo slots */
695  /* should not change the stack during an emergency gc cycle */
696  if (G(L)->gckind != KGC_EMERGENCY)
697    luaD_shrinkstack(L1);
698}
699
700
701/*
702** sweep at most 'count' elements from a list of GCObjects erasing dead
703** objects, where a dead (not alive) object is one marked with the "old"
704** (non current) white and not fixed.
705** In non-generational mode, change all non-dead objects back to white,
706** preparing for next collection cycle.
707** In generational mode, keep black objects black, and also mark them as
708** old; stop when hitting an old object, as all objects after that
709** one will be old too.
710** When object is a thread, sweep its list of open upvalues too.
711*/
712static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
713  global_State *g = G(L);
714  int ow = otherwhite(g);
715  int toclear, toset;  /* bits to clear and to set in all live objects */
716  int tostop;  /* stop sweep when this is true */
717  if (isgenerational(g)) {  /* generational mode? */
718    toclear = ~0;  /* clear nothing */
719    toset = bitmask(OLDBIT);  /* set the old bit of all surviving objects */
720    tostop = bitmask(OLDBIT);  /* do not sweep old generation */
721  }
722  else {  /* normal mode */
723    toclear = maskcolors;  /* clear all color bits + old bit */
724    toset = luaC_white(g);  /* make object white */
725    tostop = 0;  /* do not stop */
726  }
727  while (*p != NULL && count-- > 0) {
728    GCObject *curr = *p;
729    int marked = gch(curr)->marked;
730    if (isdeadm(ow, marked)) {  /* is 'curr' dead? */
731      *p = gch(curr)->next;  /* remove 'curr' from list */
732      freeobj(L, curr);  /* erase 'curr' */
733    }
734    else {
735      if (testbits(marked, tostop))
736        return NULL;  /* stop sweeping this list */
737      if (gch(curr)->tt == LUA_TTHREAD)
738        sweepthread(L, gco2th(curr));  /* sweep thread's upvalues */
739      /* update marks */
740      gch(curr)->marked = cast_byte((marked & toclear) | toset);
741      p = &gch(curr)->next;  /* go to next element */
742    }
743  }
744  return (*p == NULL) ? NULL : p;
745}
746
747
748/*
749** sweep a list until a live object (or end of list)
750*/
751static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) {
752  GCObject ** old = p;
753  int i = 0;
754  do {
755    i++;
756    p = sweeplist(L, p, 1);
757  } while (p == old);
758  if (n) *n += i;
759  return p;
760}
761
762/* }====================================================== */
763
764
765/*
766** {======================================================
767** Finalization
768** =======================================================
769*/
770
771static void checkSizes (lua_State *L) {
772  global_State *g = G(L);
773  if (g->gckind != KGC_EMERGENCY) {  /* do not change sizes in emergency */
774    int hs = g->strt.size / 2;  /* half the size of the string table */
775    if (g->strt.nuse < cast(lu_int32, hs))  /* using less than that half? */
776      luaS_resize(L, hs);  /* halve its size */
777    luaZ_freebuffer(L, &g->buff);  /* free concatenation buffer */
778  }
779}
780
781
782static GCObject *udata2finalize (global_State *g) {
783  GCObject *o = g->tobefnz;  /* get first element */
784  lua_assert(isfinalized(o));
785  g->tobefnz = gch(o)->next;  /* remove it from 'tobefnz' list */
786  gch(o)->next = g->allgc;  /* return it to 'allgc' list */
787  g->allgc = o;
788  resetbit(gch(o)->marked, SEPARATED);  /* mark that it is not in 'tobefnz' */
789  lua_assert(!isold(o));  /* see MOVE OLD rule */
790  if (!keepinvariantout(g))  /* not keeping invariant? */
791    makewhite(g, o);  /* "sweep" object */
792  return o;
793}
794
795
796static void dothecall (lua_State *L, void *ud) {
797  UNUSED(ud);
798  luaD_call(L, L->top - 2, 0, 0);
799}
800
801
802static void GCTM (lua_State *L, int propagateerrors) {
803  global_State *g = G(L);
804  const TValue *tm;
805  TValue v;
806  setgcovalue(L, &v, udata2finalize(g));
807  tm = luaT_gettmbyobj(L, &v, TM_GC);
808  if (tm != NULL && ttisfunction(tm)) {  /* is there a finalizer? */
809    int status;
810    lu_byte oldah = L->allowhook;
811    int running  = g->gcrunning;
812    L->allowhook = 0;  /* stop debug hooks during GC metamethod */
813    g->gcrunning = 0;  /* avoid GC steps */
814    setobj2s(L, L->top, tm);  /* push finalizer... */
815    setobj2s(L, L->top + 1, &v);  /* ... and its argument */
816    L->top += 2;  /* and (next line) call the finalizer */
817    status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
818    L->allowhook = oldah;  /* restore hooks */
819    g->gcrunning = running;  /* restore state */
820    if (status != LUA_OK && propagateerrors) {  /* error while running __gc? */
821      if (status == LUA_ERRRUN) {  /* is there an error object? */
822        const char *msg = (ttisstring(L->top - 1))
823                            ? svalue(L->top - 1)
824                            : "no message";
825        luaO_pushfstring(L, "error in __gc metamethod (%s)", msg);
826        status = LUA_ERRGCMM;  /* error in __gc metamethod */
827      }
828      luaD_throw(L, status);  /* re-throw error */
829    }
830  }
831}
832
833
834/*
835** move all unreachable objects (or 'all' objects) that need
836** finalization from list 'finobj' to list 'tobefnz' (to be finalized)
837*/
838static void separatetobefnz (lua_State *L, int all) {
839  global_State *g = G(L);
840  GCObject **p = &g->finobj;
841  GCObject *curr;
842  GCObject **lastnext = &g->tobefnz;
843  /* find last 'next' field in 'tobefnz' list (to add elements in its end) */
844  while (*lastnext != NULL)
845    lastnext = &gch(*lastnext)->next;
846  while ((curr = *p) != NULL) {  /* traverse all finalizable objects */
847    lua_assert(!isfinalized(curr));
848    lua_assert(testbit(gch(curr)->marked, SEPARATED));
849    if (!(iswhite(curr) || all))  /* not being collected? */
850      p = &gch(curr)->next;  /* don't bother with it */
851    else {
852      l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */
853      *p = gch(curr)->next;  /* remove 'curr' from 'finobj' list */
854      gch(curr)->next = *lastnext;  /* link at the end of 'tobefnz' list */
855      *lastnext = curr;
856      lastnext = &gch(curr)->next;
857    }
858  }
859}
860
861
862/*
863** if object 'o' has a finalizer, remove it from 'allgc' list (must
864** search the list to find it) and link it in 'finobj' list.
865*/
866void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
867  global_State *g = G(L);
868  if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */
869      isfinalized(o) ||                           /* ... or is finalized... */
870      gfasttm(g, mt, TM_GC) == NULL)                /* or has no finalizer? */
871    return;  /* nothing to be done */
872  else {  /* move 'o' to 'finobj' list */
873    GCObject **p;
874    GCheader *ho = gch(o);
875    if (g->sweepgc == &ho->next) {  /* avoid removing current sweep object */
876      lua_assert(issweepphase(g));
877      g->sweepgc = sweeptolive(L, g->sweepgc, NULL);
878    }
879    /* search for pointer pointing to 'o' */
880    for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ }
881    *p = ho->next;  /* remove 'o' from root list */
882    ho->next = g->finobj;  /* link it in list 'finobj' */
883    g->finobj = o;
884    l_setbit(ho->marked, SEPARATED);  /* mark it as such */
885    if (!keepinvariantout(g))  /* not keeping invariant? */
886      makewhite(g, o);  /* "sweep" object */
887    else
888      resetoldbit(o);  /* see MOVE OLD rule */
889  }
890}
891
892/* }====================================================== */
893
894
895/*
896** {======================================================
897** GC control
898** =======================================================
899*/
900
901
902/*
903** set a reasonable "time" to wait before starting a new GC cycle;
904** cycle will start when memory use hits threshold
905*/
906static void setpause (global_State *g, l_mem estimate) {
907  l_mem debt, threshold;
908  estimate = estimate / PAUSEADJ;  /* adjust 'estimate' */
909  threshold = (g->gcpause < MAX_LMEM / estimate)  /* overflow? */
910            ? estimate * g->gcpause  /* no overflow */
911            : MAX_LMEM;  /* overflow; truncate to maximum */
912  debt = -cast(l_mem, threshold - gettotalbytes(g));
913  luaE_setdebt(g, debt);
914}
915
916
917#define sweepphases  \
918   (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep))
919
920
921/*
922** enter first sweep phase (strings) and prepare pointers for other
923** sweep phases.  The calls to 'sweeptolive' make pointers point to an
924** object inside the list (instead of to the header), so that the real
925** sweep do not need to skip objects created between "now" and the start
926** of the real sweep.
927** Returns how many objects it swept.
928*/
929static int entersweep (lua_State *L) {
930  global_State *g = G(L);
931  int n = 0;
932  g->gcstate = GCSsweepstring;
933  lua_assert(g->sweepgc == NULL && g->sweepfin == NULL);
934  /* prepare to sweep strings, finalizable objects, and regular objects */
935  g->sweepstrgc = 0;
936  g->sweepfin = sweeptolive(L, &g->finobj, &n);
937  g->sweepgc = sweeptolive(L, &g->allgc, &n);
938  return n;
939}
940
941
942/*
943** change GC mode
944*/
945void luaC_changemode (lua_State *L, int mode) {
946  global_State *g = G(L);
947  if (mode == g->gckind) return;  /* nothing to change */
948  if (mode == KGC_GEN) {  /* change to generational mode */
949    /* make sure gray lists are consistent */
950    luaC_runtilstate(L, bitmask(GCSpropagate));
951    g->GCestimate = gettotalbytes(g);
952    g->gckind = KGC_GEN;
953  }
954  else {  /* change to incremental mode */
955    /* sweep all objects to turn them back to white
956       (as white has not changed, nothing extra will be collected) */
957    g->gckind = KGC_NORMAL;
958    entersweep(L);
959    luaC_runtilstate(L, ~sweepphases);
960  }
961}
962
963
964/*
965** call all pending finalizers
966*/
967static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
968  global_State *g = G(L);
969  while (g->tobefnz) {
970    resetoldbit(g->tobefnz);
971    GCTM(L, propagateerrors);
972  }
973}
974
975
976void luaC_freeallobjects (lua_State *L) {
977  global_State *g = G(L);
978  int i;
979  separatetobefnz(L, 1);  /* separate all objects with finalizers */
980  lua_assert(g->finobj == NULL);
981  callallpendingfinalizers(L, 0);
982  g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
983  g->gckind = KGC_NORMAL;
984  sweepwholelist(L, &g->finobj);  /* finalizers can create objs. in 'finobj' */
985  sweepwholelist(L, &g->allgc);
986  for (i = 0; i < g->strt.size; i++)  /* free all string lists */
987    sweepwholelist(L, &g->strt.hash[i]);
988  lua_assert(g->strt.nuse == 0);
989}
990
991
992static l_mem atomic (lua_State *L) {
993  global_State *g = G(L);
994  l_mem work = -cast(l_mem, g->GCmemtrav);  /* start counting work */
995  GCObject *origweak, *origall;
996  lua_assert(!iswhite(obj2gco(g->mainthread)));
997  markobject(g, L);  /* mark running thread */
998  /* registry and global metatables may be changed by API */
999  markvalue(g, &g->l_registry);
1000  markmt(g);  /* mark basic metatables */
1001  /* remark occasional upvalues of (maybe) dead threads */
1002  remarkupvals(g);
1003  propagateall(g);  /* propagate changes */
1004  work += g->GCmemtrav;  /* stop counting (do not (re)count grays) */
1005  /* traverse objects caught by write barrier and by 'remarkupvals' */
1006  retraversegrays(g);
1007  work -= g->GCmemtrav;  /* restart counting */
1008  convergeephemerons(g);
1009  /* at this point, all strongly accessible objects are marked. */
1010  /* clear values from weak tables, before checking finalizers */
1011  clearvalues(g, g->weak, NULL);
1012  clearvalues(g, g->allweak, NULL);
1013  origweak = g->weak; origall = g->allweak;
1014  work += g->GCmemtrav;  /* stop counting (objects being finalized) */
1015  separatetobefnz(L, 0);  /* separate objects to be finalized */
1016  markbeingfnz(g);  /* mark objects that will be finalized */
1017  propagateall(g);  /* remark, to propagate `preserveness' */
1018  work -= g->GCmemtrav;  /* restart counting */
1019  convergeephemerons(g);
1020  /* at this point, all resurrected objects are marked. */
1021  /* remove dead objects from weak tables */
1022  clearkeys(g, g->ephemeron, NULL);  /* clear keys from all ephemeron tables */
1023  clearkeys(g, g->allweak, NULL);  /* clear keys from all allweak tables */
1024  /* clear values from resurrected weak tables */
1025  clearvalues(g, g->weak, origweak);
1026  clearvalues(g, g->allweak, origall);
1027  g->currentwhite = cast_byte(otherwhite(g));  /* flip current white */
1028  work += g->GCmemtrav;  /* complete counting */
1029  return work;  /* estimate of memory marked by 'atomic' */
1030}
1031
1032
1033static lu_mem singlestep (lua_State *L) {
1034  global_State *g = G(L);
1035  switch (g->gcstate) {
1036    case GCSpause: {
1037      /* start to count memory traversed */
1038      g->GCmemtrav = g->strt.size * sizeof(GCObject*);
1039      lua_assert(!isgenerational(g));
1040      restartcollection(g);
1041      g->gcstate = GCSpropagate;
1042      return g->GCmemtrav;
1043    }
1044    case GCSpropagate: {
1045      if (g->gray) {
1046        lu_mem oldtrav = g->GCmemtrav;
1047        propagatemark(g);
1048        return g->GCmemtrav - oldtrav;  /* memory traversed in this step */
1049      }
1050      else {  /* no more `gray' objects */
1051        lu_mem work;
1052        int sw;
1053        g->gcstate = GCSatomic;  /* finish mark phase */
1054        g->GCestimate = g->GCmemtrav;  /* save what was counted */;
1055        work = atomic(L);  /* add what was traversed by 'atomic' */
1056        g->GCestimate += work;  /* estimate of total memory traversed */
1057        sw = entersweep(L);
1058        return work + sw * GCSWEEPCOST;
1059      }
1060    }
1061    case GCSsweepstring: {
1062      int i;
1063      for (i = 0; i < GCSWEEPMAX && g->sweepstrgc + i < g->strt.size; i++)
1064        sweepwholelist(L, &g->strt.hash[g->sweepstrgc + i]);
1065      g->sweepstrgc += i;
1066      if (g->sweepstrgc >= g->strt.size)  /* no more strings to sweep? */
1067        g->gcstate = GCSsweepudata;
1068      return i * GCSWEEPCOST;
1069    }
1070    case GCSsweepudata: {
1071      if (g->sweepfin) {
1072        g->sweepfin = sweeplist(L, g->sweepfin, GCSWEEPMAX);
1073        return GCSWEEPMAX*GCSWEEPCOST;
1074      }
1075      else {
1076        g->gcstate = GCSsweep;
1077        return 0;
1078      }
1079    }
1080    case GCSsweep: {
1081      if (g->sweepgc) {
1082        g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
1083        return GCSWEEPMAX*GCSWEEPCOST;
1084      }
1085      else {
1086        /* sweep main thread */
1087        GCObject *mt = obj2gco(g->mainthread);
1088        sweeplist(L, &mt, 1);
1089        checkSizes(L);
1090        g->gcstate = GCSpause;  /* finish collection */
1091        return GCSWEEPCOST;
1092      }
1093    }
1094    default: lua_assert(0); return 0;
1095  }
1096}
1097
1098
1099/*
1100** advances the garbage collector until it reaches a state allowed
1101** by 'statemask'
1102*/
1103void luaC_runtilstate (lua_State *L, int statesmask) {
1104  global_State *g = G(L);
1105  while (!testbit(statesmask, g->gcstate))
1106    singlestep(L);
1107}
1108
1109
1110static void generationalcollection (lua_State *L) {
1111  global_State *g = G(L);
1112  lua_assert(g->gcstate == GCSpropagate);
1113  if (g->GCestimate == 0) {  /* signal for another major collection? */
1114    luaC_fullgc(L, 0);  /* perform a full regular collection */
1115    g->GCestimate = gettotalbytes(g);  /* update control */
1116  }
1117  else {
1118    lu_mem estimate = g->GCestimate;
1119    luaC_runtilstate(L, bitmask(GCSpause));  /* run complete (minor) cycle */
1120    g->gcstate = GCSpropagate;  /* skip restart */
1121    if (gettotalbytes(g) > (estimate / 100) * g->gcmajorinc)
1122      g->GCestimate = 0;  /* signal for a major collection */
1123    else
1124      g->GCestimate = estimate;  /* keep estimate from last major coll. */
1125
1126  }
1127  setpause(g, gettotalbytes(g));
1128  lua_assert(g->gcstate == GCSpropagate);
1129}
1130
1131
1132static void incstep (lua_State *L) {
1133  global_State *g = G(L);
1134  l_mem debt = g->GCdebt;
1135  int stepmul = g->gcstepmul;
1136  if (stepmul < 40) stepmul = 40;  /* avoid ridiculous low values (and 0) */
1137  /* convert debt from Kb to 'work units' (avoid zero debt and overflows) */
1138  debt = (debt / STEPMULADJ) + 1;
1139  debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM;
1140  do {  /* always perform at least one single step */
1141    lu_mem work = singlestep(L);  /* do some work */
1142    debt -= work;
1143  } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause);
1144  if (g->gcstate == GCSpause)
1145    setpause(g, g->GCestimate);  /* pause until next cycle */
1146  else {
1147    debt = (debt / stepmul) * STEPMULADJ;  /* convert 'work units' to Kb */
1148    luaE_setdebt(g, debt);
1149  }
1150}
1151
1152
1153/*
1154** performs a basic GC step
1155*/
1156void luaC_forcestep (lua_State *L) {
1157  global_State *g = G(L);
1158  int i;
1159  if (isgenerational(g)) generationalcollection(L);
1160  else incstep(L);
1161  /* run a few finalizers (or all of them at the end of a collect cycle) */
1162  for (i = 0; g->tobefnz && (i < GCFINALIZENUM || g->gcstate == GCSpause); i++)
1163    GCTM(L, 1);  /* call one finalizer */
1164}
1165
1166
1167/*
1168** performs a basic GC step only if collector is running
1169*/
1170void luaC_step (lua_State *L) {
1171  global_State *g = G(L);
1172  if (g->gcrunning) luaC_forcestep(L);
1173  else luaE_setdebt(g, -GCSTEPSIZE);  /* avoid being called too often */
1174}
1175
1176
1177
1178/*
1179** performs a full GC cycle; if "isemergency", does not call
1180** finalizers (which could change stack positions)
1181*/
1182void luaC_fullgc (lua_State *L, int isemergency) {
1183  global_State *g = G(L);
1184  int origkind = g->gckind;
1185  lua_assert(origkind != KGC_EMERGENCY);
1186  if (isemergency)  /* do not run finalizers during emergency GC */
1187    g->gckind = KGC_EMERGENCY;
1188  else {
1189    g->gckind = KGC_NORMAL;
1190    callallpendingfinalizers(L, 1);
1191  }
1192  if (keepinvariant(g)) {  /* may there be some black objects? */
1193    /* must sweep all objects to turn them back to white
1194       (as white has not changed, nothing will be collected) */
1195    entersweep(L);
1196  }
1197  /* finish any pending sweep phase to start a new cycle */
1198  luaC_runtilstate(L, bitmask(GCSpause));
1199  luaC_runtilstate(L, ~bitmask(GCSpause));  /* start new collection */
1200  luaC_runtilstate(L, bitmask(GCSpause));  /* run entire collection */
1201  if (origkind == KGC_GEN) {  /* generational mode? */
1202    /* generational mode must be kept in propagate phase */
1203    luaC_runtilstate(L, bitmask(GCSpropagate));
1204  }
1205  g->gckind = origkind;
1206  setpause(g, gettotalbytes(g));
1207  if (!isemergency)   /* do not run finalizers during emergency GC */
1208    callallpendingfinalizers(L, 1);
1209}
1210
1211/* }====================================================== */
1212
1213
Property changes on: trunk/src/lib/lua/lgc.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/lcorolib.c
r0r22721
1/*
2** $Id: lcorolib.c,v 1.5 2013/02/21 13:44:53 roberto Exp $
3** Coroutine Library
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdlib.h>
9
10
11#define lcorolib_c
12#define LUA_LIB
13
14#include "lua.h"
15
16#include "lauxlib.h"
17#include "lualib.h"
18
19
20static int auxresume (lua_State *L, lua_State *co, int narg) {
21  int status;
22  if (!lua_checkstack(co, narg)) {
23    lua_pushliteral(L, "too many arguments to resume");
24    return -1;  /* error flag */
25  }
26  if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) {
27    lua_pushliteral(L, "cannot resume dead coroutine");
28    return -1;  /* error flag */
29  }
30  lua_xmove(L, co, narg);
31  status = lua_resume(co, L, narg);
32  if (status == LUA_OK || status == LUA_YIELD) {
33    int nres = lua_gettop(co);
34    if (!lua_checkstack(L, nres + 1)) {
35      lua_pop(co, nres);  /* remove results anyway */
36      lua_pushliteral(L, "too many results to resume");
37      return -1;  /* error flag */
38    }
39    lua_xmove(co, L, nres);  /* move yielded values */
40    return nres;
41  }
42  else {
43    lua_xmove(co, L, 1);  /* move error message */
44    return -1;  /* error flag */
45  }
46}
47
48
49static int luaB_coresume (lua_State *L) {
50  lua_State *co = lua_tothread(L, 1);
51  int r;
52  luaL_argcheck(L, co, 1, "coroutine expected");
53  r = auxresume(L, co, lua_gettop(L) - 1);
54  if (r < 0) {
55    lua_pushboolean(L, 0);
56    lua_insert(L, -2);
57    return 2;  /* return false + error message */
58  }
59  else {
60    lua_pushboolean(L, 1);
61    lua_insert(L, -(r + 1));
62    return r + 1;  /* return true + `resume' returns */
63  }
64}
65
66
67static int luaB_auxwrap (lua_State *L) {
68  lua_State *co = lua_tothread(L, lua_upvalueindex(1));
69  int r = auxresume(L, co, lua_gettop(L));
70  if (r < 0) {
71    if (lua_isstring(L, -1)) {  /* error object is a string? */
72      luaL_where(L, 1);  /* add extra info */
73      lua_insert(L, -2);
74      lua_concat(L, 2);
75    }
76    return lua_error(L);  /* propagate error */
77  }
78  return r;
79}
80
81
82static int luaB_cocreate (lua_State *L) {
83  lua_State *NL;
84  luaL_checktype(L, 1, LUA_TFUNCTION);
85  NL = lua_newthread(L);
86  lua_pushvalue(L, 1);  /* move function to top */
87  lua_xmove(L, NL, 1);  /* move function from L to NL */
88  return 1;
89}
90
91
92static int luaB_cowrap (lua_State *L) {
93  luaB_cocreate(L);
94  lua_pushcclosure(L, luaB_auxwrap, 1);
95  return 1;
96}
97
98
99static int luaB_yield (lua_State *L) {
100  return lua_yield(L, lua_gettop(L));
101}
102
103
104static int luaB_costatus (lua_State *L) {
105  lua_State *co = lua_tothread(L, 1);
106  luaL_argcheck(L, co, 1, "coroutine expected");
107  if (L == co) lua_pushliteral(L, "running");
108  else {
109    switch (lua_status(co)) {
110      case LUA_YIELD:
111        lua_pushliteral(L, "suspended");
112        break;
113      case LUA_OK: {
114        lua_Debug ar;
115        if (lua_getstack(co, 0, &ar) > 0)  /* does it have frames? */
116          lua_pushliteral(L, "normal");  /* it is running */
117        else if (lua_gettop(co) == 0)
118            lua_pushliteral(L, "dead");
119        else
120          lua_pushliteral(L, "suspended");  /* initial state */
121        break;
122      }
123      default:  /* some error occurred */
124        lua_pushliteral(L, "dead");
125        break;
126    }
127  }
128  return 1;
129}
130
131
132static int luaB_corunning (lua_State *L) {
133  int ismain = lua_pushthread(L);
134  lua_pushboolean(L, ismain);
135  return 2;
136}
137
138
139static const luaL_Reg co_funcs[] = {
140  {"create", luaB_cocreate},
141  {"resume", luaB_coresume},
142  {"running", luaB_corunning},
143  {"status", luaB_costatus},
144  {"wrap", luaB_cowrap},
145  {"yield", luaB_yield},
146  {NULL, NULL}
147};
148
149
150
151LUAMOD_API int luaopen_coroutine (lua_State *L) {
152  luaL_newlib(L, co_funcs);
153  return 1;
154}
155
Property changes on: trunk/src/lib/lua/lcorolib.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/loadlib.c
r0r22721
1/*
2** $Id: loadlib.c,v 1.111 2012/05/30 12:33:44 roberto Exp $
3** Dynamic library loader for Lua
4** See Copyright Notice in lua.h
5**
6** This module contains an implementation of loadlib for Unix systems
7** that have dlfcn, an implementation for Windows, and a stub for other
8** systems.
9*/
10
11
12/*
13** if needed, includes windows header before everything else
14*/
15#if defined(_WIN32)
16#include <windows.h>
17#endif
18
19
20#include <stdlib.h>
21#include <string.h>
22
23
24#define loadlib_c
25#define LUA_LIB
26
27#include "lua.h"
28
29#include "lauxlib.h"
30#include "lualib.h"
31
32
33/*
34** LUA_PATH and LUA_CPATH are the names of the environment
35** variables that Lua check to set its paths.
36*/
37#if !defined(LUA_PATH)
38#define LUA_PATH   "LUA_PATH"
39#endif
40
41#if !defined(LUA_CPATH)
42#define LUA_CPATH   "LUA_CPATH"
43#endif
44
45#define LUA_PATHSUFFIX      "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
46
47#define LUA_PATHVERSION      LUA_PATH LUA_PATHSUFFIX
48#define LUA_CPATHVERSION   LUA_CPATH LUA_PATHSUFFIX
49
50/*
51** LUA_PATH_SEP is the character that separates templates in a path.
52** LUA_PATH_MARK is the string that marks the substitution points in a
53** template.
54** LUA_EXEC_DIR in a Windows path is replaced by the executable's
55** directory.
56** LUA_IGMARK is a mark to ignore all before it when building the
57** luaopen_ function name.
58*/
59#if !defined (LUA_PATH_SEP)
60#define LUA_PATH_SEP      ";"
61#endif
62#if !defined (LUA_PATH_MARK)
63#define LUA_PATH_MARK      "?"
64#endif
65#if !defined (LUA_EXEC_DIR)
66#define LUA_EXEC_DIR      "!"
67#endif
68#if !defined (LUA_IGMARK)
69#define LUA_IGMARK      "-"
70#endif
71
72
73/*
74** LUA_CSUBSEP is the character that replaces dots in submodule names
75** when searching for a C loader.
76** LUA_LSUBSEP is the character that replaces dots in submodule names
77** when searching for a Lua loader.
78*/
79#if !defined(LUA_CSUBSEP)
80#define LUA_CSUBSEP      LUA_DIRSEP
81#endif
82
83#if !defined(LUA_LSUBSEP)
84#define LUA_LSUBSEP      LUA_DIRSEP
85#endif
86
87
88/* prefix for open functions in C libraries */
89#define LUA_POF      "luaopen_"
90
91/* separator for open functions in C libraries */
92#define LUA_OFSEP   "_"
93
94
95/* table (in the registry) that keeps handles for all loaded C libraries */
96#define CLIBS      "_CLIBS"
97
98#define LIB_FAIL   "open"
99
100
101/* error codes for ll_loadfunc */
102#define ERRLIB      1
103#define ERRFUNC      2
104
105#define setprogdir(L)      ((void)0)
106
107
108/*
109** system-dependent functions
110*/
111static void ll_unloadlib (void *lib);
112static void *ll_load (lua_State *L, const char *path, int seeglb);
113static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
114
115
116
117#if defined(LUA_USE_DLOPEN)
118/*
119** {========================================================================
120** This is an implementation of loadlib based on the dlfcn interface.
121** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
122** NetBSD, AIX 4.2, HPUX 11, and  probably most other Unix flavors, at least
123** as an emulation layer on top of native functions.
124** =========================================================================
125*/
126
127#include <dlfcn.h>
128
129static void ll_unloadlib (void *lib) {
130  dlclose(lib);
131}
132
133
134static void *ll_load (lua_State *L, const char *path, int seeglb) {
135  void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL));
136  if (lib == NULL) lua_pushstring(L, dlerror());
137  return lib;
138}
139
140
141static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
142  lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
143  if (f == NULL) lua_pushstring(L, dlerror());
144  return f;
145}
146
147/* }====================================================== */
148
149
150
151#elif defined(LUA_DL_DLL)
152/*
153** {======================================================================
154** This is an implementation of loadlib for Windows using native functions.
155** =======================================================================
156*/
157
158#undef setprogdir
159
160/*
161** optional flags for LoadLibraryEx
162*/
163#if !defined(LUA_LLE_FLAGS)
164#define LUA_LLE_FLAGS   0
165#endif
166
167
168static void setprogdir (lua_State *L) {
169  char buff[MAX_PATH + 1];
170  char *lb;
171  DWORD nsize = sizeof(buff)/sizeof(char);
172  DWORD n = GetModuleFileNameA(NULL, buff, nsize);
173  if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
174    luaL_error(L, "unable to get ModuleFileName");
175  else {
176    *lb = '\0';
177    luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
178    lua_remove(L, -2);  /* remove original string */
179  }
180}
181
182
183static void pusherror (lua_State *L) {
184  int error = GetLastError();
185  char buffer[128];
186  if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
187      NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL))
188    lua_pushstring(L, buffer);
189  else
190    lua_pushfstring(L, "system error %d\n", error);
191}
192
193static void ll_unloadlib (void *lib) {
194  FreeLibrary((HMODULE)lib);
195}
196
197
198static void *ll_load (lua_State *L, const char *path, int seeglb) {
199  HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS);
200  (void)(seeglb);  /* not used: symbols are 'global' by default */
201  if (lib == NULL) pusherror(L);
202  return lib;
203}
204
205
206static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
207  lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym);
208  if (f == NULL) pusherror(L);
209  return f;
210}
211
212/* }====================================================== */
213
214
215#else
216/*
217** {======================================================
218** Fallback for other systems
219** =======================================================
220*/
221
222#undef LIB_FAIL
223#define LIB_FAIL   "absent"
224
225
226#define DLMSG   "dynamic libraries not enabled; check your Lua installation"
227
228
229static void ll_unloadlib (void *lib) {
230  (void)(lib);  /* not used */
231}
232
233
234static void *ll_load (lua_State *L, const char *path, int seeglb) {
235  (void)(path); (void)(seeglb);  /* not used */
236  lua_pushliteral(L, DLMSG);
237  return NULL;
238}
239
240
241static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
242  (void)(lib); (void)(sym);  /* not used */
243  lua_pushliteral(L, DLMSG);
244  return NULL;
245}
246
247/* }====================================================== */
248#endif
249
250
251static void *ll_checkclib (lua_State *L, const char *path) {
252  void *plib;
253  lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
254  lua_getfield(L, -1, path);
255  plib = lua_touserdata(L, -1);  /* plib = CLIBS[path] */
256  lua_pop(L, 2);  /* pop CLIBS table and 'plib' */
257  return plib;
258}
259
260
261static void ll_addtoclib (lua_State *L, const char *path, void *plib) {
262  lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
263  lua_pushlightuserdata(L, plib);
264  lua_pushvalue(L, -1);
265  lua_setfield(L, -3, path);  /* CLIBS[path] = plib */
266  lua_rawseti(L, -2, luaL_len(L, -2) + 1);  /* CLIBS[#CLIBS + 1] = plib */
267  lua_pop(L, 1);  /* pop CLIBS table */
268}
269
270
271/*
272** __gc tag method for CLIBS table: calls 'll_unloadlib' for all lib
273** handles in list CLIBS
274*/
275static int gctm (lua_State *L) {
276  int n = luaL_len(L, 1);
277  for (; n >= 1; n--) {  /* for each handle, in reverse order */
278    lua_rawgeti(L, 1, n);  /* get handle CLIBS[n] */
279    ll_unloadlib(lua_touserdata(L, -1));
280    lua_pop(L, 1);  /* pop handle */
281  }
282  return 0;
283}
284
285
286static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
287  void *reg = ll_checkclib(L, path);  /* check loaded C libraries */
288  if (reg == NULL) {  /* must load library? */
289    reg = ll_load(L, path, *sym == '*');
290    if (reg == NULL) return ERRLIB;  /* unable to load library */
291    ll_addtoclib(L, path, reg);
292  }
293  if (*sym == '*') {  /* loading only library (no function)? */
294    lua_pushboolean(L, 1);  /* return 'true' */
295    return 0;  /* no errors */
296  }
297  else {
298    lua_CFunction f = ll_sym(L, reg, sym);
299    if (f == NULL)
300      return ERRFUNC;  /* unable to find function */
301    lua_pushcfunction(L, f);  /* else create new function */
302    return 0;  /* no errors */
303  }
304}
305
306
307static int ll_loadlib (lua_State *L) {
308  const char *path = luaL_checkstring(L, 1);
309  const char *init = luaL_checkstring(L, 2);
310  int stat = ll_loadfunc(L, path, init);
311  if (stat == 0)  /* no errors? */
312    return 1;  /* return the loaded function */
313  else {  /* error; error message is on stack top */
314    lua_pushnil(L);
315    lua_insert(L, -2);
316    lua_pushstring(L, (stat == ERRLIB) ?  LIB_FAIL : "init");
317    return 3;  /* return nil, error message, and where */
318  }
319}
320
321
322
323/*
324** {======================================================
325** 'require' function
326** =======================================================
327*/
328
329
330static int readable (const char *filename) {
331  FILE *f = fopen(filename, "r");  /* try to open file */
332  if (f == NULL) return 0;  /* open failed */
333  fclose(f);
334  return 1;
335}
336
337
338static const char *pushnexttemplate (lua_State *L, const char *path) {
339  const char *l;
340  while (*path == *LUA_PATH_SEP) path++;  /* skip separators */
341  if (*path == '\0') return NULL;  /* no more templates */
342  l = strchr(path, *LUA_PATH_SEP);  /* find next separator */
343  if (l == NULL) l = path + strlen(path);
344  lua_pushlstring(L, path, l - path);  /* template */
345  return l;
346}
347
348
349static const char *searchpath (lua_State *L, const char *name,
350                                             const char *path,
351                                             const char *sep,
352                                             const char *dirsep) {
353  luaL_Buffer msg;  /* to build error message */
354  luaL_buffinit(L, &msg);
355  if (*sep != '\0')  /* non-empty separator? */
356    name = luaL_gsub(L, name, sep, dirsep);  /* replace it by 'dirsep' */
357  while ((path = pushnexttemplate(L, path)) != NULL) {
358    const char *filename = luaL_gsub(L, lua_tostring(L, -1),
359                                     LUA_PATH_MARK, name);
360    lua_remove(L, -2);  /* remove path template */
361    if (readable(filename))  /* does file exist and is readable? */
362      return filename;  /* return that file name */
363    lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
364    lua_remove(L, -2);  /* remove file name */
365    luaL_addvalue(&msg);  /* concatenate error msg. entry */
366  }
367  luaL_pushresult(&msg);  /* create error message */
368  return NULL;  /* not found */
369}
370
371
372static int ll_searchpath (lua_State *L) {
373  const char *f = searchpath(L, luaL_checkstring(L, 1),
374                                luaL_checkstring(L, 2),
375                                luaL_optstring(L, 3, "."),
376                                luaL_optstring(L, 4, LUA_DIRSEP));
377  if (f != NULL) return 1;
378  else {  /* error message is on top of the stack */
379    lua_pushnil(L);
380    lua_insert(L, -2);
381    return 2;  /* return nil + error message */
382  }
383}
384
385
386static const char *findfile (lua_State *L, const char *name,
387                                           const char *pname,
388                                           const char *dirsep) {
389  const char *path;
390  lua_getfield(L, lua_upvalueindex(1), pname);
391  path = lua_tostring(L, -1);
392  if (path == NULL)
393    luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
394  return searchpath(L, name, path, ".", dirsep);
395}
396
397
398static int checkload (lua_State *L, int stat, const char *filename) {
399  if (stat) {  /* module loaded successfully? */
400    lua_pushstring(L, filename);  /* will be 2nd argument to module */
401    return 2;  /* return open function and file name */
402  }
403  else
404    return luaL_error(L, "error loading module " LUA_QS
405                         " from file " LUA_QS ":\n\t%s",
406                          lua_tostring(L, 1), filename, lua_tostring(L, -1));
407}
408
409
410static int searcher_Lua (lua_State *L) {
411  const char *filename;
412  const char *name = luaL_checkstring(L, 1);
413  filename = findfile(L, name, "path", LUA_LSUBSEP);
414  if (filename == NULL) return 1;  /* module not found in this path */
415  return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename);
416}
417
418
419static int loadfunc (lua_State *L, const char *filename, const char *modname) {
420  const char *funcname;
421  const char *mark;
422  modname = luaL_gsub(L, modname, ".", LUA_OFSEP);
423  mark = strchr(modname, *LUA_IGMARK);
424  if (mark) {
425    int stat;
426    funcname = lua_pushlstring(L, modname, mark - modname);
427    funcname = lua_pushfstring(L, LUA_POF"%s", funcname);
428    stat = ll_loadfunc(L, filename, funcname);
429    if (stat != ERRFUNC) return stat;
430    modname = mark + 1;  /* else go ahead and try old-style name */
431  }
432  funcname = lua_pushfstring(L, LUA_POF"%s", modname);
433  return ll_loadfunc(L, filename, funcname);
434}
435
436
437static int searcher_C (lua_State *L) {
438  const char *name = luaL_checkstring(L, 1);
439  const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP);
440  if (filename == NULL) return 1;  /* module not found in this path */
441  return checkload(L, (loadfunc(L, filename, name) == 0), filename);
442}
443
444
445static int searcher_Croot (lua_State *L) {
446  const char *filename;
447  const char *name = luaL_checkstring(L, 1);
448  const char *p = strchr(name, '.');
449  int stat;
450  if (p == NULL) return 0;  /* is root */
451  lua_pushlstring(L, name, p - name);
452  filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP);
453  if (filename == NULL) return 1;  /* root not found */
454  if ((stat = loadfunc(L, filename, name)) != 0) {
455    if (stat != ERRFUNC)
456      return checkload(L, 0, filename);  /* real error */
457    else {  /* open function not found */
458      lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
459                         name, filename);
460      return 1;
461    }
462  }
463  lua_pushstring(L, filename);  /* will be 2nd argument to module */
464  return 2;
465}
466
467
468static int searcher_preload (lua_State *L) {
469  const char *name = luaL_checkstring(L, 1);
470  lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD");
471  lua_getfield(L, -1, name);
472  if (lua_isnil(L, -1))  /* not found? */
473    lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
474  return 1;
475}
476
477
478static void findloader (lua_State *L, const char *name) {
479  int i;
480  luaL_Buffer msg;  /* to build error message */
481  luaL_buffinit(L, &msg);
482  lua_getfield(L, lua_upvalueindex(1), "searchers");  /* will be at index 3 */
483  if (!lua_istable(L, 3))
484    luaL_error(L, LUA_QL("package.searchers") " must be a table");
485  /*  iterate over available searchers to find a loader */
486  for (i = 1; ; i++) {
487    lua_rawgeti(L, 3, i);  /* get a searcher */
488    if (lua_isnil(L, -1)) {  /* no more searchers? */
489      lua_pop(L, 1);  /* remove nil */
490      luaL_pushresult(&msg);  /* create error message */
491      luaL_error(L, "module " LUA_QS " not found:%s",
492                    name, lua_tostring(L, -1));
493    }
494    lua_pushstring(L, name);
495    lua_call(L, 1, 2);  /* call it */
496    if (lua_isfunction(L, -2))  /* did it find a loader? */
497      return;  /* module loader found */
498    else if (lua_isstring(L, -2)) {  /* searcher returned error message? */
499      lua_pop(L, 1);  /* remove extra return */
500      luaL_addvalue(&msg);  /* concatenate error message */
501    }
502    else
503      lua_pop(L, 2);  /* remove both returns */
504  }
505}
506
507
508static int ll_require (lua_State *L) {
509  const char *name = luaL_checkstring(L, 1);
510  lua_settop(L, 1);  /* _LOADED table will be at index 2 */
511  lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
512  lua_getfield(L, 2, name);  /* _LOADED[name] */
513  if (lua_toboolean(L, -1))  /* is it there? */
514    return 1;  /* package is already loaded */
515  /* else must load package */
516  lua_pop(L, 1);  /* remove 'getfield' result */
517  findloader(L, name);
518  lua_pushstring(L, name);  /* pass name as argument to module loader */
519  lua_insert(L, -2);  /* name is 1st argument (before search data) */
520  lua_call(L, 2, 1);  /* run loader to load module */
521  if (!lua_isnil(L, -1))  /* non-nil return? */
522    lua_setfield(L, 2, name);  /* _LOADED[name] = returned value */
523  lua_getfield(L, 2, name);
524  if (lua_isnil(L, -1)) {   /* module did not set a value? */
525    lua_pushboolean(L, 1);  /* use true as result */
526    lua_pushvalue(L, -1);  /* extra copy to be returned */
527    lua_setfield(L, 2, name);  /* _LOADED[name] = true */
528  }
529  return 1;
530}
531
532/* }====================================================== */
533
534
535
536/*
537** {======================================================
538** 'module' function
539** =======================================================
540*/
541#if defined(LUA_COMPAT_MODULE)
542
543/*
544** changes the environment variable of calling function
545*/
546static void set_env (lua_State *L) {
547  lua_Debug ar;
548  if (lua_getstack(L, 1, &ar) == 0 ||
549      lua_getinfo(L, "f", &ar) == 0 ||  /* get calling function */
550      lua_iscfunction(L, -1))
551    luaL_error(L, LUA_QL("module") " not called from a Lua function");
552  lua_pushvalue(L, -2);  /* copy new environment table to top */
553  lua_setupvalue(L, -2, 1);
554  lua_pop(L, 1);  /* remove function */
555}
556
557
558static void dooptions (lua_State *L, int n) {
559  int i;
560  for (i = 2; i <= n; i++) {
561    if (lua_isfunction(L, i)) {  /* avoid 'calling' extra info. */
562      lua_pushvalue(L, i);  /* get option (a function) */
563      lua_pushvalue(L, -2);  /* module */
564      lua_call(L, 1, 0);
565    }
566  }
567}
568
569
570static void modinit (lua_State *L, const char *modname) {
571  const char *dot;
572  lua_pushvalue(L, -1);
573  lua_setfield(L, -2, "_M");  /* module._M = module */
574  lua_pushstring(L, modname);
575  lua_setfield(L, -2, "_NAME");
576  dot = strrchr(modname, '.');  /* look for last dot in module name */
577  if (dot == NULL) dot = modname;
578  else dot++;
579  /* set _PACKAGE as package name (full module name minus last part) */
580  lua_pushlstring(L, modname, dot - modname);
581  lua_setfield(L, -2, "_PACKAGE");
582}
583
584
585static int ll_module (lua_State *L) {
586  const char *modname = luaL_checkstring(L, 1);
587  int lastarg = lua_gettop(L);  /* last parameter */
588  luaL_pushmodule(L, modname, 1);  /* get/create module table */
589  /* check whether table already has a _NAME field */
590  lua_getfield(L, -1, "_NAME");
591  if (!lua_isnil(L, -1))  /* is table an initialized module? */
592    lua_pop(L, 1);
593  else {  /* no; initialize it */
594    lua_pop(L, 1);
595    modinit(L, modname);
596  }
597  lua_pushvalue(L, -1);
598  set_env(L);
599  dooptions(L, lastarg);
600  return 1;
601}
602
603
604static int ll_seeall (lua_State *L) {
605  luaL_checktype(L, 1, LUA_TTABLE);
606  if (!lua_getmetatable(L, 1)) {
607    lua_createtable(L, 0, 1); /* create new metatable */
608    lua_pushvalue(L, -1);
609    lua_setmetatable(L, 1);
610  }
611  lua_pushglobaltable(L);
612  lua_setfield(L, -2, "__index");  /* mt.__index = _G */
613  return 0;
614}
615
616#endif
617/* }====================================================== */
618
619
620
621/* auxiliary mark (for internal use) */
622#define AUXMARK      "\1"
623
624
625/*
626** return registry.LUA_NOENV as a boolean
627*/
628static int noenv (lua_State *L) {
629  int b;
630  lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
631  b = lua_toboolean(L, -1);
632  lua_pop(L, 1);  /* remove value */
633  return b;
634}
635
636
637static void setpath (lua_State *L, const char *fieldname, const char *envname1,
638                                   const char *envname2, const char *def) {
639  const char *path = getenv(envname1);
640  if (path == NULL)  /* no environment variable? */
641    path = getenv(envname2);  /* try alternative name */
642  if (path == NULL || noenv(L))  /* no environment variable? */
643    lua_pushstring(L, def);  /* use default */
644  else {
645    /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
646    path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP,
647                              LUA_PATH_SEP AUXMARK LUA_PATH_SEP);
648    luaL_gsub(L, path, AUXMARK, def);
649    lua_remove(L, -2);
650  }
651  setprogdir(L);
652  lua_setfield(L, -2, fieldname);
653}
654
655
656static const luaL_Reg pk_funcs[] = {
657  {"loadlib", ll_loadlib},
658  {"searchpath", ll_searchpath},
659#if defined(LUA_COMPAT_MODULE)
660  {"seeall", ll_seeall},
661#endif
662  {NULL, NULL}
663};
664
665
666static const luaL_Reg ll_funcs[] = {
667#if defined(LUA_COMPAT_MODULE)
668  {"module", ll_module},
669#endif
670  {"require", ll_require},
671  {NULL, NULL}
672};
673
674
675static void createsearcherstable (lua_State *L) {
676  static const lua_CFunction searchers[] =
677    {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL};
678  int i;
679  /* create 'searchers' table */
680  lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0);
681  /* fill it with pre-defined searchers */
682  for (i=0; searchers[i] != NULL; i++) {
683    lua_pushvalue(L, -2);  /* set 'package' as upvalue for all searchers */
684    lua_pushcclosure(L, searchers[i], 1);
685    lua_rawseti(L, -2, i+1);
686  }
687}
688
689
690LUAMOD_API int luaopen_package (lua_State *L) {
691  /* create table CLIBS to keep track of loaded C libraries */
692  luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS);
693  lua_createtable(L, 0, 1);  /* metatable for CLIBS */
694  lua_pushcfunction(L, gctm);
695  lua_setfield(L, -2, "__gc");  /* set finalizer for CLIBS table */
696  lua_setmetatable(L, -2);
697  /* create `package' table */
698  luaL_newlib(L, pk_funcs);
699  createsearcherstable(L);
700#if defined(LUA_COMPAT_LOADERS)
701  lua_pushvalue(L, -1);  /* make a copy of 'searchers' table */
702  lua_setfield(L, -3, "loaders");  /* put it in field `loaders' */
703#endif
704  lua_setfield(L, -2, "searchers");  /* put it in field 'searchers' */
705  /* set field 'path' */
706  setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT);
707  /* set field 'cpath' */
708  setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT);
709  /* store config information */
710  lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
711                     LUA_EXEC_DIR "\n" LUA_IGMARK "\n");
712  lua_setfield(L, -2, "config");
713  /* set field `loaded' */
714  luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
715  lua_setfield(L, -2, "loaded");
716  /* set field `preload' */
717  luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
718  lua_setfield(L, -2, "preload");
719  lua_pushglobaltable(L);
720  lua_pushvalue(L, -2);  /* set 'package' as upvalue for next lib */
721  luaL_setfuncs(L, ll_funcs, 1);  /* open lib into global table */
722  lua_pop(L, 1);  /* pop global table */
723  return 1;  /* return 'package' table */
724}
725
Property changes on: trunk/src/lib/lua/loadlib.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lfunc.c
r0r22721
1/*
2** $Id: lfunc.c,v 2.30 2012/10/03 12:36:46 roberto Exp $
3** Auxiliary functions to manipulate prototypes and closures
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stddef.h>
9
10#define lfunc_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "lfunc.h"
16#include "lgc.h"
17#include "lmem.h"
18#include "lobject.h"
19#include "lstate.h"
20
21
22
23Closure *luaF_newCclosure (lua_State *L, int n) {
24  Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n), NULL, 0)->cl;
25  c->c.nupvalues = cast_byte(n);
26  return c;
27}
28
29
30Closure *luaF_newLclosure (lua_State *L, int n) {
31  Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n), NULL, 0)->cl;
32  c->l.p = NULL;
33  c->l.nupvalues = cast_byte(n);
34  while (n--) c->l.upvals[n] = NULL;
35  return c;
36}
37
38
39UpVal *luaF_newupval (lua_State *L) {
40  UpVal *uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), NULL, 0)->uv;
41  uv->v = &uv->u.value;
42  setnilvalue(uv->v);
43  return uv;
44}
45
46
47UpVal *luaF_findupval (lua_State *L, StkId level) {
48  global_State *g = G(L);
49  GCObject **pp = &L->openupval;
50  UpVal *p;
51  UpVal *uv;
52  while (*pp != NULL && (p = gco2uv(*pp))->v >= level) {
53    GCObject *o = obj2gco(p);
54    lua_assert(p->v != &p->u.value);
55    lua_assert(!isold(o) || isold(obj2gco(L)));
56    if (p->v == level) {  /* found a corresponding upvalue? */
57      if (isdead(g, o))  /* is it dead? */
58        changewhite(o);  /* resurrect it */
59      return p;
60    }
61    pp = &p->next;
62  }
63  /* not found: create a new one */
64  uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), pp, 0)->uv;
65  uv->v = level;  /* current value lives in the stack */
66  uv->u.l.prev = &g->uvhead;  /* double link it in `uvhead' list */
67  uv->u.l.next = g->uvhead.u.l.next;
68  uv->u.l.next->u.l.prev = uv;
69  g->uvhead.u.l.next = uv;
70  lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
71  return uv;
72}
73
74
75static void unlinkupval (UpVal *uv) {
76  lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
77  uv->u.l.next->u.l.prev = uv->u.l.prev;  /* remove from `uvhead' list */
78  uv->u.l.prev->u.l.next = uv->u.l.next;
79}
80
81
82void luaF_freeupval (lua_State *L, UpVal *uv) {
83  if (uv->v != &uv->u.value)  /* is it open? */
84    unlinkupval(uv);  /* remove from open list */
85  luaM_free(L, uv);  /* free upvalue */
86}
87
88
89void luaF_close (lua_State *L, StkId level) {
90  UpVal *uv;
91  global_State *g = G(L);
92  while (L->openupval != NULL && (uv = gco2uv(L->openupval))->v >= level) {
93    GCObject *o = obj2gco(uv);
94    lua_assert(!isblack(o) && uv->v != &uv->u.value);
95    L->openupval = uv->next;  /* remove from `open' list */
96    if (isdead(g, o))
97      luaF_freeupval(L, uv);  /* free upvalue */
98    else {
99      unlinkupval(uv);  /* remove upvalue from 'uvhead' list */
100      setobj(L, &uv->u.value, uv->v);  /* move value to upvalue slot */
101      uv->v = &uv->u.value;  /* now current value lives here */
102      gch(o)->next = g->allgc;  /* link upvalue into 'allgc' list */
103      g->allgc = o;
104      luaC_checkupvalcolor(g, uv);
105    }
106  }
107}
108
109
110Proto *luaF_newproto (lua_State *L) {
111  Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p;
112  f->k = NULL;
113  f->sizek = 0;
114  f->p = NULL;
115  f->sizep = 0;
116  f->code = NULL;
117  f->cache = NULL;
118  f->sizecode = 0;
119  f->lineinfo = NULL;
120  f->sizelineinfo = 0;
121  f->upvalues = NULL;
122  f->sizeupvalues = 0;
123  f->numparams = 0;
124  f->is_vararg = 0;
125  f->maxstacksize = 0;
126  f->locvars = NULL;
127  f->sizelocvars = 0;
128  f->linedefined = 0;
129  f->lastlinedefined = 0;
130  f->source = NULL;
131  return f;
132}
133
134
135void luaF_freeproto (lua_State *L, Proto *f) {
136  luaM_freearray(L, f->code, f->sizecode);
137  luaM_freearray(L, f->p, f->sizep);
138  luaM_freearray(L, f->k, f->sizek);
139  luaM_freearray(L, f->lineinfo, f->sizelineinfo);
140  luaM_freearray(L, f->locvars, f->sizelocvars);
141  luaM_freearray(L, f->upvalues, f->sizeupvalues);
142  luaM_free(L, f);
143}
144
145
146/*
147** Look for n-th local variable at line `line' in function `func'.
148** Returns NULL if not found.
149*/
150const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
151  int i;
152  for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
153    if (pc < f->locvars[i].endpc) {  /* is variable active? */
154      local_number--;
155      if (local_number == 0)
156        return getstr(f->locvars[i].varname);
157    }
158  }
159  return NULL;  /* not found */
160}
161
Property changes on: trunk/src/lib/lua/lfunc.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/ldebug.h
r0r22721
1/*
2** $Id: ldebug.h,v 2.7 2011/10/07 20:45:19 roberto Exp $
3** Auxiliary functions from Debug Interface module
4** See Copyright Notice in lua.h
5*/
6
7#ifndef ldebug_h
8#define ldebug_h
9
10
11#include "lstate.h"
12
13
14#define pcRel(pc, p)   (cast(int, (pc) - (p)->code) - 1)
15
16#define getfuncline(f,pc)   (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
17
18#define resethookcount(L)   (L->hookcount = L->basehookcount)
19
20/* Active Lua function (given call info) */
21#define ci_func(ci)      (clLvalue((ci)->func))
22
23
24LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
25                                                const char *opname);
26LUAI_FUNC l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2);
27LUAI_FUNC l_noret luaG_aritherror (lua_State *L, const TValue *p1,
28                                                 const TValue *p2);
29LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1,
30                                                 const TValue *p2);
31LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...);
32LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
33
34#endif
Property changes on: trunk/src/lib/lua/ldebug.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/lparser.c
r0r22721
1/*
2** $Id: lparser.c,v 2.130 2013/02/06 13:37:39 roberto Exp $
3** Lua Parser
4** See Copyright Notice in lua.h
5*/
6
7
8#include <string.h>
9
10#define lparser_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "lcode.h"
16#include "ldebug.h"
17#include "ldo.h"
18#include "lfunc.h"
19#include "llex.h"
20#include "lmem.h"
21#include "lobject.h"
22#include "lopcodes.h"
23#include "lparser.h"
24#include "lstate.h"
25#include "lstring.h"
26#include "ltable.h"
27
28
29
30/* maximum number of local variables per function (must be smaller
31   than 250, due to the bytecode format) */
32#define MAXVARS      200
33
34
35#define hasmultret(k)      ((k) == VCALL || (k) == VVARARG)
36
37
38
39/*
40** nodes for block list (list of active blocks)
41*/
42typedef struct BlockCnt {
43  struct BlockCnt *previous;  /* chain */
44  short firstlabel;  /* index of first label in this block */
45  short firstgoto;  /* index of first pending goto in this block */
46  lu_byte nactvar;  /* # active locals outside the block */
47  lu_byte upval;  /* true if some variable in the block is an upvalue */
48  lu_byte isloop;  /* true if `block' is a loop */
49} BlockCnt;
50
51
52
53/*
54** prototypes for recursive non-terminal functions
55*/
56static void statement (LexState *ls);
57static void expr (LexState *ls, expdesc *v);
58
59
60static void anchor_token (LexState *ls) {
61  /* last token from outer function must be EOS */
62  lua_assert(ls->fs != NULL || ls->t.token == TK_EOS);
63  if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
64    TString *ts = ls->t.seminfo.ts;
65    luaX_newstring(ls, getstr(ts), ts->tsv.len);
66  }
67}
68
69
70/* semantic error */
71static l_noret semerror (LexState *ls, const char *msg) {
72  ls->t.token = 0;  /* remove 'near to' from final message */
73  luaX_syntaxerror(ls, msg);
74}
75
76
77static l_noret error_expected (LexState *ls, int token) {
78  luaX_syntaxerror(ls,
79      luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token)));
80}
81
82
83static l_noret errorlimit (FuncState *fs, int limit, const char *what) {
84  lua_State *L = fs->ls->L;
85  const char *msg;
86  int line = fs->f->linedefined;
87  const char *where = (line == 0)
88                      ? "main function"
89                      : luaO_pushfstring(L, "function at line %d", line);
90  msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s",
91                             what, limit, where);
92  luaX_syntaxerror(fs->ls, msg);
93}
94
95
96static void checklimit (FuncState *fs, int v, int l, const char *what) {
97  if (v > l) errorlimit(fs, l, what);
98}
99
100
101static int testnext (LexState *ls, int c) {
102  if (ls->t.token == c) {
103    luaX_next(ls);
104    return 1;
105  }
106  else return 0;
107}
108
109
110static void check (LexState *ls, int c) {
111  if (ls->t.token != c)
112    error_expected(ls, c);
113}
114
115
116static void checknext (LexState *ls, int c) {
117  check(ls, c);
118  luaX_next(ls);
119}
120
121
122#define check_condition(ls,c,msg)   { if (!(c)) luaX_syntaxerror(ls, msg); }
123
124
125
126static void check_match (LexState *ls, int what, int who, int where) {
127  if (!testnext(ls, what)) {
128    if (where == ls->linenumber)
129      error_expected(ls, what);
130    else {
131      luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
132             "%s expected (to close %s at line %d)",
133              luaX_token2str(ls, what), luaX_token2str(ls, who), where));
134    }
135  }
136}
137
138
139static TString *str_checkname (LexState *ls) {
140  TString *ts;
141  check(ls, TK_NAME);
142  ts = ls->t.seminfo.ts;
143  luaX_next(ls);
144  return ts;
145}
146
147
148static void init_exp (expdesc *e, expkind k, int i) {
149  e->f = e->t = NO_JUMP;
150  e->k = k;
151  e->u.info = i;
152}
153
154
155static void codestring (LexState *ls, expdesc *e, TString *s) {
156  init_exp(e, VK, luaK_stringK(ls->fs, s));
157}
158
159
160static void checkname (LexState *ls, expdesc *e) {
161  codestring(ls, e, str_checkname(ls));
162}
163
164
165static int registerlocalvar (LexState *ls, TString *varname) {
166  FuncState *fs = ls->fs;
167  Proto *f = fs->f;
168  int oldsize = f->sizelocvars;
169  luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
170                  LocVar, SHRT_MAX, "local variables");
171  while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
172  f->locvars[fs->nlocvars].varname = varname;
173  luaC_objbarrier(ls->L, f, varname);
174  return fs->nlocvars++;
175}
176
177
178static void new_localvar (LexState *ls, TString *name) {
179  FuncState *fs = ls->fs;
180  Dyndata *dyd = ls->dyd;
181  int reg = registerlocalvar(ls, name);
182  checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal,
183                  MAXVARS, "local variables");
184  luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1,
185                  dyd->actvar.size, Vardesc, MAX_INT, "local variables");
186  dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg);
187}
188
189
190static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) {
191  new_localvar(ls, luaX_newstring(ls, name, sz));
192}
193
194#define new_localvarliteral(ls,v) \
195   new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1)
196
197
198static LocVar *getlocvar (FuncState *fs, int i) {
199  int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx;
200  lua_assert(idx < fs->nlocvars);
201  return &fs->f->locvars[idx];
202}
203
204
205static void adjustlocalvars (LexState *ls, int nvars) {
206  FuncState *fs = ls->fs;
207  fs->nactvar = cast_byte(fs->nactvar + nvars);
208  for (; nvars; nvars--) {
209    getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc;
210  }
211}
212
213
214static void removevars (FuncState *fs, int tolevel) {
215  fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel);
216  while (fs->nactvar > tolevel)
217    getlocvar(fs, --fs->nactvar)->endpc = fs->pc;
218}
219
220
221static int searchupvalue (FuncState *fs, TString *name) {
222  int i;
223  Upvaldesc *up = fs->f->upvalues;
224  for (i = 0; i < fs->nups; i++) {
225    if (luaS_eqstr(up[i].name, name)) return i;
226  }
227  return -1;  /* not found */
228}
229
230
231static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
232  Proto *f = fs->f;
233  int oldsize = f->sizeupvalues;
234  checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
235  luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
236                  Upvaldesc, MAXUPVAL, "upvalues");
237  while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL;
238  f->upvalues[fs->nups].instack = (v->k == VLOCAL);
239  f->upvalues[fs->nups].idx = cast_byte(v->u.info);
240  f->upvalues[fs->nups].name = name;
241  luaC_objbarrier(fs->ls->L, f, name);
242  return fs->nups++;
243}
244
245
246static int searchvar (FuncState *fs, TString *n) {
247  int i;
248  for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {
249    if (luaS_eqstr(n, getlocvar(fs, i)->varname))
250      return i;
251  }
252  return -1;  /* not found */
253}
254
255
256/*
257  Mark block where variable at given level was defined
258  (to emit close instructions later).
259*/
260static void markupval (FuncState *fs, int level) {
261  BlockCnt *bl = fs->bl;
262  while (bl->nactvar > level) bl = bl->previous;
263  bl->upval = 1;
264}
265
266
267/*
268  Find variable with given name 'n'. If it is an upvalue, add this
269  upvalue into all intermediate functions.
270*/
271static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
272  if (fs == NULL)  /* no more levels? */
273    return VVOID;  /* default is global */
274  else {
275    int v = searchvar(fs, n);  /* look up locals at current level */
276    if (v >= 0) {  /* found? */
277      init_exp(var, VLOCAL, v);  /* variable is local */
278      if (!base)
279        markupval(fs, v);  /* local will be used as an upval */
280      return VLOCAL;
281    }
282    else {  /* not found as local at current level; try upvalues */
283      int idx = searchupvalue(fs, n);  /* try existing upvalues */
284      if (idx < 0) {  /* not found? */
285        if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */
286          return VVOID;  /* not found; is a global */
287        /* else was LOCAL or UPVAL */
288        idx  = newupvalue(fs, n, var);  /* will be a new upvalue */
289      }
290      init_exp(var, VUPVAL, idx);
291      return VUPVAL;
292    }
293  }
294}
295
296
297static void singlevar (LexState *ls, expdesc *var) {
298  TString *varname = str_checkname(ls);
299  FuncState *fs = ls->fs;
300  if (singlevaraux(fs, varname, var, 1) == VVOID) {  /* global name? */
301    expdesc key;
302    singlevaraux(fs, ls->envn, var, 1);  /* get environment variable */
303    lua_assert(var->k == VLOCAL || var->k == VUPVAL);
304    codestring(ls, &key, varname);  /* key is variable name */
305    luaK_indexed(fs, var, &key);  /* env[varname] */
306  }
307}
308
309
310static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
311  FuncState *fs = ls->fs;
312  int extra = nvars - nexps;
313  if (hasmultret(e->k)) {
314    extra++;  /* includes call itself */
315    if (extra < 0) extra = 0;
316    luaK_setreturns(fs, e, extra);  /* last exp. provides the difference */
317    if (extra > 1) luaK_reserveregs(fs, extra-1);
318  }
319  else {
320    if (e->k != VVOID) luaK_exp2nextreg(fs, e);  /* close last expression */
321    if (extra > 0) {
322      int reg = fs->freereg;
323      luaK_reserveregs(fs, extra);
324      luaK_nil(fs, reg, extra);
325    }
326  }
327}
328
329
330static void enterlevel (LexState *ls) {
331  lua_State *L = ls->L;
332  ++L->nCcalls;
333  checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels");
334}
335
336
337#define leavelevel(ls)   ((ls)->L->nCcalls--)
338
339
340static void closegoto (LexState *ls, int g, Labeldesc *label) {
341  int i;
342  FuncState *fs = ls->fs;
343  Labellist *gl = &ls->dyd->gt;
344  Labeldesc *gt = &gl->arr[g];
345  lua_assert(luaS_eqstr(gt->name, label->name));
346  if (gt->nactvar < label->nactvar) {
347    TString *vname = getlocvar(fs, gt->nactvar)->varname;
348    const char *msg = luaO_pushfstring(ls->L,
349      "<goto %s> at line %d jumps into the scope of local " LUA_QS,
350      getstr(gt->name), gt->line, getstr(vname));
351    semerror(ls, msg);
352  }
353  luaK_patchlist(fs, gt->pc, label->pc);
354  /* remove goto from pending list */
355  for (i = g; i < gl->n - 1; i++)
356    gl->arr[i] = gl->arr[i + 1];
357  gl->n--;
358}
359
360
361/*
362** try to close a goto with existing labels; this solves backward jumps
363*/
364static int findlabel (LexState *ls, int g) {
365  int i;
366  BlockCnt *bl = ls->fs->bl;
367  Dyndata *dyd = ls->dyd;
368  Labeldesc *gt = &dyd->gt.arr[g];
369  /* check labels in current block for a match */
370  for (i = bl->firstlabel; i < dyd->label.n; i++) {
371    Labeldesc *lb = &dyd->label.arr[i];
372    if (luaS_eqstr(lb->name, gt->name)) {  /* correct label? */
373      if (gt->nactvar > lb->nactvar &&
374          (bl->upval || dyd->label.n > bl->firstlabel))
375        luaK_patchclose(ls->fs, gt->pc, lb->nactvar);
376      closegoto(ls, g, lb);  /* close it */
377      return 1;
378    }
379  }
380  return 0;  /* label not found; cannot close goto */
381}
382
383
384static int newlabelentry (LexState *ls, Labellist *l, TString *name,
385                          int line, int pc) {
386  int n = l->n;
387  luaM_growvector(ls->L, l->arr, n, l->size,
388                  Labeldesc, SHRT_MAX, "labels/gotos");
389  l->arr[n].name = name;
390  l->arr[n].line = line;
391  l->arr[n].nactvar = ls->fs->nactvar;
392  l->arr[n].pc = pc;
393  l->n++;
394  return n;
395}
396
397
398/*
399** check whether new label 'lb' matches any pending gotos in current
400** block; solves forward jumps
401*/
402static void findgotos (LexState *ls, Labeldesc *lb) {
403  Labellist *gl = &ls->dyd->gt;
404  int i = ls->fs->bl->firstgoto;
405  while (i < gl->n) {
406    if (luaS_eqstr(gl->arr[i].name, lb->name))
407      closegoto(ls, i, lb);
408    else
409      i++;
410  }
411}
412
413
414/*
415** "export" pending gotos to outer level, to check them against
416** outer labels; if the block being exited has upvalues, and
417** the goto exits the scope of any variable (which can be the
418** upvalue), close those variables being exited.
419*/
420static void movegotosout (FuncState *fs, BlockCnt *bl) {
421  int i = bl->firstgoto;
422  Labellist *gl = &fs->ls->dyd->gt;
423  /* correct pending gotos to current block and try to close it
424     with visible labels */
425  while (i < gl->n) {
426    Labeldesc *gt = &gl->arr[i];
427    if (gt->nactvar > bl->nactvar) {
428      if (bl->upval)
429        luaK_patchclose(fs, gt->pc, bl->nactvar);
430      gt->nactvar = bl->nactvar;
431    }
432    if (!findlabel(fs->ls, i))
433      i++;  /* move to next one */
434  }
435}
436
437
438static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) {
439  bl->isloop = isloop;
440  bl->nactvar = fs->nactvar;
441  bl->firstlabel = fs->ls->dyd->label.n;
442  bl->firstgoto = fs->ls->dyd->gt.n;
443  bl->upval = 0;
444  bl->previous = fs->bl;
445  fs->bl = bl;
446  lua_assert(fs->freereg == fs->nactvar);
447}
448
449
450/*
451** create a label named "break" to resolve break statements
452*/
453static void breaklabel (LexState *ls) {
454  TString *n = luaS_new(ls->L, "break");
455  int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc);
456  findgotos(ls, &ls->dyd->label.arr[l]);
457}
458
459/*
460** generates an error for an undefined 'goto'; choose appropriate
461** message when label name is a reserved word (which can only be 'break')
462*/
463static l_noret undefgoto (LexState *ls, Labeldesc *gt) {
464  const char *msg = isreserved(gt->name)
465                    ? "<%s> at line %d not inside a loop"
466                    : "no visible label " LUA_QS " for <goto> at line %d";
467  msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line);
468  semerror(ls, msg);
469}
470
471
472static void leaveblock (FuncState *fs) {
473  BlockCnt *bl = fs->bl;
474  LexState *ls = fs->ls;
475  if (bl->previous && bl->upval) {
476    /* create a 'jump to here' to close upvalues */
477    int j = luaK_jump(fs);
478    luaK_patchclose(fs, j, bl->nactvar);
479    luaK_patchtohere(fs, j);
480  }
481  if (bl->isloop)
482    breaklabel(ls);  /* close pending breaks */
483  fs->bl = bl->previous;
484  removevars(fs, bl->nactvar);
485  lua_assert(bl->nactvar == fs->nactvar);
486  fs->freereg = fs->nactvar;  /* free registers */
487  ls->dyd->label.n = bl->firstlabel;  /* remove local labels */
488  if (bl->previous)  /* inner block? */
489    movegotosout(fs, bl);  /* update pending gotos to outer block */
490  else if (bl->firstgoto < ls->dyd->gt.n)  /* pending gotos in outer block? */
491    undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]);  /* error */
492}
493
494
495/*
496** adds a new prototype into list of prototypes
497*/
498static Proto *addprototype (LexState *ls) {
499  Proto *clp;
500  lua_State *L = ls->L;
501  FuncState *fs = ls->fs;
502  Proto *f = fs->f;  /* prototype of current function */
503  if (fs->np >= f->sizep) {
504    int oldsize = f->sizep;
505    luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions");
506    while (oldsize < f->sizep) f->p[oldsize++] = NULL;
507  }
508  f->p[fs->np++] = clp = luaF_newproto(L);
509  luaC_objbarrier(L, f, clp);
510  return clp;
511}
512
513
514/*
515** codes instruction to create new closure in parent function.
516** The OP_CLOSURE instruction must use the last available register,
517** so that, if it invokes the GC, the GC knows which registers
518** are in use at that time.
519*/
520static void codeclosure (LexState *ls, expdesc *v) {
521  FuncState *fs = ls->fs->prev;
522  init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1));
523  luaK_exp2nextreg(fs, v);  /* fix it at the last register */
524}
525
526
527static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
528  lua_State *L = ls->L;
529  Proto *f;
530  fs->prev = ls->fs;  /* linked list of funcstates */
531  fs->ls = ls;
532  ls->fs = fs;
533  fs->pc = 0;
534  fs->lasttarget = 0;
535  fs->jpc = NO_JUMP;
536  fs->freereg = 0;
537  fs->nk = 0;
538  fs->np = 0;
539  fs->nups = 0;
540  fs->nlocvars = 0;
541  fs->nactvar = 0;
542  fs->firstlocal = ls->dyd->actvar.n;
543  fs->bl = NULL;
544  f = fs->f;
545  f->source = ls->source;
546  f->maxstacksize = 2;  /* registers 0/1 are always valid */
547  fs->h = luaH_new(L);
548  /* anchor table of constants (to avoid being collected) */
549  sethvalue2s(L, L->top, fs->h);
550  incr_top(L);
551  enterblock(fs, bl, 0);
552}
553
554
555static void close_func (LexState *ls) {
556  lua_State *L = ls->L;
557  FuncState *fs = ls->fs;
558  Proto *f = fs->f;
559  luaK_ret(fs, 0, 0);  /* final return */
560  leaveblock(fs);
561  luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
562  f->sizecode = fs->pc;
563  luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
564  f->sizelineinfo = fs->pc;
565  luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
566  f->sizek = fs->nk;
567  luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
568  f->sizep = fs->np;
569  luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
570  f->sizelocvars = fs->nlocvars;
571  luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc);
572  f->sizeupvalues = fs->nups;
573  lua_assert(fs->bl == NULL);
574  ls->fs = fs->prev;
575  /* last token read was anchored in defunct function; must re-anchor it */
576  anchor_token(ls);
577  L->top--;  /* pop table of constants */
578  luaC_checkGC(L);
579}
580
581
582
583/*============================================================*/
584/* GRAMMAR RULES */
585/*============================================================*/
586
587
588/*
589** check whether current token is in the follow set of a block.
590** 'until' closes syntactical blocks, but do not close scope,
591** so it handled in separate.
592*/
593static int block_follow (LexState *ls, int withuntil) {
594  switch (ls->t.token) {
595    case TK_ELSE: case TK_ELSEIF:
596    case TK_END: case TK_EOS:
597      return 1;
598    case TK_UNTIL: return withuntil;
599    default: return 0;
600  }
601}
602
603
604static void statlist (LexState *ls) {
605  /* statlist -> { stat [`;'] } */
606  while (!block_follow(ls, 1)) {
607    if (ls->t.token == TK_RETURN) {
608      statement(ls);
609      return;  /* 'return' must be last statement */
610    }
611    statement(ls);
612  }
613}
614
615
616static void fieldsel (LexState *ls, expdesc *v) {
617  /* fieldsel -> ['.' | ':'] NAME */
618  FuncState *fs = ls->fs;
619  expdesc key;
620  luaK_exp2anyregup(fs, v);
621  luaX_next(ls);  /* skip the dot or colon */
622  checkname(ls, &key);
623  luaK_indexed(fs, v, &key);
624}
625
626
627static void yindex (LexState *ls, expdesc *v) {
628  /* index -> '[' expr ']' */
629  luaX_next(ls);  /* skip the '[' */
630  expr(ls, v);
631  luaK_exp2val(ls->fs, v);
632  checknext(ls, ']');
633}
634
635
636/*
637** {======================================================================
638** Rules for Constructors
639** =======================================================================
640*/
641
642
643struct ConsControl {
644  expdesc v;  /* last list item read */
645  expdesc *t;  /* table descriptor */
646  int nh;  /* total number of `record' elements */
647  int na;  /* total number of array elements */
648  int tostore;  /* number of array elements pending to be stored */
649};
650
651
652static void recfield (LexState *ls, struct ConsControl *cc) {
653  /* recfield -> (NAME | `['exp1`]') = exp1 */
654  FuncState *fs = ls->fs;
655  int reg = ls->fs->freereg;
656  expdesc key, val;
657  int rkkey;
658  if (ls->t.token == TK_NAME) {
659    checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
660    checkname(ls, &key);
661  }
662  else  /* ls->t.token == '[' */
663    yindex(ls, &key);
664  cc->nh++;
665  checknext(ls, '=');
666  rkkey = luaK_exp2RK(fs, &key);
667  expr(ls, &val);
668  luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val));
669  fs->freereg = reg;  /* free registers */
670}
671
672
673static void closelistfield (FuncState *fs, struct ConsControl *cc) {
674  if (cc->v.k == VVOID) return;  /* there is no list item */
675  luaK_exp2nextreg(fs, &cc->v);
676  cc->v.k = VVOID;
677  if (cc->tostore == LFIELDS_PER_FLUSH) {
678    luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore);  /* flush */
679    cc->tostore = 0;  /* no more items pending */
680  }
681}
682
683
684static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
685  if (cc->tostore == 0) return;
686  if (hasmultret(cc->v.k)) {
687    luaK_setmultret(fs, &cc->v);
688    luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET);
689    cc->na--;  /* do not count last expression (unknown number of elements) */
690  }
691  else {
692    if (cc->v.k != VVOID)
693      luaK_exp2nextreg(fs, &cc->v);
694    luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore);
695  }
696}
697
698
699static void listfield (LexState *ls, struct ConsControl *cc) {
700  /* listfield -> exp */
701  expr(ls, &cc->v);
702  checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
703  cc->na++;
704  cc->tostore++;
705}
706
707
708static void field (LexState *ls, struct ConsControl *cc) {
709  /* field -> listfield | recfield */
710  switch(ls->t.token) {
711    case TK_NAME: {  /* may be 'listfield' or 'recfield' */
712      if (luaX_lookahead(ls) != '=')  /* expression? */
713        listfield(ls, cc);
714      else
715        recfield(ls, cc);
716      break;
717    }
718    case '[': {
719      recfield(ls, cc);
720      break;
721    }
722    default: {
723      listfield(ls, cc);
724      break;
725    }
726  }
727}
728
729
730static void constructor (LexState *ls, expdesc *t) {
731  /* constructor -> '{' [ field { sep field } [sep] ] '}'
732     sep -> ',' | ';' */
733  FuncState *fs = ls->fs;
734  int line = ls->linenumber;
735  int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
736  struct ConsControl cc;
737  cc.na = cc.nh = cc.tostore = 0;
738  cc.t = t;
739  init_exp(t, VRELOCABLE, pc);
740  init_exp(&cc.v, VVOID, 0);  /* no value (yet) */
741  luaK_exp2nextreg(ls->fs, t);  /* fix it at stack top */
742  checknext(ls, '{');
743  do {
744    lua_assert(cc.v.k == VVOID || cc.tostore > 0);
745    if (ls->t.token == '}') break;
746    closelistfield(fs, &cc);
747    field(ls, &cc);
748  } while (testnext(ls, ',') || testnext(ls, ';'));
749  check_match(ls, '}', '{', line);
750  lastlistfield(fs, &cc);
751  SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
752  SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh));  /* set initial table size */
753}
754
755/* }====================================================================== */
756
757
758
759static void parlist (LexState *ls) {
760  /* parlist -> [ param { `,' param } ] */
761  FuncState *fs = ls->fs;
762  Proto *f = fs->f;
763  int nparams = 0;
764  f->is_vararg = 0;
765  if (ls->t.token != ')') {  /* is `parlist' not empty? */
766    do {
767      switch (ls->t.token) {
768        case TK_NAME: {  /* param -> NAME */
769          new_localvar(ls, str_checkname(ls));
770          nparams++;
771          break;
772        }
773        case TK_DOTS: {  /* param -> `...' */
774          luaX_next(ls);
775          f->is_vararg = 1;
776          break;
777        }
778        default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
779      }
780    } while (!f->is_vararg && testnext(ls, ','));
781  }
782  adjustlocalvars(ls, nparams);
783  f->numparams = cast_byte(fs->nactvar);
784  luaK_reserveregs(fs, fs->nactvar);  /* reserve register for parameters */
785}
786
787
788static void body (LexState *ls, expdesc *e, int ismethod, int line) {
789  /* body ->  `(' parlist `)' block END */
790  FuncState new_fs;
791  BlockCnt bl;
792  new_fs.f = addprototype(ls);
793  new_fs.f->linedefined = line;
794  open_func(ls, &new_fs, &bl);
795  checknext(ls, '(');
796  if (ismethod) {
797    new_localvarliteral(ls, "self");  /* create 'self' parameter */
798    adjustlocalvars(ls, 1);
799  }
800  parlist(ls);
801  checknext(ls, ')');
802  statlist(ls);
803  new_fs.f->lastlinedefined = ls->linenumber;
804  check_match(ls, TK_END, TK_FUNCTION, line);
805  codeclosure(ls, e);
806  close_func(ls);
807}
808
809
810static int explist (LexState *ls, expdesc *v) {
811  /* explist -> expr { `,' expr } */
812  int n = 1;  /* at least one expression */
813  expr(ls, v);
814  while (testnext(ls, ',')) {
815    luaK_exp2nextreg(ls->fs, v);
816    expr(ls, v);
817    n++;
818  }
819  return n;
820}
821
822
823static void funcargs (LexState *ls, expdesc *f, int line) {
824  FuncState *fs = ls->fs;
825  expdesc args;
826  int base, nparams;
827  switch (ls->t.token) {
828    case '(': {  /* funcargs -> `(' [ explist ] `)' */
829      luaX_next(ls);
830      if (ls->t.token == ')')  /* arg list is empty? */
831        args.k = VVOID;
832      else {
833        explist(ls, &args);
834        luaK_setmultret(fs, &args);
835      }
836      check_match(ls, ')', '(', line);
837      break;
838    }
839    case '{': {  /* funcargs -> constructor */
840      constructor(ls, &args);
841      break;
842    }
843    case TK_STRING: {  /* funcargs -> STRING */
844      codestring(ls, &args, ls->t.seminfo.ts);
845      luaX_next(ls);  /* must use `seminfo' before `next' */
846      break;
847    }
848    default: {
849      luaX_syntaxerror(ls, "function arguments expected");
850    }
851  }
852  lua_assert(f->k == VNONRELOC);
853  base = f->u.info;  /* base register for call */
854  if (hasmultret(args.k))
855    nparams = LUA_MULTRET;  /* open call */
856  else {
857    if (args.k != VVOID)
858      luaK_exp2nextreg(fs, &args);  /* close last argument */
859    nparams = fs->freereg - (base+1);
860  }
861  init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
862  luaK_fixline(fs, line);
863  fs->freereg = base+1;  /* call remove function and arguments and leaves
864                            (unless changed) one result */
865}
866
867
868
869
870/*
871** {======================================================================
872** Expression parsing
873** =======================================================================
874*/
875
876
877static void primaryexp (LexState *ls, expdesc *v) {
878  /* primaryexp -> NAME | '(' expr ')' */
879  switch (ls->t.token) {
880    case '(': {
881      int line = ls->linenumber;
882      luaX_next(ls);
883      expr(ls, v);
884      check_match(ls, ')', '(', line);
885      luaK_dischargevars(ls->fs, v);
886      return;
887    }
888    case TK_NAME: {
889      singlevar(ls, v);
890      return;
891    }
892    default: {
893      luaX_syntaxerror(ls, "unexpected symbol");
894    }
895  }
896}
897
898
899static void suffixedexp (LexState *ls, expdesc *v) {
900  /* suffixedexp ->
901       primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */
902  FuncState *fs = ls->fs;
903  int line = ls->linenumber;
904  primaryexp(ls, v);
905  for (;;) {
906    switch (ls->t.token) {
907      case '.': {  /* fieldsel */
908        fieldsel(ls, v);
909        break;
910      }
911      case '[': {  /* `[' exp1 `]' */
912        expdesc key;
913        luaK_exp2anyregup(fs, v);
914        yindex(ls, &key);
915        luaK_indexed(fs, v, &key);
916        break;
917      }
918      case ':': {  /* `:' NAME funcargs */
919        expdesc key;
920        luaX_next(ls);
921        checkname(ls, &key);
922        luaK_self(fs, v, &key);
923        funcargs(ls, v, line);
924        break;
925      }
926      case '(': case TK_STRING: case '{': {  /* funcargs */
927        luaK_exp2nextreg(fs, v);
928        funcargs(ls, v, line);
929        break;
930      }
931      default: return;
932    }
933  }
934}
935
936
937static void simpleexp (LexState *ls, expdesc *v) {
938  /* simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... |
939                  constructor | FUNCTION body | suffixedexp */
940  switch (ls->t.token) {
941    case TK_NUMBER: {
942      init_exp(v, VKNUM, 0);
943      v->u.nval = ls->t.seminfo.r;
944      break;
945    }
946    case TK_STRING: {
947      codestring(ls, v, ls->t.seminfo.ts);
948      break;
949    }
950    case TK_NIL: {
951      init_exp(v, VNIL, 0);
952      break;
953    }
954    case TK_TRUE: {
955      init_exp(v, VTRUE, 0);
956      break;
957    }
958    case TK_FALSE: {
959      init_exp(v, VFALSE, 0);
960      break;
961    }
962    case TK_DOTS: {  /* vararg */
963      FuncState *fs = ls->fs;
964      check_condition(ls, fs->f->is_vararg,
965                      "cannot use " LUA_QL("...") " outside a vararg function");
966      init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
967      break;
968    }
969    case '{': {  /* constructor */
970      constructor(ls, v);
971      return;
972    }
973    case TK_FUNCTION: {
974      luaX_next(ls);
975      body(ls, v, 0, ls->linenumber);
976      return;
977    }
978    default: {
979      suffixedexp(ls, v);
980      return;
981    }
982  }
983  luaX_next(ls);
984}
985
986
987static UnOpr getunopr (int op) {
988  switch (op) {
989    case TK_NOT: return OPR_NOT;
990    case '-': return OPR_MINUS;
991    case '#': return OPR_LEN;
992    default: return OPR_NOUNOPR;
993  }
994}
995
996
997static BinOpr getbinopr (int op) {
998  switch (op) {
999    case '+': return OPR_ADD;
1000    case '-': return OPR_SUB;
1001    case '*': return OPR_MUL;
1002    case '/': return OPR_DIV;
1003    case '%': return OPR_MOD;
1004    case '^': return OPR_POW;
1005    case TK_CONCAT: return OPR_CONCAT;
1006    case TK_NE: return OPR_NE;
1007    case TK_EQ: return OPR_EQ;
1008    case '<': return OPR_LT;
1009    case TK_LE: return OPR_LE;
1010    case '>': return OPR_GT;
1011    case TK_GE: return OPR_GE;
1012    case TK_AND: return OPR_AND;
1013    case TK_OR: return OPR_OR;
1014    default: return OPR_NOBINOPR;
1015  }
1016}
1017
1018
1019static const struct {
1020  lu_byte left;  /* left priority for each binary operator */
1021  lu_byte right; /* right priority */
1022} priority[] = {  /* ORDER OPR */
1023   {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7},  /* `+' `-' `*' `/' `%' */
1024   {10, 9}, {5, 4},                 /* ^, .. (right associative) */
1025   {3, 3}, {3, 3}, {3, 3},          /* ==, <, <= */
1026   {3, 3}, {3, 3}, {3, 3},          /* ~=, >, >= */
1027   {2, 2}, {1, 1}                   /* and, or */
1028};
1029
1030#define UNARY_PRIORITY   8  /* priority for unary operators */
1031
1032
1033/*
1034** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
1035** where `binop' is any binary operator with a priority higher than `limit'
1036*/
1037static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
1038  BinOpr op;
1039  UnOpr uop;
1040  enterlevel(ls);
1041  uop = getunopr(ls->t.token);
1042  if (uop != OPR_NOUNOPR) {
1043    int line = ls->linenumber;
1044    luaX_next(ls);
1045    subexpr(ls, v, UNARY_PRIORITY);
1046    luaK_prefix(ls->fs, uop, v, line);
1047  }
1048  else simpleexp(ls, v);
1049  /* expand while operators have priorities higher than `limit' */
1050  op = getbinopr(ls->t.token);
1051  while (op != OPR_NOBINOPR && priority[op].left > limit) {
1052    expdesc v2;
1053    BinOpr nextop;
1054    int line = ls->linenumber;
1055    luaX_next(ls);
1056    luaK_infix(ls->fs, op, v);
1057    /* read sub-expression with higher priority */
1058    nextop = subexpr(ls, &v2, priority[op].right);
1059    luaK_posfix(ls->fs, op, v, &v2, line);
1060    op = nextop;
1061  }
1062  leavelevel(ls);
1063  return op;  /* return first untreated operator */
1064}
1065
1066
1067static void expr (LexState *ls, expdesc *v) {
1068  subexpr(ls, v, 0);
1069}
1070
1071/* }==================================================================== */
1072
1073
1074
1075/*
1076** {======================================================================
1077** Rules for Statements
1078** =======================================================================
1079*/
1080
1081
1082static void block (LexState *ls) {
1083  /* block -> statlist */
1084  FuncState *fs = ls->fs;
1085  BlockCnt bl;
1086  enterblock(fs, &bl, 0);
1087  statlist(ls);
1088  leaveblock(fs);
1089}
1090
1091
1092/*
1093** structure to chain all variables in the left-hand side of an
1094** assignment
1095*/
1096struct LHS_assign {
1097  struct LHS_assign *prev;
1098  expdesc v;  /* variable (global, local, upvalue, or indexed) */
1099};
1100
1101
1102/*
1103** check whether, in an assignment to an upvalue/local variable, the
1104** upvalue/local variable is begin used in a previous assignment to a
1105** table. If so, save original upvalue/local value in a safe place and
1106** use this safe copy in the previous assignment.
1107*/
1108static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
1109  FuncState *fs = ls->fs;
1110  int extra = fs->freereg;  /* eventual position to save local variable */
1111  int conflict = 0;
1112  for (; lh; lh = lh->prev) {  /* check all previous assignments */
1113    if (lh->v.k == VINDEXED) {  /* assigning to a table? */
1114      /* table is the upvalue/local being assigned now? */
1115      if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) {
1116        conflict = 1;
1117        lh->v.u.ind.vt = VLOCAL;
1118        lh->v.u.ind.t = extra;  /* previous assignment will use safe copy */
1119      }
1120      /* index is the local being assigned? (index cannot be upvalue) */
1121      if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) {
1122        conflict = 1;
1123        lh->v.u.ind.idx = extra;  /* previous assignment will use safe copy */
1124      }
1125    }
1126  }
1127  if (conflict) {
1128    /* copy upvalue/local value to a temporary (in position 'extra') */
1129    OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
1130    luaK_codeABC(fs, op, extra, v->u.info, 0);
1131    luaK_reserveregs(fs, 1);
1132  }
1133}
1134
1135
1136static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
1137  expdesc e;
1138  check_condition(ls, vkisvar(lh->v.k), "syntax error");
1139  if (testnext(ls, ',')) {  /* assignment -> ',' suffixedexp assignment */
1140    struct LHS_assign nv;
1141    nv.prev = lh;
1142    suffixedexp(ls, &nv.v);
1143    if (nv.v.k != VINDEXED)
1144      check_conflict(ls, lh, &nv.v);
1145    checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS,
1146                    "C levels");
1147    assignment(ls, &nv, nvars+1);
1148  }
1149  else {  /* assignment -> `=' explist */
1150    int nexps;
1151    checknext(ls, '=');
1152    nexps = explist(ls, &e);
1153    if (nexps != nvars) {
1154      adjust_assign(ls, nvars, nexps, &e);
1155      if (nexps > nvars)
1156        ls->fs->freereg -= nexps - nvars;  /* remove extra values */
1157    }
1158    else {
1159      luaK_setoneret(ls->fs, &e);  /* close last expression */
1160      luaK_storevar(ls->fs, &lh->v, &e);
1161      return;  /* avoid default */
1162    }
1163  }
1164  init_exp(&e, VNONRELOC, ls->fs->freereg-1);  /* default assignment */
1165  luaK_storevar(ls->fs, &lh->v, &e);
1166}
1167
1168
1169static int cond (LexState *ls) {
1170  /* cond -> exp */
1171  expdesc v;
1172  expr(ls, &v);  /* read condition */
1173  if (v.k == VNIL) v.k = VFALSE;  /* `falses' are all equal here */
1174  luaK_goiftrue(ls->fs, &v);
1175  return v.f;
1176}
1177
1178
1179static void gotostat (LexState *ls, int pc) {
1180  int line = ls->linenumber;
1181  TString *label;
1182  int g;
1183  if (testnext(ls, TK_GOTO))
1184    label = str_checkname(ls);
1185  else {
1186    luaX_next(ls);  /* skip break */
1187    label = luaS_new(ls->L, "break");
1188  }
1189  g = newlabelentry(ls, &ls->dyd->gt, label, line, pc);
1190  findlabel(ls, g);  /* close it if label already defined */
1191}
1192
1193
1194/* check for repeated labels on the same block */
1195static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) {
1196  int i;
1197  for (i = fs->bl->firstlabel; i < ll->n; i++) {
1198    if (luaS_eqstr(label, ll->arr[i].name)) {
1199      const char *msg = luaO_pushfstring(fs->ls->L,
1200                          "label " LUA_QS " already defined on line %d",
1201                          getstr(label), ll->arr[i].line);
1202      semerror(fs->ls, msg);
1203    }
1204  }
1205}
1206
1207
1208/* skip no-op statements */
1209static void skipnoopstat (LexState *ls) {
1210  while (ls->t.token == ';' || ls->t.token == TK_DBCOLON)
1211    statement(ls);
1212}
1213
1214
1215static void labelstat (LexState *ls, TString *label, int line) {
1216  /* label -> '::' NAME '::' */
1217  FuncState *fs = ls->fs;
1218  Labellist *ll = &ls->dyd->label;
1219  int l;  /* index of new label being created */
1220  checkrepeated(fs, ll, label);  /* check for repeated labels */
1221  checknext(ls, TK_DBCOLON);  /* skip double colon */
1222  /* create new entry for this label */
1223  l = newlabelentry(ls, ll, label, line, fs->pc);
1224  skipnoopstat(ls);  /* skip other no-op statements */
1225  if (block_follow(ls, 0)) {  /* label is last no-op statement in the block? */
1226    /* assume that locals are already out of scope */
1227    ll->arr[l].nactvar = fs->bl->nactvar;
1228  }
1229  findgotos(ls, &ll->arr[l]);
1230}
1231
1232
1233static void whilestat (LexState *ls, int line) {
1234  /* whilestat -> WHILE cond DO block END */
1235  FuncState *fs = ls->fs;
1236  int whileinit;
1237  int condexit;
1238  BlockCnt bl;
1239  luaX_next(ls);  /* skip WHILE */
1240  whileinit = luaK_getlabel(fs);
1241  condexit = cond(ls);
1242  enterblock(fs, &bl, 1);
1243  checknext(ls, TK_DO);
1244  block(ls);
1245  luaK_jumpto(fs, whileinit);
1246  check_match(ls, TK_END, TK_WHILE, line);
1247  leaveblock(fs);
1248  luaK_patchtohere(fs, condexit);  /* false conditions finish the loop */
1249}
1250
1251
1252static void repeatstat (LexState *ls, int line) {
1253  /* repeatstat -> REPEAT block UNTIL cond */
1254  int condexit;
1255  FuncState *fs = ls->fs;
1256  int repeat_init = luaK_getlabel(fs);
1257  BlockCnt bl1, bl2;
1258  enterblock(fs, &bl1, 1);  /* loop block */
1259  enterblock(fs, &bl2, 0);  /* scope block */
1260  luaX_next(ls);  /* skip REPEAT */
1261  statlist(ls);
1262  check_match(ls, TK_UNTIL, TK_REPEAT, line);
1263  condexit = cond(ls);  /* read condition (inside scope block) */
1264  if (bl2.upval)  /* upvalues? */
1265    luaK_patchclose(fs, condexit, bl2.nactvar);
1266  leaveblock(fs);  /* finish scope */
1267  luaK_patchlist(fs, condexit, repeat_init);  /* close the loop */
1268  leaveblock(fs);  /* finish loop */
1269}
1270
1271
1272static int exp1 (LexState *ls) {
1273  expdesc e;
1274  int reg;
1275  expr(ls, &e);
1276  luaK_exp2nextreg(ls->fs, &e);
1277  lua_assert(e.k == VNONRELOC);
1278  reg = e.u.info;
1279  return reg;
1280}
1281
1282
1283static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
1284  /* forbody -> DO block */
1285  BlockCnt bl;
1286  FuncState *fs = ls->fs;
1287  int prep, endfor;
1288  adjustlocalvars(ls, 3);  /* control variables */
1289  checknext(ls, TK_DO);
1290  prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);
1291  enterblock(fs, &bl, 0);  /* scope for declared variables */
1292  adjustlocalvars(ls, nvars);
1293  luaK_reserveregs(fs, nvars);
1294  block(ls);
1295  leaveblock(fs);  /* end of scope for declared variables */
1296  luaK_patchtohere(fs, prep);
1297  if (isnum)  /* numeric for? */
1298    endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP);
1299  else {  /* generic for */
1300    luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars);
1301    luaK_fixline(fs, line);
1302    endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP);
1303  }
1304  luaK_patchlist(fs, endfor, prep + 1);
1305  luaK_fixline(fs, line);
1306}
1307
1308
1309static void fornum (LexState *ls, TString *varname, int line) {
1310  /* fornum -> NAME = exp1,exp1[,exp1] forbody */
1311  FuncState *fs = ls->fs;
1312  int base = fs->freereg;
1313  new_localvarliteral(ls, "(for index)");
1314  new_localvarliteral(ls, "(for limit)");
1315  new_localvarliteral(ls, "(for step)");
1316  new_localvar(ls, varname);
1317  checknext(ls, '=');
1318  exp1(ls);  /* initial value */
1319  checknext(ls, ',');
1320  exp1(ls);  /* limit */
1321  if (testnext(ls, ','))
1322    exp1(ls);  /* optional step */
1323  else {  /* default step = 1 */
1324    luaK_codek(fs, fs->freereg, luaK_numberK(fs, 1));
1325    luaK_reserveregs(fs, 1);
1326  }
1327  forbody(ls, base, line, 1, 1);
1328}
1329
1330
1331static void forlist (LexState *ls, TString *indexname) {
1332  /* forlist -> NAME {,NAME} IN explist forbody */
1333  FuncState *fs = ls->fs;
1334  expdesc e;
1335  int nvars = 4;  /* gen, state, control, plus at least one declared var */
1336  int line;
1337  int base = fs->freereg;
1338  /* create control variables */
1339  new_localvarliteral(ls, "(for generator)");
1340  new_localvarliteral(ls, "(for state)");
1341  new_localvarliteral(ls, "(for control)");
1342  /* create declared variables */
1343  new_localvar(ls, indexname);
1344  while (testnext(ls, ',')) {
1345    new_localvar(ls, str_checkname(ls));
1346    nvars++;
1347  }
1348  checknext(ls, TK_IN);
1349  line = ls->linenumber;
1350  adjust_assign(ls, 3, explist(ls, &e), &e);
1351  luaK_checkstack(fs, 3);  /* extra space to call generator */
1352  forbody(ls, base, line, nvars - 3, 0);
1353}
1354
1355
1356static void forstat (LexState *ls, int line) {
1357  /* forstat -> FOR (fornum | forlist) END */
1358  FuncState *fs = ls->fs;
1359  TString *varname;
1360  BlockCnt bl;
1361  enterblock(fs, &bl, 1);  /* scope for loop and control variables */
1362  luaX_next(ls);  /* skip `for' */
1363  varname = str_checkname(ls);  /* first variable name */
1364  switch (ls->t.token) {
1365    case '=': fornum(ls, varname, line); break;
1366    case ',': case TK_IN: forlist(ls, varname); break;
1367    default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected");
1368  }
1369  check_match(ls, TK_END, TK_FOR, line);
1370  leaveblock(fs);  /* loop scope (`break' jumps to this point) */
1371}
1372
1373
1374static void test_then_block (LexState *ls, int *escapelist) {
1375  /* test_then_block -> [IF | ELSEIF] cond THEN block */
1376  BlockCnt bl;
1377  FuncState *fs = ls->fs;
1378  expdesc v;
1379  int jf;  /* instruction to skip 'then' code (if condition is false) */
1380  luaX_next(ls);  /* skip IF or ELSEIF */
1381  expr(ls, &v);  /* read condition */
1382  checknext(ls, TK_THEN);
1383  if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) {
1384    luaK_goiffalse(ls->fs, &v);  /* will jump to label if condition is true */
1385    enterblock(fs, &bl, 0);  /* must enter block before 'goto' */
1386    gotostat(ls, v.t);  /* handle goto/break */
1387    skipnoopstat(ls);  /* skip other no-op statements */
1388    if (block_follow(ls, 0)) {  /* 'goto' is the entire block? */
1389      leaveblock(fs);
1390      return;  /* and that is it */
1391    }
1392    else  /* must skip over 'then' part if condition is false */
1393      jf = luaK_jump(fs);
1394  }
1395  else {  /* regular case (not goto/break) */
1396    luaK_goiftrue(ls->fs, &v);  /* skip over block if condition is false */
1397    enterblock(fs, &bl, 0);
1398    jf = v.f;
1399  }
1400  statlist(ls);  /* `then' part */
1401  leaveblock(fs);
1402  if (ls->t.token == TK_ELSE ||
1403      ls->t.token == TK_ELSEIF)  /* followed by 'else'/'elseif'? */
1404    luaK_concat(fs, escapelist, luaK_jump(fs));  /* must jump over it */
1405  luaK_patchtohere(fs, jf);
1406}
1407
1408
1409static void ifstat (LexState *ls, int line) {
1410  /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
1411  FuncState *fs = ls->fs;
1412  int escapelist = NO_JUMP;  /* exit list for finished parts */
1413  test_then_block(ls, &escapelist);  /* IF cond THEN block */
1414  while (ls->t.token == TK_ELSEIF)
1415    test_then_block(ls, &escapelist);  /* ELSEIF cond THEN block */
1416  if (testnext(ls, TK_ELSE))
1417    block(ls);  /* `else' part */
1418  check_match(ls, TK_END, TK_IF, line);
1419  luaK_patchtohere(fs, escapelist);  /* patch escape list to 'if' end */
1420}
1421
1422
1423static void localfunc (LexState *ls) {
1424  expdesc b;
1425  FuncState *fs = ls->fs;
1426  new_localvar(ls, str_checkname(ls));  /* new local variable */
1427  adjustlocalvars(ls, 1);  /* enter its scope */
1428  body(ls, &b, 0, ls->linenumber);  /* function created in next register */
1429  /* debug information will only see the variable after this point! */
1430  getlocvar(fs, b.u.info)->startpc = fs->pc;
1431}
1432
1433
1434static void localstat (LexState *ls) {
1435  /* stat -> LOCAL NAME {`,' NAME} [`=' explist] */
1436  int nvars = 0;
1437  int nexps;
1438  expdesc e;
1439  do {
1440    new_localvar(ls, str_checkname(ls));
1441    nvars++;
1442  } while (testnext(ls, ','));
1443  if (testnext(ls, '='))
1444    nexps = explist(ls, &e);
1445  else {
1446    e.k = VVOID;
1447    nexps = 0;
1448  }
1449  adjust_assign(ls, nvars, nexps, &e);
1450  adjustlocalvars(ls, nvars);
1451}
1452
1453
1454static int funcname (LexState *ls, expdesc *v) {
1455  /* funcname -> NAME {fieldsel} [`:' NAME] */
1456  int ismethod = 0;
1457  singlevar(ls, v);
1458  while (ls->t.token == '.')
1459    fieldsel(ls, v);
1460  if (ls->t.token == ':') {
1461    ismethod = 1;
1462    fieldsel(ls, v);
1463  }
1464  return ismethod;
1465}
1466
1467
1468static void funcstat (LexState *ls, int line) {
1469  /* funcstat -> FUNCTION funcname body */
1470  int ismethod;
1471  expdesc v, b;
1472  luaX_next(ls);  /* skip FUNCTION */
1473  ismethod = funcname(ls, &v);
1474  body(ls, &b, ismethod, line);
1475  luaK_storevar(ls->fs, &v, &b);
1476  luaK_fixline(ls->fs, line);  /* definition `happens' in the first line */
1477}
1478
1479
1480static void exprstat (LexState *ls) {
1481  /* stat -> func | assignment */
1482  FuncState *fs = ls->fs;
1483  struct LHS_assign v;
1484  suffixedexp(ls, &v.v);
1485  if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */
1486    v.prev = NULL;
1487    assignment(ls, &v, 1);
1488  }
1489  else {  /* stat -> func */
1490    check_condition(ls, v.v.k == VCALL, "syntax error");
1491    SETARG_C(getcode(fs, &v.v), 1);  /* call statement uses no results */
1492  }
1493}
1494
1495
1496static void retstat (LexState *ls) {
1497  /* stat -> RETURN [explist] [';'] */
1498  FuncState *fs = ls->fs;
1499  expdesc e;
1500  int first, nret;  /* registers with returned values */
1501  if (block_follow(ls, 1) || ls->t.token == ';')
1502    first = nret = 0;  /* return no values */
1503  else {
1504    nret = explist(ls, &e);  /* optional return values */
1505    if (hasmultret(e.k)) {
1506      luaK_setmultret(fs, &e);
1507      if (e.k == VCALL && nret == 1) {  /* tail call? */
1508        SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
1509        lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
1510      }
1511      first = fs->nactvar;
1512      nret = LUA_MULTRET;  /* return all values */
1513    }
1514    else {
1515      if (nret == 1)  /* only one single value? */
1516        first = luaK_exp2anyreg(fs, &e);
1517      else {
1518        luaK_exp2nextreg(fs, &e);  /* values must go to the `stack' */
1519        first = fs->nactvar;  /* return all `active' values */
1520        lua_assert(nret == fs->freereg - first);
1521      }
1522    }
1523  }
1524  luaK_ret(fs, first, nret);
1525  testnext(ls, ';');  /* skip optional semicolon */
1526}
1527
1528
1529static void statement (LexState *ls) {
1530  int line = ls->linenumber;  /* may be needed for error messages */
1531  enterlevel(ls);
1532  switch (ls->t.token) {
1533    case ';': {  /* stat -> ';' (empty statement) */
1534      luaX_next(ls);  /* skip ';' */
1535      break;
1536    }
1537    case TK_IF: {  /* stat -> ifstat */
1538      ifstat(ls, line);
1539      break;
1540    }
1541    case TK_WHILE: {  /* stat -> whilestat */
1542      whilestat(ls, line);
1543      break;
1544    }
1545    case TK_DO: {  /* stat -> DO block END */
1546      luaX_next(ls);  /* skip DO */
1547      block(ls);
1548      check_match(ls, TK_END, TK_DO, line);
1549      break;
1550    }
1551    case TK_FOR: {  /* stat -> forstat */
1552      forstat(ls, line);
1553      break;
1554    }
1555    case TK_REPEAT: {  /* stat -> repeatstat */
1556      repeatstat(ls, line);
1557      break;
1558    }
1559    case TK_FUNCTION: {  /* stat -> funcstat */
1560      funcstat(ls, line);
1561      break;
1562    }
1563    case TK_LOCAL: {  /* stat -> localstat */
1564      luaX_next(ls);  /* skip LOCAL */
1565      if (testnext(ls, TK_FUNCTION))  /* local function? */
1566        localfunc(ls);
1567      else
1568        localstat(ls);
1569      break;
1570    }
1571    case TK_DBCOLON: {  /* stat -> label */
1572      luaX_next(ls);  /* skip double colon */
1573      labelstat(ls, str_checkname(ls), line);
1574      break;
1575    }
1576    case TK_RETURN: {  /* stat -> retstat */
1577      luaX_next(ls);  /* skip RETURN */
1578      retstat(ls);
1579      break;
1580    }
1581    case TK_BREAK:   /* stat -> breakstat */
1582    case TK_GOTO: {  /* stat -> 'goto' NAME */
1583      gotostat(ls, luaK_jump(ls->fs));
1584      break;
1585    }
1586    default: {  /* stat -> func | assignment */
1587      exprstat(ls);
1588      break;
1589    }
1590  }
1591  lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
1592             ls->fs->freereg >= ls->fs->nactvar);
1593  ls->fs->freereg = ls->fs->nactvar;  /* free registers */
1594  leavelevel(ls);
1595}
1596
1597/* }====================================================================== */
1598
1599
1600/*
1601** compiles the main function, which is a regular vararg function with an
1602** upvalue named LUA_ENV
1603*/
1604static void mainfunc (LexState *ls, FuncState *fs) {
1605  BlockCnt bl;
1606  expdesc v;
1607  open_func(ls, fs, &bl);
1608  fs->f->is_vararg = 1;  /* main function is always vararg */
1609  init_exp(&v, VLOCAL, 0);  /* create and... */
1610  newupvalue(fs, ls->envn, &v);  /* ...set environment upvalue */
1611  luaX_next(ls);  /* read first token */
1612  statlist(ls);  /* parse main body */
1613  check(ls, TK_EOS);
1614  close_func(ls);
1615}
1616
1617
1618Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
1619                      Dyndata *dyd, const char *name, int firstchar) {
1620  LexState lexstate;
1621  FuncState funcstate;
1622  Closure *cl = luaF_newLclosure(L, 1);  /* create main closure */
1623  /* anchor closure (to avoid being collected) */
1624  setclLvalue(L, L->top, cl);
1625  incr_top(L);
1626  funcstate.f = cl->l.p = luaF_newproto(L);
1627  funcstate.f->source = luaS_new(L, name);  /* create and anchor TString */
1628  lexstate.buff = buff;
1629  lexstate.dyd = dyd;
1630  dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
1631  luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar);
1632  mainfunc(&lexstate, &funcstate);
1633  lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
1634  /* all scopes should be correctly finished */
1635  lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
1636  return cl;  /* it's on the stack too */
1637}
1638
Property changes on: trunk/src/lib/lua/lparser.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/lgc.h
r0r22721
1/*
2** $Id: lgc.h,v 2.58 2012/09/11 12:53:08 roberto Exp $
3** Garbage Collector
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lgc_h
8#define lgc_h
9
10
11#include "lobject.h"
12#include "lstate.h"
13
14/*
15** Collectable objects may have one of three colors: white, which
16** means the object is not marked; gray, which means the
17** object is marked, but its references may be not marked; and
18** black, which means that the object and all its references are marked.
19** The main invariant of the garbage collector, while marking objects,
20** is that a black object can never point to a white one. Moreover,
21** any gray object must be in a "gray list" (gray, grayagain, weak,
22** allweak, ephemeron) so that it can be visited again before finishing
23** the collection cycle. These lists have no meaning when the invariant
24** is not being enforced (e.g., sweep phase).
25*/
26
27
28
29/* how much to allocate before next GC step */
30#if !defined(GCSTEPSIZE)
31/* ~100 small strings */
32#define GCSTEPSIZE   (cast_int(100 * sizeof(TString)))
33#endif
34
35
36/*
37** Possible states of the Garbage Collector
38*/
39#define GCSpropagate   0
40#define GCSatomic   1
41#define GCSsweepstring   2
42#define GCSsweepudata   3
43#define GCSsweep   4
44#define GCSpause   5
45
46
47#define issweepphase(g)  \
48   (GCSsweepstring <= (g)->gcstate && (g)->gcstate <= GCSsweep)
49
50#define isgenerational(g)   ((g)->gckind == KGC_GEN)
51
52/*
53** macros to tell when main invariant (white objects cannot point to black
54** ones) must be kept. During a non-generational collection, the sweep
55** phase may break the invariant, as objects turned white may point to
56** still-black objects. The invariant is restored when sweep ends and
57** all objects are white again. During a generational collection, the
58** invariant must be kept all times.
59*/
60
61#define keepinvariant(g)   (isgenerational(g) || g->gcstate <= GCSatomic)
62
63
64/*
65** Outside the collector, the state in generational mode is kept in
66** 'propagate', so 'keepinvariant' is always true.
67*/
68#define keepinvariantout(g)  \
69  check_exp(g->gcstate == GCSpropagate || !isgenerational(g),  \
70            g->gcstate <= GCSatomic)
71
72
73/*
74** some useful bit tricks
75*/
76#define resetbits(x,m)      ((x) &= cast(lu_byte, ~(m)))
77#define setbits(x,m)      ((x) |= (m))
78#define testbits(x,m)      ((x) & (m))
79#define bitmask(b)      (1<<(b))
80#define bit2mask(b1,b2)      (bitmask(b1) | bitmask(b2))
81#define l_setbit(x,b)      setbits(x, bitmask(b))
82#define resetbit(x,b)      resetbits(x, bitmask(b))
83#define testbit(x,b)      testbits(x, bitmask(b))
84
85
86/* Layout for bit use in `marked' field: */
87#define WHITE0BIT   0  /* object is white (type 0) */
88#define WHITE1BIT   1  /* object is white (type 1) */
89#define BLACKBIT   2  /* object is black */
90#define FINALIZEDBIT   3  /* object has been separated for finalization */
91#define SEPARATED   4  /* object is in 'finobj' list or in 'tobefnz' */
92#define FIXEDBIT   5  /* object is fixed (should not be collected) */
93#define OLDBIT      6  /* object is old (only in generational mode) */
94/* bit 7 is currently used by tests (luaL_checkmemory) */
95
96#define WHITEBITS   bit2mask(WHITE0BIT, WHITE1BIT)
97
98
99#define iswhite(x)      testbits((x)->gch.marked, WHITEBITS)
100#define isblack(x)      testbit((x)->gch.marked, BLACKBIT)
101#define isgray(x)  /* neither white nor black */  \
102   (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT)))
103
104#define isold(x)   testbit((x)->gch.marked, OLDBIT)
105
106/* MOVE OLD rule: whenever an object is moved to the beginning of
107   a GC list, its old bit must be cleared */
108#define resetoldbit(o)   resetbit((o)->gch.marked, OLDBIT)
109
110#define otherwhite(g)   (g->currentwhite ^ WHITEBITS)
111#define isdeadm(ow,m)   (!(((m) ^ WHITEBITS) & (ow)))
112#define isdead(g,v)   isdeadm(otherwhite(g), (v)->gch.marked)
113
114#define changewhite(x)   ((x)->gch.marked ^= WHITEBITS)
115#define gray2black(x)   l_setbit((x)->gch.marked, BLACKBIT)
116
117#define valiswhite(x)   (iscollectable(x) && iswhite(gcvalue(x)))
118
119#define luaC_white(g)   cast(lu_byte, (g)->currentwhite & WHITEBITS)
120
121
122#define luaC_condGC(L,c) \
123   {if (G(L)->GCdebt > 0) {c;}; condchangemem(L);}
124#define luaC_checkGC(L)      luaC_condGC(L, luaC_step(L);)
125
126
127#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p)))  \
128   luaC_barrier_(L,obj2gco(p),gcvalue(v)); }
129
130#define luaC_barrierback(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p)))  \
131   luaC_barrierback_(L,p); }
132
133#define luaC_objbarrier(L,p,o)  \
134   { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
135      luaC_barrier_(L,obj2gco(p),obj2gco(o)); }
136
137#define luaC_objbarrierback(L,p,o)  \
138   { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) luaC_barrierback_(L,p); }
139
140#define luaC_barrierproto(L,p,c) \
141   { if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); }
142
143LUAI_FUNC void luaC_freeallobjects (lua_State *L);
144LUAI_FUNC void luaC_step (lua_State *L);
145LUAI_FUNC void luaC_forcestep (lua_State *L);
146LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
147LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
148LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz,
149                                 GCObject **list, int offset);
150LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
151LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o);
152LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c);
153LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt);
154LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv);
155LUAI_FUNC void luaC_changemode (lua_State *L, int mode);
156
157#endif
Property changes on: trunk/src/lib/lua/lgc.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/liolib.c
r0r22721
1/*
2** $Id: liolib.c,v 2.111 2013/03/21 13:57:27 roberto Exp $
3** Standard I/O (and system) library
4** See Copyright Notice in lua.h
5*/
6
7
8/*
9** POSIX idiosyncrasy!
10** This definition must come before the inclusion of 'stdio.h'; it
11** should not affect non-POSIX systems
12*/
13#if !defined(_FILE_OFFSET_BITS)
14#define _FILE_OFFSET_BITS 64
15#endif
16
17
18#include <errno.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22
23#define liolib_c
24#define LUA_LIB
25
26#include "lua.h"
27
28#include "lauxlib.h"
29#include "lualib.h"
30
31
32#if !defined(lua_checkmode)
33
34/*
35** Check whether 'mode' matches '[rwa]%+?b?'.
36** Change this macro to accept other modes for 'fopen' besides
37** the standard ones.
38*/
39#define lua_checkmode(mode) \
40   (*mode != '\0' && strchr("rwa", *(mode++)) != NULL &&   \
41   (*mode != '+' || ++mode) &&  /* skip if char is '+' */   \
42   (*mode != 'b' || ++mode) &&  /* skip if char is 'b' */   \
43   (*mode == '\0'))
44
45#endif
46
47/*
48** {======================================================
49** lua_popen spawns a new process connected to the current
50** one through the file streams.
51** =======================================================
52*/
53
54#if !defined(lua_popen)   /* { */
55
56#if defined(LUA_USE_POPEN)   /* { */
57
58#define lua_popen(L,c,m)   ((void)L, fflush(NULL), popen(c,m))
59#define lua_pclose(L,file)   ((void)L, pclose(file))
60
61#elif defined(LUA_WIN)      /* }{ */
62
63#define lua_popen(L,c,m)      ((void)L, _popen(c,m))
64#define lua_pclose(L,file)      ((void)L, _pclose(file))
65
66
67#else            /* }{ */
68
69#define lua_popen(L,c,m)      ((void)((void)c, m),  \
70      luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0)
71#define lua_pclose(L,file)      ((void)((void)L, file), -1)
72
73
74#endif            /* } */
75
76#endif         /* } */
77
78/* }====================================================== */
79
80
81/*
82** {======================================================
83** lua_fseek/lua_ftell: configuration for longer offsets
84** =======================================================
85*/
86
87#if !defined(lua_fseek)   /* { */
88
89#if defined(LUA_USE_POSIX)
90
91#define l_fseek(f,o,w)      fseeko(f,o,w)
92#define l_ftell(f)      ftello(f)
93#define l_seeknum      off_t
94
95#elif defined(LUA_WIN) && !defined(_CRTIMP_TYPEINFO) \
96   && defined(_MSC_VER) && (_MSC_VER >= 1400)
97/* Windows (but not DDK) and Visual C++ 2005 or higher */
98
99#define l_fseek(f,o,w)      _fseeki64(f,o,w)
100#define l_ftell(f)      _ftelli64(f)
101#define l_seeknum      __int64
102
103#else
104
105#define l_fseek(f,o,w)      fseek(f,o,w)
106#define l_ftell(f)      ftell(f)
107#define l_seeknum      long
108
109#endif
110
111#endif         /* } */
112
113/* }====================================================== */
114
115
116#define IO_PREFIX   "_IO_"
117#define IO_INPUT   (IO_PREFIX "input")
118#define IO_OUTPUT   (IO_PREFIX "output")
119
120
121typedef luaL_Stream LStream;
122
123
124#define tolstream(L)   ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE))
125
126#define isclosed(p)   ((p)->closef == NULL)
127
128
129static int io_type (lua_State *L) {
130  LStream *p;
131  luaL_checkany(L, 1);
132  p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE);
133  if (p == NULL)
134    lua_pushnil(L);  /* not a file */
135  else if (isclosed(p))
136    lua_pushliteral(L, "closed file");
137  else
138    lua_pushliteral(L, "file");
139  return 1;
140}
141
142
143static int f_tostring (lua_State *L) {
144  LStream *p = tolstream(L);
145  if (isclosed(p))
146    lua_pushliteral(L, "file (closed)");
147  else
148    lua_pushfstring(L, "file (%p)", p->f);
149  return 1;
150}
151
152
153static FILE *tofile (lua_State *L) {
154  LStream *p = tolstream(L);
155  if (isclosed(p))
156    luaL_error(L, "attempt to use a closed file");
157  lua_assert(p->f);
158  return p->f;
159}
160
161
162/*
163** When creating file handles, always creates a `closed' file handle
164** before opening the actual file; so, if there is a memory error, the
165** file is not left opened.
166*/
167static LStream *newprefile (lua_State *L) {
168  LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream));
169  p->closef = NULL;  /* mark file handle as 'closed' */
170  luaL_setmetatable(L, LUA_FILEHANDLE);
171  return p;
172}
173
174
175static int aux_close (lua_State *L) {
176  LStream *p = tolstream(L);
177  lua_CFunction cf = p->closef;
178  p->closef = NULL;  /* mark stream as closed */
179  return (*cf)(L);  /* close it */
180}
181
182
183static int io_close (lua_State *L) {
184  if (lua_isnone(L, 1))  /* no argument? */
185    lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT);  /* use standard output */
186  tofile(L);  /* make sure argument is an open stream */
187  return aux_close(L);
188}
189
190
191static int f_gc (lua_State *L) {
192  LStream *p = tolstream(L);
193  if (!isclosed(p) && p->f != NULL)
194    aux_close(L);  /* ignore closed and incompletely open files */
195  return 0;
196}
197
198
199/*
200** function to close regular files
201*/
202static int io_fclose (lua_State *L) {
203  LStream *p = tolstream(L);
204  int res = fclose(p->f);
205  return luaL_fileresult(L, (res == 0), NULL);
206}
207
208
209static LStream *newfile (lua_State *L) {
210  LStream *p = newprefile(L);
211  p->f = NULL;
212  p->closef = &io_fclose;
213  return p;
214}
215
216
217static void opencheck (lua_State *L, const char *fname, const char *mode) {
218  LStream *p = newfile(L);
219  p->f = fopen(fname, mode);
220  if (p->f == NULL)
221    luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno));
222}
223
224
225static int io_open (lua_State *L) {
226  const char *filename = luaL_checkstring(L, 1);
227  const char *mode = luaL_optstring(L, 2, "r");
228  LStream *p = newfile(L);
229  const char *md = mode;  /* to traverse/check mode */
230  luaL_argcheck(L, lua_checkmode(md), 2, "invalid mode");
231  p->f = fopen(filename, mode);
232  return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
233}
234
235
236/*
237** function to close 'popen' files
238*/
239static int io_pclose (lua_State *L) {
240  LStream *p = tolstream(L);
241  return luaL_execresult(L, lua_pclose(L, p->f));
242}
243
244
245static int io_popen (lua_State *L) {
246  const char *filename = luaL_checkstring(L, 1);
247  const char *mode = luaL_optstring(L, 2, "r");
248  LStream *p = newprefile(L);
249  p->f = lua_popen(L, filename, mode);
250  p->closef = &io_pclose;
251  return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
252}
253
254
255static int io_tmpfile (lua_State *L) {
256  LStream *p = newfile(L);
257  p->f = tmpfile();
258  return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1;
259}
260
261
262static FILE *getiofile (lua_State *L, const char *findex) {
263  LStream *p;
264  lua_getfield(L, LUA_REGISTRYINDEX, findex);
265  p = (LStream *)lua_touserdata(L, -1);
266  if (isclosed(p))
267    luaL_error(L, "standard %s file is closed", findex + strlen(IO_PREFIX));
268  return p->f;
269}
270
271
272static int g_iofile (lua_State *L, const char *f, const char *mode) {
273  if (!lua_isnoneornil(L, 1)) {
274    const char *filename = lua_tostring(L, 1);
275    if (filename)
276      opencheck(L, filename, mode);
277    else {
278      tofile(L);  /* check that it's a valid file handle */
279      lua_pushvalue(L, 1);
280    }
281    lua_setfield(L, LUA_REGISTRYINDEX, f);
282  }
283  /* return current value */
284  lua_getfield(L, LUA_REGISTRYINDEX, f);
285  return 1;
286}
287
288
289static int io_input (lua_State *L) {
290  return g_iofile(L, IO_INPUT, "r");
291}
292
293
294static int io_output (lua_State *L) {
295  return g_iofile(L, IO_OUTPUT, "w");
296}
297
298
299static int io_readline (lua_State *L);
300
301
302static void aux_lines (lua_State *L, int toclose) {
303  int i;
304  int n = lua_gettop(L) - 1;  /* number of arguments to read */
305  /* ensure that arguments will fit here and into 'io_readline' stack */
306  luaL_argcheck(L, n <= LUA_MINSTACK - 3, LUA_MINSTACK - 3, "too many options");
307  lua_pushvalue(L, 1);  /* file handle */
308  lua_pushinteger(L, n);  /* number of arguments to read */
309  lua_pushboolean(L, toclose);  /* close/not close file when finished */
310  for (i = 1; i <= n; i++) lua_pushvalue(L, i + 1);  /* copy arguments */
311  lua_pushcclosure(L, io_readline, 3 + n);
312}
313
314
315static int f_lines (lua_State *L) {
316  tofile(L);  /* check that it's a valid file handle */
317  aux_lines(L, 0);
318  return 1;
319}
320
321
322static int io_lines (lua_State *L) {
323  int toclose;
324  if (lua_isnone(L, 1)) lua_pushnil(L);  /* at least one argument */
325  if (lua_isnil(L, 1)) {  /* no file name? */
326    lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT);  /* get default input */
327    lua_replace(L, 1);  /* put it at index 1 */
328    tofile(L);  /* check that it's a valid file handle */
329    toclose = 0;  /* do not close it after iteration */
330  }
331  else {  /* open a new file */
332    const char *filename = luaL_checkstring(L, 1);
333    opencheck(L, filename, "r");
334    lua_replace(L, 1);  /* put file at index 1 */
335    toclose = 1;  /* close it after iteration */
336  }
337  aux_lines(L, toclose);
338  return 1;
339}
340
341
342/*
343** {======================================================
344** READ
345** =======================================================
346*/
347
348
349static int read_number (lua_State *L, FILE *f) {
350  lua_Number d;
351  if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
352    lua_pushnumber(L, d);
353    return 1;
354  }
355  else {
356   lua_pushnil(L);  /* "result" to be removed */
357   return 0;  /* read fails */
358  }
359}
360
361
362static int test_eof (lua_State *L, FILE *f) {
363  int c = getc(f);
364  ungetc(c, f);
365  lua_pushlstring(L, NULL, 0);
366  return (c != EOF);
367}
368
369
370static int read_line (lua_State *L, FILE *f, int chop) {
371  luaL_Buffer b;
372  luaL_buffinit(L, &b);
373  for (;;) {
374    size_t l;
375    char *p = luaL_prepbuffer(&b);
376    if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) {  /* eof? */
377      luaL_pushresult(&b);  /* close buffer */
378      return (lua_rawlen(L, -1) > 0);  /* check whether read something */
379    }
380    l = strlen(p);
381    if (l == 0 || p[l-1] != '\n')
382      luaL_addsize(&b, l);
383    else {
384      luaL_addsize(&b, l - chop);  /* chop 'eol' if needed */
385      luaL_pushresult(&b);  /* close buffer */
386      return 1;  /* read at least an `eol' */
387    }
388  }
389}
390
391
392#define MAX_SIZE_T   (~(size_t)0)
393
394static void read_all (lua_State *L, FILE *f) {
395  size_t rlen = LUAL_BUFFERSIZE;  /* how much to read in each cycle */
396  luaL_Buffer b;
397  luaL_buffinit(L, &b);
398  for (;;) {
399    char *p = luaL_prepbuffsize(&b, rlen);
400    size_t nr = fread(p, sizeof(char), rlen, f);
401    luaL_addsize(&b, nr);
402    if (nr < rlen) break;  /* eof? */
403    else if (rlen <= (MAX_SIZE_T / 4))  /* avoid buffers too large */
404      rlen *= 2;  /* double buffer size at each iteration */
405  }
406  luaL_pushresult(&b);  /* close buffer */
407}
408
409
410static int read_chars (lua_State *L, FILE *f, size_t n) {
411  size_t nr;  /* number of chars actually read */
412  char *p;
413  luaL_Buffer b;
414  luaL_buffinit(L, &b);
415  p = luaL_prepbuffsize(&b, n);  /* prepare buffer to read whole block */
416  nr = fread(p, sizeof(char), n, f);  /* try to read 'n' chars */
417  luaL_addsize(&b, nr);
418  luaL_pushresult(&b);  /* close buffer */
419  return (nr > 0);  /* true iff read something */
420}
421
422
423static int g_read (lua_State *L, FILE *f, int first) {
424  int nargs = lua_gettop(L) - 1;
425  int success;
426  int n;
427  clearerr(f);
428  if (nargs == 0) {  /* no arguments? */
429    success = read_line(L, f, 1);
430    n = first+1;  /* to return 1 result */
431  }
432  else {  /* ensure stack space for all results and for auxlib's buffer */
433    luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
434    success = 1;
435    for (n = first; nargs-- && success; n++) {
436      if (lua_type(L, n) == LUA_TNUMBER) {
437        size_t l = (size_t)lua_tointeger(L, n);
438        success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
439      }
440      else {
441        const char *p = lua_tostring(L, n);
442        luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
443        switch (p[1]) {
444          case 'n':  /* number */
445            success = read_number(L, f);
446            break;
447          case 'l':  /* line */
448            success = read_line(L, f, 1);
449            break;
450          case 'L':  /* line with end-of-line */
451            success = read_line(L, f, 0);
452            break;
453          case 'a':  /* file */
454            read_all(L, f);  /* read entire file */
455            success = 1; /* always success */
456            break;
457          default:
458            return luaL_argerror(L, n, "invalid format");
459        }
460      }
461    }
462  }
463  if (ferror(f))
464    return luaL_fileresult(L, 0, NULL);
465  if (!success) {
466    lua_pop(L, 1);  /* remove last result */
467    lua_pushnil(L);  /* push nil instead */
468  }
469  return n - first;
470}
471
472
473static int io_read (lua_State *L) {
474  return g_read(L, getiofile(L, IO_INPUT), 1);
475}
476
477
478static int f_read (lua_State *L) {
479  return g_read(L, tofile(L), 2);
480}
481
482
483static int io_readline (lua_State *L) {
484  LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1));
485  int i;
486  int n = (int)lua_tointeger(L, lua_upvalueindex(2));
487  if (isclosed(p))  /* file is already closed? */
488    return luaL_error(L, "file is already closed");
489  lua_settop(L , 1);
490  for (i = 1; i <= n; i++)  /* push arguments to 'g_read' */
491    lua_pushvalue(L, lua_upvalueindex(3 + i));
492  n = g_read(L, p->f, 2);  /* 'n' is number of results */
493  lua_assert(n > 0);  /* should return at least a nil */
494  if (!lua_isnil(L, -n))  /* read at least one value? */
495    return n;  /* return them */
496  else {  /* first result is nil: EOF or error */
497    if (n > 1) {  /* is there error information? */
498      /* 2nd result is error message */
499      return luaL_error(L, "%s", lua_tostring(L, -n + 1));
500    }
501    if (lua_toboolean(L, lua_upvalueindex(3))) {  /* generator created file? */
502      lua_settop(L, 0);
503      lua_pushvalue(L, lua_upvalueindex(1));
504      aux_close(L);  /* close it */
505    }
506    return 0;
507  }
508}
509
510/* }====================================================== */
511
512
513static int g_write (lua_State *L, FILE *f, int arg) {
514  int nargs = lua_gettop(L) - arg;
515  int status = 1;
516  for (; nargs--; arg++) {
517    if (lua_type(L, arg) == LUA_TNUMBER) {
518      /* optimization: could be done exactly as for strings */
519      status = status &&
520          fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
521    }
522    else {
523      size_t l;
524      const char *s = luaL_checklstring(L, arg, &l);
525      status = status && (fwrite(s, sizeof(char), l, f) == l);
526    }
527  }
528  if (status) return 1;  /* file handle already on stack top */
529  else return luaL_fileresult(L, status, NULL);
530}
531
532
533static int io_write (lua_State *L) {
534  return g_write(L, getiofile(L, IO_OUTPUT), 1);
535}
536
537
538static int f_write (lua_State *L) {
539  FILE *f = tofile(L);
540  lua_pushvalue(L, 1);  /* push file at the stack top (to be returned) */
541  return g_write(L, f, 2);
542}
543
544
545static int f_seek (lua_State *L) {
546  static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
547  static const char *const modenames[] = {"set", "cur", "end", NULL};
548  FILE *f = tofile(L);
549  int op = luaL_checkoption(L, 2, "cur", modenames);
550  lua_Number p3 = luaL_optnumber(L, 3, 0);
551  l_seeknum offset = (l_seeknum)p3;
552  luaL_argcheck(L, (lua_Number)offset == p3, 3,
553                  "not an integer in proper range");
554  op = l_fseek(f, offset, mode[op]);
555  if (op)
556    return luaL_fileresult(L, 0, NULL);  /* error */
557  else {
558    lua_pushnumber(L, (lua_Number)(1.0*l_ftell(f)));
559    return 1;
560  }
561}
562
563
564static int f_setvbuf (lua_State *L) {
565  static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
566  static const char *const modenames[] = {"no", "full", "line", NULL};
567  FILE *f = tofile(L);
568  int op = luaL_checkoption(L, 2, NULL, modenames);
569  lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
570  int res = setvbuf(f, NULL, mode[op], sz);
571  return luaL_fileresult(L, res == 0, NULL);
572}
573
574
575
576static int io_flush (lua_State *L) {
577  return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
578}
579
580
581static int f_flush (lua_State *L) {
582  return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL);
583}
584
585
586/*
587** functions for 'io' library
588*/
589static const luaL_Reg iolib[] = {
590  {"close", io_close},
591  {"flush", io_flush},
592  {"input", io_input},
593  {"lines", io_lines},
594  {"open", io_open},
595  {"output", io_output},
596  {"popen", io_popen},
597  {"read", io_read},
598  {"tmpfile", io_tmpfile},
599  {"type", io_type},
600  {"write", io_write},
601  {NULL, NULL}
602};
603
604
605/*
606** methods for file handles
607*/
608static const luaL_Reg flib[] = {
609  {"close", io_close},
610  {"flush", f_flush},
611  {"lines", f_lines},
612  {"read", f_read},
613  {"seek", f_seek},
614  {"setvbuf", f_setvbuf},
615  {"write", f_write},
616  {"__gc", f_gc},
617  {"__tostring", f_tostring},
618  {NULL, NULL}
619};
620
621
622static void createmeta (lua_State *L) {
623  luaL_newmetatable(L, LUA_FILEHANDLE);  /* create metatable for file handles */
624  lua_pushvalue(L, -1);  /* push metatable */
625  lua_setfield(L, -2, "__index");  /* metatable.__index = metatable */
626  luaL_setfuncs(L, flib, 0);  /* add file methods to new metatable */
627  lua_pop(L, 1);  /* pop new metatable */
628}
629
630
631/*
632** function to (not) close the standard files stdin, stdout, and stderr
633*/
634static int io_noclose (lua_State *L) {
635  LStream *p = tolstream(L);
636  p->closef = &io_noclose;  /* keep file opened */
637  lua_pushnil(L);
638  lua_pushliteral(L, "cannot close standard file");
639  return 2;
640}
641
642
643static void createstdfile (lua_State *L, FILE *f, const char *k,
644                           const char *fname) {
645  LStream *p = newprefile(L);
646  p->f = f;
647  p->closef = &io_noclose;
648  if (k != NULL) {
649    lua_pushvalue(L, -1);
650    lua_setfield(L, LUA_REGISTRYINDEX, k);  /* add file to registry */
651  }
652  lua_setfield(L, -2, fname);  /* add file to module */
653}
654
655
656LUAMOD_API int luaopen_io (lua_State *L) {
657  luaL_newlib(L, iolib);  /* new module */
658  createmeta(L);
659  /* create (and set) default files */
660  createstdfile(L, stdin, IO_INPUT, "stdin");
661  createstdfile(L, stdout, IO_OUTPUT, "stdout");
662  createstdfile(L, stderr, NULL, "stderr");
663  return 1;
664}
665
Property changes on: trunk/src/lib/lua/liolib.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lfunc.h
r0r22721
1/*
2** $Id: lfunc.h,v 2.8 2012/05/08 13:53:33 roberto Exp $
3** Auxiliary functions to manipulate prototypes and closures
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lfunc_h
8#define lfunc_h
9
10
11#include "lobject.h"
12
13
14#define sizeCclosure(n)   (cast(int, sizeof(CClosure)) + \
15                         cast(int, sizeof(TValue)*((n)-1)))
16
17#define sizeLclosure(n)   (cast(int, sizeof(LClosure)) + \
18                         cast(int, sizeof(TValue *)*((n)-1)))
19
20
21LUAI_FUNC Proto *luaF_newproto (lua_State *L);
22LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems);
23LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems);
24LUAI_FUNC UpVal *luaF_newupval (lua_State *L);
25LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
26LUAI_FUNC void luaF_close (lua_State *L, StkId level);
27LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
28LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv);
29LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
30                                         int pc);
31
32
33#endif
Property changes on: trunk/src/lib/lua/lfunc.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lparser.h
r0r22721
1/*
2** $Id: lparser.h,v 1.70 2012/05/08 13:53:33 roberto Exp $
3** Lua Parser
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lparser_h
8#define lparser_h
9
10#include "llimits.h"
11#include "lobject.h"
12#include "lzio.h"
13
14
15/*
16** Expression descriptor
17*/
18
19typedef enum {
20  VVOID,   /* no value */
21  VNIL,
22  VTRUE,
23  VFALSE,
24  VK,      /* info = index of constant in `k' */
25  VKNUM,   /* nval = numerical value */
26  VNONRELOC,   /* info = result register */
27  VLOCAL,   /* info = local register */
28  VUPVAL,       /* info = index of upvalue in 'upvalues' */
29  VINDEXED,   /* t = table register/upvalue; idx = index R/K */
30  VJMP,      /* info = instruction pc */
31  VRELOCABLE,   /* info = instruction pc */
32  VCALL,   /* info = instruction pc */
33  VVARARG   /* info = instruction pc */
34} expkind;
35
36
37#define vkisvar(k)   (VLOCAL <= (k) && (k) <= VINDEXED)
38#define vkisinreg(k)   ((k) == VNONRELOC || (k) == VLOCAL)
39
40typedef struct expdesc {
41  expkind k;
42  union {
43    struct {  /* for indexed variables (VINDEXED) */
44      short idx;  /* index (R/K) */
45      lu_byte t;  /* table (register or upvalue) */
46      lu_byte vt;  /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
47    } ind;
48    int info;  /* for generic use */
49    lua_Number nval;  /* for VKNUM */
50  } u;
51  int t;  /* patch list of `exit when true' */
52  int f;  /* patch list of `exit when false' */
53} expdesc;
54
55
56/* description of active local variable */
57typedef struct Vardesc {
58  short idx;  /* variable index in stack */
59} Vardesc;
60
61
62/* description of pending goto statements and label statements */
63typedef struct Labeldesc {
64  TString *name;  /* label identifier */
65  int pc;  /* position in code */
66  int line;  /* line where it appeared */
67  lu_byte nactvar;  /* local level where it appears in current block */
68} Labeldesc;
69
70
71/* list of labels or gotos */
72typedef struct Labellist {
73  Labeldesc *arr;  /* array */
74  int n;  /* number of entries in use */
75  int size;  /* array size */
76} Labellist;
77
78
79/* dynamic structures used by the parser */
80typedef struct Dyndata {
81  struct {  /* list of active local variables */
82    Vardesc *arr;
83    int n;
84    int size;
85  } actvar;
86  Labellist gt;  /* list of pending gotos */
87  Labellist label;   /* list of active labels */
88} Dyndata;
89
90
91/* control of blocks */
92struct BlockCnt;  /* defined in lparser.c */
93
94
95/* state needed to generate code for a given function */
96typedef struct FuncState {
97  Proto *f;  /* current function header */
98  Table *h;  /* table to find (and reuse) elements in `k' */
99  struct FuncState *prev;  /* enclosing function */
100  struct LexState *ls;  /* lexical state */
101  struct BlockCnt *bl;  /* chain of current blocks */
102  int pc;  /* next position to code (equivalent to `ncode') */
103  int lasttarget;   /* 'label' of last 'jump label' */
104  int jpc;  /* list of pending jumps to `pc' */
105  int nk;  /* number of elements in `k' */
106  int np;  /* number of elements in `p' */
107  int firstlocal;  /* index of first local var (in Dyndata array) */
108  short nlocvars;  /* number of elements in 'f->locvars' */
109  lu_byte nactvar;  /* number of active local variables */
110  lu_byte nups;  /* number of upvalues */
111  lu_byte freereg;  /* first free register */
112} FuncState;
113
114
115LUAI_FUNC Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
116                                Dyndata *dyd, const char *name, int firstchar);
117
118
119#endif
Property changes on: trunk/src/lib/lua/lparser.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lualib.h
r0r22721
1/*
2** $Id: lualib.h,v 1.43 2011/12/08 12:11:37 roberto Exp $
3** Lua standard libraries
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lualib_h
9#define lualib_h
10
11#include "lua.h"
12
13
14
15LUAMOD_API int (luaopen_base) (lua_State *L);
16
17#define LUA_COLIBNAME   "coroutine"
18LUAMOD_API int (luaopen_coroutine) (lua_State *L);
19
20#define LUA_TABLIBNAME   "table"
21LUAMOD_API int (luaopen_table) (lua_State *L);
22
23#define LUA_IOLIBNAME   "io"
24LUAMOD_API int (luaopen_io) (lua_State *L);
25
26#define LUA_OSLIBNAME   "os"
27LUAMOD_API int (luaopen_os) (lua_State *L);
28
29#define LUA_STRLIBNAME   "string"
30LUAMOD_API int (luaopen_string) (lua_State *L);
31
32#define LUA_BITLIBNAME   "bit32"
33LUAMOD_API int (luaopen_bit32) (lua_State *L);
34
35#define LUA_MATHLIBNAME   "math"
36LUAMOD_API int (luaopen_math) (lua_State *L);
37
38#define LUA_DBLIBNAME   "debug"
39LUAMOD_API int (luaopen_debug) (lua_State *L);
40
41#define LUA_LOADLIBNAME   "package"
42LUAMOD_API int (luaopen_package) (lua_State *L);
43
44
45/* open all previous libraries */
46LUALIB_API void (luaL_openlibs) (lua_State *L);
47
48
49
50#if !defined(lua_assert)
51#define lua_assert(x)   ((void)0)
52#endif
53
54
55#endif
Property changes on: trunk/src/lib/lua/lualib.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/linit.c
r0r22721
1/*
2** $Id: linit.c,v 1.32 2011/04/08 19:17:36 roberto Exp $
3** Initialization of libraries for lua.c and other clients
4** See Copyright Notice in lua.h
5*/
6
7
8/*
9** If you embed Lua in your program and need to open the standard
10** libraries, call luaL_openlibs in your program. If you need a
11** different set of libraries, copy this file to your project and edit
12** it to suit your needs.
13*/
14
15
16#define linit_c
17#define LUA_LIB
18
19#include "lua.h"
20
21#include "lualib.h"
22#include "lauxlib.h"
23
24
25/*
26** these libs are loaded by lua.c and are readily available to any Lua
27** program
28*/
29static const luaL_Reg loadedlibs[] = {
30  {"_G", luaopen_base},
31  {LUA_LOADLIBNAME, luaopen_package},
32  {LUA_COLIBNAME, luaopen_coroutine},
33  {LUA_TABLIBNAME, luaopen_table},
34  {LUA_IOLIBNAME, luaopen_io},
35  {LUA_OSLIBNAME, luaopen_os},
36  {LUA_STRLIBNAME, luaopen_string},
37  {LUA_BITLIBNAME, luaopen_bit32},
38  {LUA_MATHLIBNAME, luaopen_math},
39  {LUA_DBLIBNAME, luaopen_debug},
40  {NULL, NULL}
41};
42
43
44/*
45** these libs are preloaded and must be required before used
46*/
47static const luaL_Reg preloadedlibs[] = {
48  {NULL, NULL}
49};
50
51
52LUALIB_API void luaL_openlibs (lua_State *L) {
53  const luaL_Reg *lib;
54  /* call open functions from 'loadedlibs' and set results to global table */
55  for (lib = loadedlibs; lib->func; lib++) {
56    luaL_requiref(L, lib->name, lib->func, 1);
57    lua_pop(L, 1);  /* remove lib */
58  }
59  /* add open functions from 'preloadedlibs' into 'package.preload' table */
60  luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
61  for (lib = preloadedlibs; lib->func; lib++) {
62    lua_pushcfunction(L, lib->func);
63    lua_setfield(L, -2, lib->name);
64  }
65  lua_pop(L, 1);  /* remove _PRELOAD table */
66}
67
Property changes on: trunk/src/lib/lua/linit.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lua.c
r0r22721
1/*
2** $Id: lua.c,v 1.206 2012/09/29 20:07:06 roberto Exp $
3** Lua stand-alone interpreter
4** See Copyright Notice in lua.h
5*/
6
7
8#include <signal.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12
13#define lua_c
14
15#include "lua.h"
16
17#include "lauxlib.h"
18#include "lualib.h"
19
20
21#if !defined(LUA_PROMPT)
22#define LUA_PROMPT      "> "
23#define LUA_PROMPT2      ">> "
24#endif
25
26#if !defined(LUA_PROGNAME)
27#define LUA_PROGNAME      "lua"
28#endif
29
30#if !defined(LUA_MAXINPUT)
31#define LUA_MAXINPUT      512
32#endif
33
34#if !defined(LUA_INIT)
35#define LUA_INIT      "LUA_INIT"
36#endif
37
38#define LUA_INITVERSION  \
39   LUA_INIT "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
40
41
42/*
43** lua_stdin_is_tty detects whether the standard input is a 'tty' (that
44** is, whether we're running lua interactively).
45*/
46#if defined(LUA_USE_ISATTY)
47#include <unistd.h>
48#define lua_stdin_is_tty()   isatty(0)
49#elif defined(LUA_WIN)
50#include <io.h>
51#include <stdio.h>
52#define lua_stdin_is_tty()   _isatty(_fileno(stdin))
53#else
54#define lua_stdin_is_tty()   1  /* assume stdin is a tty */
55#endif
56
57
58/*
59** lua_readline defines how to show a prompt and then read a line from
60** the standard input.
61** lua_saveline defines how to "save" a read line in a "history".
62** lua_freeline defines how to free a line read by lua_readline.
63*/
64#if defined(LUA_USE_READLINE)
65
66#include <stdio.h>
67#include <readline/readline.h>
68#include <readline/history.h>
69#define lua_readline(L,b,p)   ((void)L, ((b)=readline(p)) != NULL)
70#define lua_saveline(L,idx) \
71        if (lua_rawlen(L,idx) > 0)  /* non-empty line? */ \
72          add_history(lua_tostring(L, idx));  /* add it to history */
73#define lua_freeline(L,b)   ((void)L, free(b))
74
75#elif !defined(lua_readline)
76
77#define lua_readline(L,b,p) \
78        ((void)L, fputs(p, stdout), fflush(stdout),  /* show prompt */ \
79        fgets(b, LUA_MAXINPUT, stdin) != NULL)  /* get line */
80#define lua_saveline(L,idx)   { (void)L; (void)idx; }
81#define lua_freeline(L,b)   { (void)L; (void)b; }
82
83#endif
84
85
86
87
88static lua_State *globalL = NULL;
89
90static const char *progname = LUA_PROGNAME;
91
92
93
94static void lstop (lua_State *L, lua_Debug *ar) {
95  (void)ar;  /* unused arg. */
96  lua_sethook(L, NULL, 0, 0);
97  luaL_error(L, "interrupted!");
98}
99
100
101static void laction (int i) {
102  signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
103                              terminate process (default action) */
104  lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
105}
106
107
108static void print_usage (const char *badoption) {
109  luai_writestringerror("%s: ", progname);
110  if (badoption[1] == 'e' || badoption[1] == 'l')
111    luai_writestringerror("'%s' needs argument\n", badoption);
112  else
113    luai_writestringerror("unrecognized option '%s'\n", badoption);
114  luai_writestringerror(
115  "usage: %s [options] [script [args]]\n"
116  "Available options are:\n"
117  "  -e stat  execute string " LUA_QL("stat") "\n"
118  "  -i       enter interactive mode after executing " LUA_QL("script") "\n"
119  "  -l name  require library " LUA_QL("name") "\n"
120  "  -v       show version information\n"
121  "  -E       ignore environment variables\n"
122  "  --       stop handling options\n"
123  "  -        stop handling options and execute stdin\n"
124  ,
125  progname);
126}
127
128
129static void l_message (const char *pname, const char *msg) {
130  if (pname) luai_writestringerror("%s: ", pname);
131  luai_writestringerror("%s\n", msg);
132}
133
134
135static int report (lua_State *L, int status) {
136  if (status != LUA_OK && !lua_isnil(L, -1)) {
137    const char *msg = lua_tostring(L, -1);
138    if (msg == NULL) msg = "(error object is not a string)";
139    l_message(progname, msg);
140    lua_pop(L, 1);
141    /* force a complete garbage collection in case of errors */
142    lua_gc(L, LUA_GCCOLLECT, 0);
143  }
144  return status;
145}
146
147
148/* the next function is called unprotected, so it must avoid errors */
149static void finalreport (lua_State *L, int status) {
150  if (status != LUA_OK) {
151    const char *msg = (lua_type(L, -1) == LUA_TSTRING) ? lua_tostring(L, -1)
152                                                       : NULL;
153    if (msg == NULL) msg = "(error object is not a string)";
154    l_message(progname, msg);
155    lua_pop(L, 1);
156  }
157}
158
159
160static int traceback (lua_State *L) {
161  const char *msg = lua_tostring(L, 1);
162  if (msg)
163    luaL_traceback(L, L, msg, 1);
164  else if (!lua_isnoneornil(L, 1)) {  /* is there an error object? */
165    if (!luaL_callmeta(L, 1, "__tostring"))  /* try its 'tostring' metamethod */
166      lua_pushliteral(L, "(no error message)");
167  }
168  return 1;
169}
170
171
172static int docall (lua_State *L, int narg, int nres) {
173  int status;
174  int base = lua_gettop(L) - narg;  /* function index */
175  lua_pushcfunction(L, traceback);  /* push traceback function */
176  lua_insert(L, base);  /* put it under chunk and args */
177  globalL = L;  /* to be available to 'laction' */
178  signal(SIGINT, laction);
179  status = lua_pcall(L, narg, nres, base);
180  signal(SIGINT, SIG_DFL);
181  lua_remove(L, base);  /* remove traceback function */
182  return status;
183}
184
185
186static void print_version (void) {
187  luai_writestring(LUA_COPYRIGHT, strlen(LUA_COPYRIGHT));
188  luai_writeline();
189}
190
191
192static int getargs (lua_State *L, char **argv, int n) {
193  int narg;
194  int i;
195  int argc = 0;
196  while (argv[argc]) argc++;  /* count total number of arguments */
197  narg = argc - (n + 1);  /* number of arguments to the script */
198  luaL_checkstack(L, narg + 3, "too many arguments to script");
199  for (i=n+1; i < argc; i++)
200    lua_pushstring(L, argv[i]);
201  lua_createtable(L, narg, n + 1);
202  for (i=0; i < argc; i++) {
203    lua_pushstring(L, argv[i]);
204    lua_rawseti(L, -2, i - n);
205  }
206  return narg;
207}
208
209
210static int dofile (lua_State *L, const char *name) {
211  int status = luaL_loadfile(L, name);
212  if (status == LUA_OK) status = docall(L, 0, 0);
213  return report(L, status);
214}
215
216
217static int dostring (lua_State *L, const char *s, const char *name) {
218  int status = luaL_loadbuffer(L, s, strlen(s), name);
219  if (status == LUA_OK) status = docall(L, 0, 0);
220  return report(L, status);
221}
222
223
224static int dolibrary (lua_State *L, const char *name) {
225  int status;
226  lua_getglobal(L, "require");
227  lua_pushstring(L, name);
228  status = docall(L, 1, 1);  /* call 'require(name)' */
229  if (status == LUA_OK)
230    lua_setglobal(L, name);  /* global[name] = require return */
231  return report(L, status);
232}
233
234
235static const char *get_prompt (lua_State *L, int firstline) {
236  const char *p;
237  lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2");
238  p = lua_tostring(L, -1);
239  if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
240  return p;
241}
242
243/* mark in error messages for incomplete statements */
244#define EOFMARK      "<eof>"
245#define marklen      (sizeof(EOFMARK)/sizeof(char) - 1)
246
247static int incomplete (lua_State *L, int status) {
248  if (status == LUA_ERRSYNTAX) {
249    size_t lmsg;
250    const char *msg = lua_tolstring(L, -1, &lmsg);
251    if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) {
252      lua_pop(L, 1);
253      return 1;
254    }
255  }
256  return 0;  /* else... */
257}
258
259
260static int pushline (lua_State *L, int firstline) {
261  char buffer[LUA_MAXINPUT];
262  char *b = buffer;
263  size_t l;
264  const char *prmt = get_prompt(L, firstline);
265  int readstatus = lua_readline(L, b, prmt);
266  lua_pop(L, 1);  /* remove result from 'get_prompt' */
267  if (readstatus == 0)
268    return 0;  /* no input */
269  l = strlen(b);
270  if (l > 0 && b[l-1] == '\n')  /* line ends with newline? */
271    b[l-1] = '\0';  /* remove it */
272  if (firstline && b[0] == '=')  /* first line starts with `=' ? */
273    lua_pushfstring(L, "return %s", b+1);  /* change it to `return' */
274  else
275    lua_pushstring(L, b);
276  lua_freeline(L, b);
277  return 1;
278}
279
280
281static int loadline (lua_State *L) {
282  int status;
283  lua_settop(L, 0);
284  if (!pushline(L, 1))
285    return -1;  /* no input */
286  for (;;) {  /* repeat until gets a complete line */
287    size_t l;
288    const char *line = lua_tolstring(L, 1, &l);
289    status = luaL_loadbuffer(L, line, l, "=stdin");
290    if (!incomplete(L, status)) break;  /* cannot try to add lines? */
291    if (!pushline(L, 0))  /* no more input? */
292      return -1;
293    lua_pushliteral(L, "\n");  /* add a new line... */
294    lua_insert(L, -2);  /* ...between the two lines */
295    lua_concat(L, 3);  /* join them */
296  }
297  lua_saveline(L, 1);
298  lua_remove(L, 1);  /* remove line */
299  return status;
300}
301
302
303static void dotty (lua_State *L) {
304  int status;
305  const char *oldprogname = progname;
306  progname = NULL;
307  while ((status = loadline(L)) != -1) {
308    if (status == LUA_OK) status = docall(L, 0, LUA_MULTRET);
309    report(L, status);
310    if (status == LUA_OK && lua_gettop(L) > 0) {  /* any result to print? */
311      luaL_checkstack(L, LUA_MINSTACK, "too many results to print");
312      lua_getglobal(L, "print");
313      lua_insert(L, 1);
314      if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != LUA_OK)
315        l_message(progname, lua_pushfstring(L,
316                               "error calling " LUA_QL("print") " (%s)",
317                               lua_tostring(L, -1)));
318    }
319  }
320  lua_settop(L, 0);  /* clear stack */
321  luai_writeline();
322  progname = oldprogname;
323}
324
325
326static int handle_script (lua_State *L, char **argv, int n) {
327  int status;
328  const char *fname;
329  int narg = getargs(L, argv, n);  /* collect arguments */
330  lua_setglobal(L, "arg");
331  fname = argv[n];
332  if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0)
333    fname = NULL;  /* stdin */
334  status = luaL_loadfile(L, fname);
335  lua_insert(L, -(narg+1));
336  if (status == LUA_OK)
337    status = docall(L, narg, LUA_MULTRET);
338  else
339    lua_pop(L, narg);
340  return report(L, status);
341}
342
343
344/* check that argument has no extra characters at the end */
345#define noextrachars(x)      {if ((x)[2] != '\0') return -1;}
346
347
348/* indices of various argument indicators in array args */
349#define has_i      0   /* -i */
350#define has_v      1   /* -v */
351#define has_e      2   /* -e */
352#define has_E      3   /* -E */
353
354#define num_has      4   /* number of 'has_*' */
355
356
357static int collectargs (char **argv, int *args) {
358  int i;
359  for (i = 1; argv[i] != NULL; i++) {
360    if (argv[i][0] != '-')  /* not an option? */
361        return i;
362    switch (argv[i][1]) {  /* option */
363      case '-':
364        noextrachars(argv[i]);
365        return (argv[i+1] != NULL ? i+1 : 0);
366      case '\0':
367        return i;
368      case 'E':
369        args[has_E] = 1;
370        break;
371      case 'i':
372        noextrachars(argv[i]);
373        args[has_i] = 1;  /* go through */
374      case 'v':
375        noextrachars(argv[i]);
376        args[has_v] = 1;
377        break;
378      case 'e':
379        args[has_e] = 1;  /* go through */
380      case 'l':  /* both options need an argument */
381        if (argv[i][2] == '\0') {  /* no concatenated argument? */
382          i++;  /* try next 'argv' */
383          if (argv[i] == NULL || argv[i][0] == '-')
384            return -(i - 1);  /* no next argument or it is another option */
385        }
386        break;
387      default:  /* invalid option; return its index... */
388        return -i;  /* ...as a negative value */
389    }
390  }
391  return 0;
392}
393
394
395static int runargs (lua_State *L, char **argv, int n) {
396  int i;
397  for (i = 1; i < n; i++) {
398    lua_assert(argv[i][0] == '-');
399    switch (argv[i][1]) {  /* option */
400      case 'e': {
401        const char *chunk = argv[i] + 2;
402        if (*chunk == '\0') chunk = argv[++i];
403        lua_assert(chunk != NULL);
404        if (dostring(L, chunk, "=(command line)") != LUA_OK)
405          return 0;
406        break;
407      }
408      case 'l': {
409        const char *filename = argv[i] + 2;
410        if (*filename == '\0') filename = argv[++i];
411        lua_assert(filename != NULL);
412        if (dolibrary(L, filename) != LUA_OK)
413          return 0;  /* stop if file fails */
414        break;
415      }
416      default: break;
417    }
418  }
419  return 1;
420}
421
422
423static int handle_luainit (lua_State *L) {
424  const char *name = "=" LUA_INITVERSION;
425  const char *init = getenv(name + 1);
426  if (init == NULL) {
427    name = "=" LUA_INIT;
428    init = getenv(name + 1);  /* try alternative name */
429  }
430  if (init == NULL) return LUA_OK;
431  else if (init[0] == '@')
432    return dofile(L, init+1);
433  else
434    return dostring(L, init, name);
435}
436
437
438static int pmain (lua_State *L) {
439  int argc = (int)lua_tointeger(L, 1);
440  char **argv = (char **)lua_touserdata(L, 2);
441  int script;
442  int args[num_has];
443  args[has_i] = args[has_v] = args[has_e] = args[has_E] = 0;
444  if (argv[0] && argv[0][0]) progname = argv[0];
445  script = collectargs(argv, args);
446  if (script < 0) {  /* invalid arg? */
447    print_usage(argv[-script]);
448    return 0;
449  }
450  if (args[has_v]) print_version();
451  if (args[has_E]) {  /* option '-E'? */
452    lua_pushboolean(L, 1);  /* signal for libraries to ignore env. vars. */
453    lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
454  }
455  /* open standard libraries */
456  luaL_checkversion(L);
457  lua_gc(L, LUA_GCSTOP, 0);  /* stop collector during initialization */
458  luaL_openlibs(L);  /* open libraries */
459  lua_gc(L, LUA_GCRESTART, 0);
460  if (!args[has_E] && handle_luainit(L) != LUA_OK)
461    return 0;  /* error running LUA_INIT */
462  /* execute arguments -e and -l */
463  if (!runargs(L, argv, (script > 0) ? script : argc)) return 0;
464  /* execute main script (if there is one) */
465  if (script && handle_script(L, argv, script) != LUA_OK) return 0;
466  if (args[has_i])  /* -i option? */
467    dotty(L);
468  else if (script == 0 && !args[has_e] && !args[has_v]) {  /* no arguments? */
469    if (lua_stdin_is_tty()) {
470      print_version();
471      dotty(L);
472    }
473    else dofile(L, NULL);  /* executes stdin as a file */
474  }
475  lua_pushboolean(L, 1);  /* signal no errors */
476  return 1;
477}
478
479
480int main (int argc, char **argv) {
481  int status, result;
482  lua_State *L = luaL_newstate();  /* create state */
483  if (L == NULL) {
484    l_message(argv[0], "cannot create state: not enough memory");
485    return EXIT_FAILURE;
486  }
487  /* call 'pmain' in protected mode */
488  lua_pushcfunction(L, &pmain);
489  lua_pushinteger(L, argc);  /* 1st argument */
490  lua_pushlightuserdata(L, argv); /* 2nd argument */
491  status = lua_pcall(L, 2, 1, 0);
492  result = lua_toboolean(L, -1);  /* get result */
493  finalreport(L, status);
494  lua_close(L);
495  return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
496}
497
Property changes on: trunk/src/lib/lua/lua.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/llimits.h
r0r22721
1/*
2** $Id: llimits.h,v 1.103 2013/02/20 14:08:56 roberto Exp $
3** Limits, basic types, and some other `installation-dependent' definitions
4** See Copyright Notice in lua.h
5*/
6
7#ifndef llimits_h
8#define llimits_h
9
10
11#include <limits.h>
12#include <stddef.h>
13
14
15#include "lua.h"
16
17
18typedef unsigned LUA_INT32 lu_int32;
19
20typedef LUAI_UMEM lu_mem;
21
22typedef LUAI_MEM l_mem;
23
24
25
26/* chars used as small naturals (so that `char' is reserved for characters) */
27typedef unsigned char lu_byte;
28
29
30#define MAX_SIZET   ((size_t)(~(size_t)0)-2)
31
32#define MAX_LUMEM   ((lu_mem)(~(lu_mem)0)-2)
33
34#define MAX_LMEM   ((l_mem) ((MAX_LUMEM >> 1) - 2))
35
36
37#define MAX_INT (INT_MAX-2)  /* maximum value of an int (-2 for safety) */
38
39/*
40** conversion of pointer to integer
41** this is for hashing only; there is no problem if the integer
42** cannot hold the whole pointer value
43*/
44#define IntPoint(p)  ((unsigned int)(lu_mem)(p))
45
46
47
48/* type to ensure maximum alignment */
49#if !defined(LUAI_USER_ALIGNMENT_T)
50#define LUAI_USER_ALIGNMENT_T   union { double u; void *s; long l; }
51#endif
52
53typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
54
55
56/* result of a `usual argument conversion' over lua_Number */
57typedef LUAI_UACNUMBER l_uacNumber;
58
59
60/* internal assertions for in-house debugging */
61#if defined(lua_assert)
62#define check_exp(c,e)      (lua_assert(c), (e))
63/* to avoid problems with conditions too long */
64#define lua_longassert(c)   { if (!(c)) lua_assert(0); }
65#else
66#define lua_assert(c)      ((void)0)
67#define check_exp(c,e)      (e)
68#define lua_longassert(c)   ((void)0)
69#endif
70
71/*
72** assertion for checking API calls
73*/
74#if !defined(luai_apicheck)
75
76#if defined(LUA_USE_APICHECK)
77#include <assert.h>
78#define luai_apicheck(L,e)   assert(e)
79#else
80#define luai_apicheck(L,e)   lua_assert(e)
81#endif
82
83#endif
84
85#define api_check(l,e,msg)   luai_apicheck(l,(e) && msg)
86
87
88#if !defined(UNUSED)
89#define UNUSED(x)   ((void)(x))   /* to avoid warnings */
90#endif
91
92
93#define cast(t, exp)   ((t)(exp))
94
95#define cast_byte(i)   cast(lu_byte, (i))
96#define cast_num(i)   cast(lua_Number, (i))
97#define cast_int(i)   cast(int, (i))
98#define cast_uchar(i)   cast(unsigned char, (i))
99
100
101/*
102** non-return type
103*/
104#if defined(__GNUC__)
105#define l_noret      void __attribute__((noreturn))
106#elif defined(_MSC_VER)
107#define l_noret      void __declspec(noreturn)
108#else
109#define l_noret      void
110#endif
111
112
113
114/*
115** maximum depth for nested C calls and syntactical nested non-terminals
116** in a program. (Value must fit in an unsigned short int.)
117*/
118#if !defined(LUAI_MAXCCALLS)
119#define LUAI_MAXCCALLS      200
120#endif
121
122/*
123** maximum number of upvalues in a closure (both C and Lua). (Value
124** must fit in an unsigned char.)
125*/
126#define MAXUPVAL   UCHAR_MAX
127
128
129/*
130** type for virtual-machine instructions
131** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
132*/
133typedef lu_int32 Instruction;
134
135
136
137/* maximum stack for a Lua function */
138#define MAXSTACK   250
139
140
141
142/* minimum size for the string table (must be power of 2) */
143#if !defined(MINSTRTABSIZE)
144#define MINSTRTABSIZE   32
145#endif
146
147
148/* minimum size for string buffer */
149#if !defined(LUA_MINBUFFER)
150#define LUA_MINBUFFER   32
151#endif
152
153
154#if !defined(lua_lock)
155#define lua_lock(L)     ((void) 0)
156#define lua_unlock(L)   ((void) 0)
157#endif
158
159#if !defined(luai_threadyield)
160#define luai_threadyield(L)     {lua_unlock(L); lua_lock(L);}
161#endif
162
163
164/*
165** these macros allow user-specific actions on threads when you defined
166** LUAI_EXTRASPACE and need to do something extra when a thread is
167** created/deleted/resumed/yielded.
168*/
169#if !defined(luai_userstateopen)
170#define luai_userstateopen(L)      ((void)L)
171#endif
172
173#if !defined(luai_userstateclose)
174#define luai_userstateclose(L)      ((void)L)
175#endif
176
177#if !defined(luai_userstatethread)
178#define luai_userstatethread(L,L1)   ((void)L)
179#endif
180
181#if !defined(luai_userstatefree)
182#define luai_userstatefree(L,L1)   ((void)L)
183#endif
184
185#if !defined(luai_userstateresume)
186#define luai_userstateresume(L,n)       ((void)L)
187#endif
188
189#if !defined(luai_userstateyield)
190#define luai_userstateyield(L,n)        ((void)L)
191#endif
192
193/*
194** lua_number2int is a macro to convert lua_Number to int.
195** lua_number2integer is a macro to convert lua_Number to lua_Integer.
196** lua_number2unsigned is a macro to convert a lua_Number to a lua_Unsigned.
197** lua_unsigned2number is a macro to convert a lua_Unsigned to a lua_Number.
198** luai_hashnum is a macro to hash a lua_Number value into an integer.
199** The hash must be deterministic and give reasonable values for
200** both small and large values (outside the range of integers).
201*/
202
203#if defined(MS_ASMTRICK) || defined(LUA_MSASMTRICK)   /* { */
204/* trick with Microsoft assembler for X86 */
205
206#define lua_number2int(i,n)  __asm {__asm fld n   __asm fistp i}
207#define lua_number2integer(i,n)      lua_number2int(i, n)
208#define lua_number2unsigned(i,n)  \
209  {__int64 l; __asm {__asm fld n   __asm fistp l} i = (unsigned int)l;}
210
211
212#elif defined(LUA_IEEE754TRICK)      /* }{ */
213/* the next trick should work on any machine using IEEE754 with
214   a 32-bit int type */
215
216union luai_Cast { double l_d; LUA_INT32 l_p[2]; };
217
218#if !defined(LUA_IEEEENDIAN)   /* { */
219#define LUAI_EXTRAIEEE   \
220  static const union luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)};
221#define LUA_IEEEENDIANLOC   (ieeeendian.l_p[1] == 33)
222#else
223#define LUA_IEEEENDIANLOC   LUA_IEEEENDIAN
224#define LUAI_EXTRAIEEE      /* empty */
225#endif            /* } */
226
227#define lua_number2int32(i,n,t) \
228  { LUAI_EXTRAIEEE \
229    volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \
230    (i) = (t)u.l_p[LUA_IEEEENDIANLOC]; }
231
232#define luai_hashnum(i,n)  \
233  { volatile union luai_Cast u; u.l_d = (n) + 1.0;  /* avoid -0 */ \
234    (i) = u.l_p[0]; (i) += u.l_p[1]; }  /* add double bits for his hash */
235
236#define lua_number2int(i,n)      lua_number2int32(i, n, int)
237#define lua_number2unsigned(i,n)   lua_number2int32(i, n, lua_Unsigned)
238
239/* the trick can be expanded to lua_Integer when it is a 32-bit value */
240#if defined(LUA_IEEELL)
241#define lua_number2integer(i,n)      lua_number2int32(i, n, lua_Integer)
242#endif
243
244#endif            /* } */
245
246
247/* the following definitions always work, but may be slow */
248
249#if !defined(lua_number2int)
250#define lua_number2int(i,n)   ((i)=(int)(n))
251#endif
252
253#if !defined(lua_number2integer)
254#define lua_number2integer(i,n)   ((i)=(lua_Integer)(n))
255#endif
256
257#if !defined(lua_number2unsigned)   /* { */
258/* the following definition assures proper modulo behavior */
259#if defined(LUA_NUMBER_DOUBLE) || defined(LUA_NUMBER_FLOAT)
260#include <math.h>
261#define SUPUNSIGNED   ((lua_Number)(~(lua_Unsigned)0) + 1)
262#define lua_number2unsigned(i,n)  \
263   ((i)=(lua_Unsigned)((n) - floor((n)/SUPUNSIGNED)*SUPUNSIGNED))
264#else
265#define lua_number2unsigned(i,n)   ((i)=(lua_Unsigned)(n))
266#endif
267#endif            /* } */
268
269
270#if !defined(lua_unsigned2number)
271/* on several machines, coercion from unsigned to double is slow,
272   so it may be worth to avoid */
273#define lua_unsigned2number(u)  \
274    (((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u))
275#endif
276
277
278
279#if defined(ltable_c) && !defined(luai_hashnum)
280
281#include <float.h>
282#include <math.h>
283
284#define luai_hashnum(i,n) { int e;  \
285  n = l_mathop(frexp)(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP);  \
286  lua_number2int(i, n); i += e; }
287
288#endif
289
290
291
292/*
293** macro to control inclusion of some hard tests on stack reallocation
294*/
295#if !defined(HARDSTACKTESTS)
296#define condmovestack(L)   ((void)0)
297#else
298/* realloc stack keeping its size */
299#define condmovestack(L)   luaD_reallocstack((L), (L)->stacksize)
300#endif
301
302#if !defined(HARDMEMTESTS)
303#define condchangemem(L)   condmovestack(L)
304#else
305#define condchangemem(L)  \
306   ((void)(!(G(L)->gcrunning) || (luaC_fullgc(L, 0), 1)))
307#endif
308
309#endif
Property changes on: trunk/src/lib/lua/llimits.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lstring.c
r0r22721
1/*
2** $Id: lstring.c,v 2.26 2013/01/08 13:50:10 roberto Exp $
3** String table (keeps all strings handled by Lua)
4** See Copyright Notice in lua.h
5*/
6
7
8#include <string.h>
9
10#define lstring_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "lmem.h"
16#include "lobject.h"
17#include "lstate.h"
18#include "lstring.h"
19
20
21/*
22** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to
23** compute its hash
24*/
25#if !defined(LUAI_HASHLIMIT)
26#define LUAI_HASHLIMIT      5
27#endif
28
29
30/*
31** equality for long strings
32*/
33int luaS_eqlngstr (TString *a, TString *b) {
34  size_t len = a->tsv.len;
35  lua_assert(a->tsv.tt == LUA_TLNGSTR && b->tsv.tt == LUA_TLNGSTR);
36  return (a == b) ||  /* same instance or... */
37    ((len == b->tsv.len) &&  /* equal length and ... */
38     (memcmp(getstr(a), getstr(b), len) == 0));  /* equal contents */
39}
40
41
42/*
43** equality for strings
44*/
45int luaS_eqstr (TString *a, TString *b) {
46  return (a->tsv.tt == b->tsv.tt) &&
47         (a->tsv.tt == LUA_TSHRSTR ? eqshrstr(a, b) : luaS_eqlngstr(a, b));
48}
49
50
51unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) {
52  unsigned int h = seed ^ cast(unsigned int, l);
53  size_t l1;
54  size_t step = (l >> LUAI_HASHLIMIT) + 1;
55  for (l1 = l; l1 >= step; l1 -= step)
56    h = h ^ ((h<<5) + (h>>2) + cast_byte(str[l1 - 1]));
57  return h;
58}
59
60
61/*
62** resizes the string table
63*/
64void luaS_resize (lua_State *L, int newsize) {
65  int i;
66  stringtable *tb = &G(L)->strt;
67  /* cannot resize while GC is traversing strings */
68  luaC_runtilstate(L, ~bitmask(GCSsweepstring));
69  if (newsize > tb->size) {
70    luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);
71    for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL;
72  }
73  /* rehash */
74  for (i=0; i<tb->size; i++) {
75    GCObject *p = tb->hash[i];
76    tb->hash[i] = NULL;
77    while (p) {  /* for each node in the list */
78      GCObject *next = gch(p)->next;  /* save next */
79      unsigned int h = lmod(gco2ts(p)->hash, newsize);  /* new position */
80      gch(p)->next = tb->hash[h];  /* chain it */
81      tb->hash[h] = p;
82      resetoldbit(p);  /* see MOVE OLD rule */
83      p = next;
84    }
85  }
86  if (newsize < tb->size) {
87    /* shrinking slice must be empty */
88    lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL);
89    luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);
90  }
91  tb->size = newsize;
92}
93
94
95/*
96** creates a new string object
97*/
98static TString *createstrobj (lua_State *L, const char *str, size_t l,
99                              int tag, unsigned int h, GCObject **list) {
100  TString *ts;
101  size_t totalsize;  /* total size of TString object */
102  totalsize = sizeof(TString) + ((l + 1) * sizeof(char));
103  ts = &luaC_newobj(L, tag, totalsize, list, 0)->ts;
104  ts->tsv.len = l;
105  ts->tsv.hash = h;
106  ts->tsv.extra = 0;
107  memcpy(ts+1, str, l*sizeof(char));
108  ((char *)(ts+1))[l] = '\0';  /* ending 0 */
109  return ts;
110}
111
112
113/*
114** creates a new short string, inserting it into string table
115*/
116static TString *newshrstr (lua_State *L, const char *str, size_t l,
117                                       unsigned int h) {
118  GCObject **list;  /* (pointer to) list where it will be inserted */
119  stringtable *tb = &G(L)->strt;
120  TString *s;
121  if (tb->nuse >= cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
122    luaS_resize(L, tb->size*2);  /* too crowded */
123  list = &tb->hash[lmod(h, tb->size)];
124  s = createstrobj(L, str, l, LUA_TSHRSTR, h, list);
125  tb->nuse++;
126  return s;
127}
128
129
130/*
131** checks whether short string exists and reuses it or creates a new one
132*/
133static TString *internshrstr (lua_State *L, const char *str, size_t l) {
134  GCObject *o;
135  global_State *g = G(L);
136  unsigned int h = luaS_hash(str, l, g->seed);
137  for (o = g->strt.hash[lmod(h, g->strt.size)];
138       o != NULL;
139       o = gch(o)->next) {
140    TString *ts = rawgco2ts(o);
141    if (h == ts->tsv.hash &&
142        l == ts->tsv.len &&
143        (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
144      if (isdead(G(L), o))  /* string is dead (but was not collected yet)? */
145        changewhite(o);  /* resurrect it */
146      return ts;
147    }
148  }
149  return newshrstr(L, str, l, h);  /* not found; create a new string */
150}
151
152
153/*
154** new string (with explicit length)
155*/
156TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
157  if (l <= LUAI_MAXSHORTLEN)  /* short string? */
158    return internshrstr(L, str, l);
159  else {
160    if (l + 1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
161      luaM_toobig(L);
162    return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed, NULL);
163  }
164}
165
166
167/*
168** new zero-terminated string
169*/
170TString *luaS_new (lua_State *L, const char *str) {
171  return luaS_newlstr(L, str, strlen(str));
172}
173
174
175Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
176  Udata *u;
177  if (s > MAX_SIZET - sizeof(Udata))
178    luaM_toobig(L);
179  u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s, NULL, 0)->u;
180  u->uv.len = s;
181  u->uv.metatable = NULL;
182  u->uv.env = e;
183  return u;
184}
185
Property changes on: trunk/src/lib/lua/lstring.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lobject.c
r0r22721
1/*
2** $Id: lobject.c,v 2.58 2013/02/20 14:08:56 roberto Exp $
3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h
5*/
6
7#include <stdarg.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#define lobject_c
13#define LUA_CORE
14
15#include "lua.h"
16
17#include "lctype.h"
18#include "ldebug.h"
19#include "ldo.h"
20#include "lmem.h"
21#include "lobject.h"
22#include "lstate.h"
23#include "lstring.h"
24#include "lvm.h"
25
26
27
28LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT};
29
30
31/*
32** converts an integer to a "floating point byte", represented as
33** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
34** eeeee != 0 and (xxx) otherwise.
35*/
36int luaO_int2fb (unsigned int x) {
37  int e = 0;  /* exponent */
38  if (x < 8) return x;
39  while (x >= 0x10) {
40    x = (x+1) >> 1;
41    e++;
42  }
43  return ((e+1) << 3) | (cast_int(x) - 8);
44}
45
46
47/* converts back */
48int luaO_fb2int (int x) {
49  int e = (x >> 3) & 0x1f;
50  if (e == 0) return x;
51  else return ((x & 7) + 8) << (e - 1);
52}
53
54
55int luaO_ceillog2 (unsigned int x) {
56  static const lu_byte log_2[256] = {
57    0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
58    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
59    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
60    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
61    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
62    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
63    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
64    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
65  };
66  int l = 0;
67  x--;
68  while (x >= 256) { l += 8; x >>= 8; }
69  return l + log_2[x];
70}
71
72
73lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) {
74  switch (op) {
75    case LUA_OPADD: return luai_numadd(NULL, v1, v2);
76    case LUA_OPSUB: return luai_numsub(NULL, v1, v2);
77    case LUA_OPMUL: return luai_nummul(NULL, v1, v2);
78    case LUA_OPDIV: return luai_numdiv(NULL, v1, v2);
79    case LUA_OPMOD: return luai_nummod(NULL, v1, v2);
80    case LUA_OPPOW: return luai_numpow(NULL, v1, v2);
81    case LUA_OPUNM: return luai_numunm(NULL, v1);
82    default: lua_assert(0); return 0;
83  }
84}
85
86
87int luaO_hexavalue (int c) {
88  if (lisdigit(c)) return c - '0';
89  else return ltolower(c) - 'a' + 10;
90}
91
92
93#if !defined(lua_strx2number)
94
95#include <math.h>
96
97
98static int isneg (const char **s) {
99  if (**s == '-') { (*s)++; return 1; }
100  else if (**s == '+') (*s)++;
101  return 0;
102}
103
104
105static lua_Number readhexa (const char **s, lua_Number r, int *count) {
106  for (; lisxdigit(cast_uchar(**s)); (*s)++) {  /* read integer part */
107    r = (r * cast_num(16.0)) + cast_num(1.0*luaO_hexavalue(cast_uchar(**s)));
108    (*count)++;
109  }
110  return r;
111}
112
113
114/*
115** convert an hexadecimal numeric string to a number, following
116** C99 specification for 'strtod'
117*/
118static lua_Number lua_strx2number (const char *s, char **endptr) {
119  lua_Number r = 0.0;
120  int e = 0, i = 0;
121  int neg = 0;  /* 1 if number is negative */
122  *endptr = cast(char *, s);  /* nothing is valid yet */
123  while (lisspace(cast_uchar(*s))) s++;  /* skip initial spaces */
124  neg = isneg(&s);  /* check signal */
125  if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X')))  /* check '0x' */
126    return 0.0;  /* invalid format (no '0x') */
127  s += 2;  /* skip '0x' */
128  r = readhexa(&s, r, &i);  /* read integer part */
129  if (*s == '.') {
130    s++;  /* skip dot */
131    r = readhexa(&s, r, &e);  /* read fractional part */
132  }
133  if (i == 0 && e == 0)
134    return 0.0;  /* invalid format (no digit) */
135  e *= -4;  /* each fractional digit divides value by 2^-4 */
136  *endptr = cast(char *, s);  /* valid up to here */
137  if (*s == 'p' || *s == 'P') {  /* exponent part? */
138    int exp1 = 0;
139    int neg1;
140    s++;  /* skip 'p' */
141    neg1 = isneg(&s);  /* signal */
142    if (!lisdigit(cast_uchar(*s)))
143      goto ret;  /* must have at least one digit */
144    while (lisdigit(cast_uchar(*s)))  /* read exponent */
145      exp1 = exp1 * 10 + *(s++) - '0';
146    if (neg1) exp1 = -exp1;
147    e += exp1;
148  }
149  *endptr = cast(char *, s);  /* valid up to here */
150 ret:
151  if (neg) r = -r;
152  return l_mathop(ldexp)(r, e);
153}
154
155#endif
156
157
158int luaO_str2d (const char *s, size_t len, lua_Number *result) {
159  char *endptr;
160  if (strpbrk(s, "nN"))  /* reject 'inf' and 'nan' */
161    return 0;
162  else if (strpbrk(s, "xX"))  /* hexa? */
163    *result = lua_strx2number(s, &endptr);
164  else
165    *result = lua_str2number(s, &endptr);
166  if (endptr == s) return 0;  /* nothing recognized */
167  while (lisspace(cast_uchar(*endptr))) endptr++;
168  return (endptr == s + len);  /* OK if no trailing characters */
169}
170
171
172
173static void pushstr (lua_State *L, const char *str, size_t l) {
174  setsvalue2s(L, L->top++, luaS_newlstr(L, str, l));
175}
176
177
178/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
179const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
180  int n = 0;
181  for (;;) {
182    const char *e = strchr(fmt, '%');
183    if (e == NULL) break;
184    luaD_checkstack(L, 2);  /* fmt + item */
185    pushstr(L, fmt, e - fmt);
186    switch (*(e+1)) {
187      case 's': {
188        const char *s = va_arg(argp, char *);
189        if (s == NULL) s = "(null)";
190        pushstr(L, s, strlen(s));
191        break;
192      }
193      case 'c': {
194        char buff;
195        buff = cast(char, va_arg(argp, int));
196        pushstr(L, &buff, 1);
197        break;
198      }
199      case 'd': {
200        setnvalue(L->top++, cast_num(va_arg(argp, int)));
201        break;
202      }
203      case 'f': {
204        setnvalue(L->top++, cast_num(va_arg(argp, l_uacNumber)));
205        break;
206      }
207      case 'p': {
208        char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
209        int l = sprintf(buff, "%p", va_arg(argp, void *));
210        pushstr(L, buff, l);
211        break;
212      }
213      case '%': {
214        pushstr(L, "%", 1);
215        break;
216      }
217      default: {
218        luaG_runerror(L,
219            "invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"),
220            *(e + 1));
221      }
222    }
223    n += 2;
224    fmt = e+2;
225  }
226  luaD_checkstack(L, 1);
227  pushstr(L, fmt, strlen(fmt));
228  if (n > 0) luaV_concat(L, n + 1);
229  return svalue(L->top - 1);
230}
231
232
233const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
234  const char *msg;
235  va_list argp;
236  va_start(argp, fmt);
237  msg = luaO_pushvfstring(L, fmt, argp);
238  va_end(argp);
239  return msg;
240}
241
242
243/* number of chars of a literal string without the ending \0 */
244#define LL(x)   (sizeof(x)/sizeof(char) - 1)
245
246#define RETS   "..."
247#define PRE   "[string \""
248#define POS   "\"]"
249
250#define addstr(a,b,l)   ( memcpy(a,b,(l) * sizeof(char)), a += (l) )
251
252void luaO_chunkid (char *out, const char *source, size_t bufflen) {
253  size_t l = strlen(source);
254  if (*source == '=') {  /* 'literal' source */
255    if (l <= bufflen)  /* small enough? */
256      memcpy(out, source + 1, l * sizeof(char));
257    else {  /* truncate it */
258      addstr(out, source + 1, bufflen - 1);
259      *out = '\0';
260    }
261  }
262  else if (*source == '@') {  /* file name */
263    if (l <= bufflen)  /* small enough? */
264      memcpy(out, source + 1, l * sizeof(char));
265    else {  /* add '...' before rest of name */
266      addstr(out, RETS, LL(RETS));
267      bufflen -= LL(RETS);
268      memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char));
269    }
270  }
271  else {  /* string; format as [string "source"] */
272    const char *nl = strchr(source, '\n');  /* find first new line (if any) */
273    addstr(out, PRE, LL(PRE));  /* add prefix */
274    bufflen -= LL(PRE RETS POS) + 1;  /* save space for prefix+suffix+'\0' */
275    if (l < bufflen && nl == NULL) {  /* small one-line source? */
276      addstr(out, source, l);  /* keep it */
277    }
278    else {
279      if (nl != NULL) l = nl - source;  /* stop at first newline */
280      if (l > bufflen) l = bufflen;
281      addstr(out, source, l);
282      addstr(out, RETS, LL(RETS));
283    }
284    memcpy(out, POS, (LL(POS) + 1) * sizeof(char));
285  }
286}
287
Property changes on: trunk/src/lib/lua/lobject.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/loslib.c
r0r22721
1/*
2** $Id: loslib.c,v 1.40 2012/10/19 15:54:02 roberto Exp $
3** Standard Operating System library
4** See Copyright Notice in lua.h
5*/
6
7
8#include <errno.h>
9#include <locale.h>
10#include <stdlib.h>
11#include <string.h>
12#include <time.h>
13
14#define loslib_c
15#define LUA_LIB
16
17#include "lua.h"
18
19#include "lauxlib.h"
20#include "lualib.h"
21
22
23/*
24** list of valid conversion specifiers for the 'strftime' function
25*/
26#if !defined(LUA_STRFTIMEOPTIONS)
27
28#if !defined(LUA_USE_POSIX)
29#define LUA_STRFTIMEOPTIONS   { "aAbBcdHIjmMpSUwWxXyYz%", "" }
30#else
31#define LUA_STRFTIMEOPTIONS \
32   { "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "" \
33     "", "E", "cCxXyY",  \
34     "O", "deHImMSuUVwWy" }
35#endif
36
37#endif
38
39
40
41/*
42** By default, Lua uses tmpnam except when POSIX is available, where it
43** uses mkstemp.
44*/
45#if defined(LUA_USE_MKSTEMP)
46#include <unistd.h>
47#define LUA_TMPNAMBUFSIZE   32
48#define lua_tmpnam(b,e) { \
49        strcpy(b, "/tmp/lua_XXXXXX"); \
50        e = mkstemp(b); \
51        if (e != -1) close(e); \
52        e = (e == -1); }
53
54#elif !defined(lua_tmpnam)
55
56#define LUA_TMPNAMBUFSIZE   L_tmpnam
57#define lua_tmpnam(b,e)      { e = (tmpnam(b) == NULL); }
58
59#endif
60
61
62/*
63** By default, Lua uses gmtime/localtime, except when POSIX is available,
64** where it uses gmtime_r/localtime_r
65*/
66#if defined(LUA_USE_GMTIME_R)
67
68#define l_gmtime(t,r)      gmtime_r(t,r)
69#define l_localtime(t,r)   localtime_r(t,r)
70
71#elif !defined(l_gmtime)
72
73#define l_gmtime(t,r)      ((void)r, gmtime(t))
74#define l_localtime(t,r)     ((void)r, localtime(t))
75
76#endif
77
78
79
80static int os_execute (lua_State *L) {
81  const char *cmd = luaL_optstring(L, 1, NULL);
82  int stat = system(cmd);
83  if (cmd != NULL)
84    return luaL_execresult(L, stat);
85  else {
86    lua_pushboolean(L, stat);  /* true if there is a shell */
87    return 1;
88  }
89}
90
91
92static int os_remove (lua_State *L) {
93  const char *filename = luaL_checkstring(L, 1);
94  return luaL_fileresult(L, remove(filename) == 0, filename);
95}
96
97
98static int os_rename (lua_State *L) {
99  const char *fromname = luaL_checkstring(L, 1);
100  const char *toname = luaL_checkstring(L, 2);
101  return luaL_fileresult(L, rename(fromname, toname) == 0, NULL);
102}
103
104
105static int os_tmpname (lua_State *L) {
106  char buff[LUA_TMPNAMBUFSIZE];
107  int err;
108  lua_tmpnam(buff, err);
109  if (err)
110    return luaL_error(L, "unable to generate a unique filename");
111  lua_pushstring(L, buff);
112  return 1;
113}
114
115
116static int os_getenv (lua_State *L) {
117  lua_pushstring(L, getenv(luaL_checkstring(L, 1)));  /* if NULL push nil */
118  return 1;
119}
120
121
122static int os_clock (lua_State *L) {
123  lua_pushnumber(L, ((lua_Number)(1.0*clock()))/(lua_Number)CLOCKS_PER_SEC);
124  return 1;
125}
126
127
128/*
129** {======================================================
130** Time/Date operations
131** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
132**   wday=%w+1, yday=%j, isdst=? }
133** =======================================================
134*/
135
136static void setfield (lua_State *L, const char *key, int value) {
137  lua_pushinteger(L, value);
138  lua_setfield(L, -2, key);
139}
140
141static void setboolfield (lua_State *L, const char *key, int value) {
142  if (value < 0)  /* undefined? */
143    return;  /* does not set field */
144  lua_pushboolean(L, value);
145  lua_setfield(L, -2, key);
146}
147
148static int getboolfield (lua_State *L, const char *key) {
149  int res;
150  lua_getfield(L, -1, key);
151  res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
152  lua_pop(L, 1);
153  return res;
154}
155
156
157static int getfield (lua_State *L, const char *key, int d) {
158  int res, isnum;
159  lua_getfield(L, -1, key);
160  res = (int)lua_tointegerx(L, -1, &isnum);
161  if (!isnum) {
162    if (d < 0)
163      return luaL_error(L, "field " LUA_QS " missing in date table", key);
164    res = d;
165  }
166  lua_pop(L, 1);
167  return res;
168}
169
170
171static const char *checkoption (lua_State *L, const char *conv, char *buff) {
172  static const char *const options[] = LUA_STRFTIMEOPTIONS;
173  unsigned int i;
174  for (i = 0; i < sizeof(options)/sizeof(options[0]); i += 2) {
175    if (*conv != '\0' && strchr(options[i], *conv) != NULL) {
176      buff[1] = *conv;
177      if (*options[i + 1] == '\0') {  /* one-char conversion specifier? */
178        buff[2] = '\0';  /* end buffer */
179        return conv + 1;
180      }
181      else if (*(conv + 1) != '\0' &&
182               strchr(options[i + 1], *(conv + 1)) != NULL) {
183        buff[2] = *(conv + 1);  /* valid two-char conversion specifier */
184        buff[3] = '\0';  /* end buffer */
185        return conv + 2;
186      }
187    }
188  }
189  luaL_argerror(L, 1,
190    lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv));
191  return conv;  /* to avoid warnings */
192}
193
194
195static int os_date (lua_State *L) {
196  const char *s = luaL_optstring(L, 1, "%c");
197  time_t t = luaL_opt(L, luaL_checknumber, 2, time(NULL));
198  struct tm tmr, *stm;
199  if (*s == '!') {  /* UTC? */
200    stm = l_gmtime(&t, &tmr);
201    s++;  /* skip `!' */
202  }
203  else
204    stm = l_localtime(&t, &tmr);
205  if (stm == NULL)  /* invalid date? */
206    lua_pushnil(L);
207  else if (strcmp(s, "*t") == 0) {
208    lua_createtable(L, 0, 9);  /* 9 = number of fields */
209    setfield(L, "sec", stm->tm_sec);
210    setfield(L, "min", stm->tm_min);
211    setfield(L, "hour", stm->tm_hour);
212    setfield(L, "day", stm->tm_mday);
213    setfield(L, "month", stm->tm_mon+1);
214    setfield(L, "year", stm->tm_year+1900);
215    setfield(L, "wday", stm->tm_wday+1);
216    setfield(L, "yday", stm->tm_yday+1);
217    setboolfield(L, "isdst", stm->tm_isdst);
218  }
219  else {
220    char cc[4];
221    luaL_Buffer b;
222    cc[0] = '%';
223    luaL_buffinit(L, &b);
224    while (*s) {
225      if (*s != '%')  /* no conversion specifier? */
226        luaL_addchar(&b, *s++);
227      else {
228        size_t reslen;
229        char buff[200];  /* should be big enough for any conversion result */
230        s = checkoption(L, s + 1, cc);
231        reslen = strftime(buff, sizeof(buff), cc, stm);
232        luaL_addlstring(&b, buff, reslen);
233      }
234    }
235    luaL_pushresult(&b);
236  }
237  return 1;
238}
239
240
241static int os_time (lua_State *L) {
242  time_t t;
243  if (lua_isnoneornil(L, 1))  /* called without args? */
244    t = time(NULL);  /* get current time */
245  else {
246    struct tm ts;
247    luaL_checktype(L, 1, LUA_TTABLE);
248    lua_settop(L, 1);  /* make sure table is at the top */
249    ts.tm_sec = getfield(L, "sec", 0);
250    ts.tm_min = getfield(L, "min", 0);
251    ts.tm_hour = getfield(L, "hour", 12);
252    ts.tm_mday = getfield(L, "day", -1);
253    ts.tm_mon = getfield(L, "month", -1) - 1;
254    ts.tm_year = getfield(L, "year", -1) - 1900;
255    ts.tm_isdst = getboolfield(L, "isdst");
256    t = mktime(&ts);
257  }
258  if (t == (time_t)(-1))
259    lua_pushnil(L);
260  else
261    lua_pushnumber(L, (lua_Number)t);
262  return 1;
263}
264
265
266static int os_difftime (lua_State *L) {
267  lua_pushnumber(L, difftime((luaL_checknumber(L, 1)),
268                             (luaL_optnumber(L, 2, 0))));
269  return 1;
270}
271
272/* }====================================================== */
273
274
275static int os_setlocale (lua_State *L) {
276  static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
277                      LC_NUMERIC, LC_TIME};
278  static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
279     "numeric", "time", NULL};
280  const char *l = luaL_optstring(L, 1, NULL);
281  int op = luaL_checkoption(L, 2, "all", catnames);
282  lua_pushstring(L, setlocale(cat[op], l));
283  return 1;
284}
285
286
287static int os_exit (lua_State *L) {
288  int status;
289  if (lua_isboolean(L, 1))
290    status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE);
291  else
292    status = luaL_optint(L, 1, EXIT_SUCCESS);
293  if (lua_toboolean(L, 2))
294    lua_close(L);
295  if (L) exit(status);  /* 'if' to avoid warnings for unreachable 'return' */
296  return 0;
297}
298
299
300static const luaL_Reg syslib[] = {
301  {"clock",     os_clock},
302  {"date",      os_date},
303  {"difftime",  os_difftime},
304  {"execute",   os_execute},
305  {"exit",      os_exit},
306  {"getenv",    os_getenv},
307  {"remove",    os_remove},
308  {"rename",    os_rename},
309  {"setlocale", os_setlocale},
310  {"time",      os_time},
311  {"tmpname",   os_tmpname},
312  {NULL, NULL}
313};
314
315/* }====================================================== */
316
317
318
319LUAMOD_API int luaopen_os (lua_State *L) {
320  luaL_newlib(L, syslib);
321  return 1;
322}
323
Property changes on: trunk/src/lib/lua/loslib.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/luac.c
r0r22721
1/*
2** $Id: luac.c,v 1.69 2011/11/29 17:46:33 lhf Exp $
3** Lua compiler (saves bytecodes to files; also list bytecodes)
4** See Copyright Notice in lua.h
5*/
6
7#include <errno.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#define luac_c
13#define LUA_CORE
14
15#include "lua.h"
16#include "lauxlib.h"
17
18#include "lobject.h"
19#include "lstate.h"
20#include "lundump.h"
21
22static void PrintFunction(const Proto* f, int full);
23#define luaU_print   PrintFunction
24
25#define PROGNAME   "luac"      /* default program name */
26#define OUTPUT      PROGNAME ".out"   /* default output file */
27
28static int listing=0;         /* list bytecodes? */
29static int dumping=1;         /* dump bytecodes? */
30static int stripping=0;         /* strip debug information? */
31static char Output[]={ OUTPUT };   /* default output file name */
32static const char* output=Output;   /* actual output file name */
33static const char* progname=PROGNAME;   /* actual program name */
34
35static void fatal(const char* message)
36{
37 fprintf(stderr,"%s: %s\n",progname,message);
38 exit(EXIT_FAILURE);
39}
40
41static void cannot(const char* what)
42{
43 fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno));
44 exit(EXIT_FAILURE);
45}
46
47static void usage(const char* message)
48{
49 if (*message=='-')
50  fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message);
51 else
52  fprintf(stderr,"%s: %s\n",progname,message);
53 fprintf(stderr,
54  "usage: %s [options] [filenames]\n"
55  "Available options are:\n"
56  "  -l       list (use -l -l for full listing)\n"
57  "  -o name  output to file " LUA_QL("name") " (default is \"%s\")\n"
58  "  -p       parse only\n"
59  "  -s       strip debug information\n"
60  "  -v       show version information\n"
61  "  --       stop handling options\n"
62  "  -        stop handling options and process stdin\n"
63  ,progname,Output);
64 exit(EXIT_FAILURE);
65}
66
67#define IS(s)   (strcmp(argv[i],s)==0)
68
69static int doargs(int argc, char* argv[])
70{
71 int i;
72 int version=0;
73 if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0];
74 for (i=1; i<argc; i++)
75 {
76  if (*argv[i]!='-')         /* end of options; keep it */
77   break;
78  else if (IS("--"))         /* end of options; skip it */
79  {
80   ++i;
81   if (version) ++version;
82   break;
83  }
84  else if (IS("-"))         /* end of options; use stdin */
85   break;
86  else if (IS("-l"))         /* list */
87   ++listing;
88  else if (IS("-o"))         /* output file */
89  {
90   output=argv[++i];
91   if (output==NULL || *output==0 || (*output=='-' && output[1]!=0))
92    usage(LUA_QL("-o") " needs argument");
93   if (IS("-")) output=NULL;
94  }
95  else if (IS("-p"))         /* parse only */
96   dumping=0;
97  else if (IS("-s"))         /* strip debug information */
98   stripping=1;
99  else if (IS("-v"))         /* show version */
100   ++version;
101  else               /* unknown option */
102   usage(argv[i]);
103 }
104 if (i==argc && (listing || !dumping))
105 {
106  dumping=0;
107  argv[--i]=Output;
108 }
109 if (version)
110 {
111  printf("%s\n",LUA_COPYRIGHT);
112  if (version==argc-1) exit(EXIT_SUCCESS);
113 }
114 return i;
115}
116
117#define FUNCTION "(function()end)();"
118
119static const char* reader(lua_State *L, void *ud, size_t *size)
120{
121 UNUSED(L);
122 if ((*(int*)ud)--)
123 {
124  *size=sizeof(FUNCTION)-1;
125  return FUNCTION;
126 }
127 else
128 {
129  *size=0;
130  return NULL;
131 }
132}
133
134#define toproto(L,i) getproto(L->top+(i))
135
136static const Proto* combine(lua_State* L, int n)
137{
138 if (n==1)
139  return toproto(L,-1);
140 else
141 {
142  Proto* f;
143  int i=n;
144  if (lua_load(L,reader,&i,"=(" PROGNAME ")",NULL)!=LUA_OK) fatal(lua_tostring(L,-1));
145  f=toproto(L,-1);
146  for (i=0; i<n; i++)
147  {
148   f->p[i]=toproto(L,i-n-1);
149   if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0;
150  }
151  f->sizelineinfo=0;
152  return f;
153 }
154}
155
156static int writer(lua_State* L, const void* p, size_t size, void* u)
157{
158 UNUSED(L);
159 return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0);
160}
161
162static int pmain(lua_State* L)
163{
164 int argc=(int)lua_tointeger(L,1);
165 char** argv=(char**)lua_touserdata(L,2);
166 const Proto* f;
167 int i;
168 if (!lua_checkstack(L,argc)) fatal("too many input files");
169 for (i=0; i<argc; i++)
170 {
171  const char* filename=IS("-") ? NULL : argv[i];
172  if (luaL_loadfile(L,filename)!=LUA_OK) fatal(lua_tostring(L,-1));
173 }
174 f=combine(L,argc);
175 if (listing) luaU_print(f,listing>1);
176 if (dumping)
177 {
178  FILE* D= (output==NULL) ? stdout : fopen(output,"wb");
179  if (D==NULL) cannot("open");
180  lua_lock(L);
181  luaU_dump(L,f,writer,D,stripping);
182  lua_unlock(L);
183  if (ferror(D)) cannot("write");
184  if (fclose(D)) cannot("close");
185 }
186 return 0;
187}
188
189int main(int argc, char* argv[])
190{
191 lua_State* L;
192 int i=doargs(argc,argv);
193 argc-=i; argv+=i;
194 if (argc<=0) usage("no input files given");
195 L=luaL_newstate();
196 if (L==NULL) fatal("cannot create state: not enough memory");
197 lua_pushcfunction(L,&pmain);
198 lua_pushinteger(L,argc);
199 lua_pushlightuserdata(L,argv);
200 if (lua_pcall(L,2,0,0)!=LUA_OK) fatal(lua_tostring(L,-1));
201 lua_close(L);
202 return EXIT_SUCCESS;
203}
204
205/*
206** $Id: print.c,v 1.68 2011/09/30 10:21:20 lhf Exp $
207** print bytecodes
208** See Copyright Notice in lua.h
209*/
210
211#include <ctype.h>
212#include <stdio.h>
213
214#define luac_c
215#define LUA_CORE
216
217#include "ldebug.h"
218#include "lobject.h"
219#include "lopcodes.h"
220
221#define VOID(p)      ((const void*)(p))
222
223static void PrintString(const TString* ts)
224{
225 const char* s=getstr(ts);
226 size_t i,n=ts->tsv.len;
227 printf("%c",'"');
228 for (i=0; i<n; i++)
229 {
230  int c=(int)(unsigned char)s[i];
231  switch (c)
232  {
233   case '"':  printf("\\\""); break;
234   case '\\': printf("\\\\"); break;
235   case '\a': printf("\\a"); break;
236   case '\b': printf("\\b"); break;
237   case '\f': printf("\\f"); break;
238   case '\n': printf("\\n"); break;
239   case '\r': printf("\\r"); break;
240   case '\t': printf("\\t"); break;
241   case '\v': printf("\\v"); break;
242   default:   if (isprint(c))
243            printf("%c",c);
244      else
245         printf("\\%03d",c);
246  }
247 }
248 printf("%c",'"');
249}
250
251static void PrintConstant(const Proto* f, int i)
252{
253 const TValue* o=&f->k[i];
254 switch (ttype(o))
255 {
256  case LUA_TNIL:
257   printf("nil");
258   break;
259  case LUA_TBOOLEAN:
260   printf(bvalue(o) ? "true" : "false");
261   break;
262  case LUA_TNUMBER:
263   printf(LUA_NUMBER_FMT,nvalue(o));
264   break;
265  case LUA_TSTRING:
266   PrintString(rawtsvalue(o));
267   break;
268  default:            /* cannot happen */
269   printf("? type=%d",ttype(o));
270   break;
271 }
272}
273
274#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-")
275#define MYK(x)      (-1-(x))
276
277static void PrintCode(const Proto* f)
278{
279 const Instruction* code=f->code;
280 int pc,n=f->sizecode;
281 for (pc=0; pc<n; pc++)
282 {
283  Instruction i=code[pc];
284  OpCode o=GET_OPCODE(i);
285  int a=GETARG_A(i);
286  int b=GETARG_B(i);
287  int c=GETARG_C(i);
288  int ax=GETARG_Ax(i);
289  int bx=GETARG_Bx(i);
290  int sbx=GETARG_sBx(i);
291  int line=getfuncline(f,pc);
292  printf("\t%d\t",pc+1);
293  if (line>0) printf("[%d]\t",line); else printf("[-]\t");
294  printf("%-9s\t",luaP_opnames[o]);
295  switch (getOpMode(o))
296  {
297   case iABC:
298    printf("%d",a);
299    if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (MYK(INDEXK(b))) : b);
300    if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (MYK(INDEXK(c))) : c);
301    break;
302   case iABx:
303    printf("%d",a);
304    if (getBMode(o)==OpArgK) printf(" %d",MYK(bx));
305    if (getBMode(o)==OpArgU) printf(" %d",bx);
306    break;
307   case iAsBx:
308    printf("%d %d",a,sbx);
309    break;
310   case iAx:
311    printf("%d",MYK(ax));
312    break;
313  }
314  switch (o)
315  {
316   case OP_LOADK:
317    printf("\t; "); PrintConstant(f,bx);
318    break;
319   case OP_GETUPVAL:
320   case OP_SETUPVAL:
321    printf("\t; %s",UPVALNAME(b));
322    break;
323   case OP_GETTABUP:
324    printf("\t; %s",UPVALNAME(b));
325    if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
326    break;
327   case OP_SETTABUP:
328    printf("\t; %s",UPVALNAME(a));
329    if (ISK(b)) { printf(" "); PrintConstant(f,INDEXK(b)); }
330    if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
331    break;
332   case OP_GETTABLE:
333   case OP_SELF:
334    if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
335    break;
336   case OP_SETTABLE:
337   case OP_ADD:
338   case OP_SUB:
339   case OP_MUL:
340   case OP_DIV:
341   case OP_POW:
342   case OP_EQ:
343   case OP_LT:
344   case OP_LE:
345    if (ISK(b) || ISK(c))
346    {
347     printf("\t; ");
348     if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
349     printf(" ");
350     if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
351    }
352    break;
353   case OP_JMP:
354   case OP_FORLOOP:
355   case OP_FORPREP:
356   case OP_TFORLOOP:
357    printf("\t; to %d",sbx+pc+2);
358    break;
359   case OP_CLOSURE:
360    printf("\t; %p",VOID(f->p[bx]));
361    break;
362   case OP_SETLIST:
363    if (c==0) printf("\t; %d",(int)code[++pc]); else printf("\t; %d",c);
364    break;
365   case OP_EXTRAARG:
366    printf("\t; "); PrintConstant(f,ax);
367    break;
368   default:
369    break;
370  }
371  printf("\n");
372 }
373}
374
375#define SS(x)   ((x==1)?"":"s")
376#define S(x)   (int)(x),SS(x)
377
378static void PrintHeader(const Proto* f)
379{
380 const char* s=f->source ? getstr(f->source) : "=?";
381 if (*s=='@' || *s=='=')
382  s++;
383 else if (*s==LUA_SIGNATURE[0])
384  s="(bstring)";
385 else
386  s="(string)";
387 printf("\n%s <%s:%d,%d> (%d instruction%s at %p)\n",
388    (f->linedefined==0)?"main":"function",s,
389   f->linedefined,f->lastlinedefined,
390   S(f->sizecode),VOID(f));
391 printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
392   (int)(f->numparams),f->is_vararg?"+":"",SS(f->numparams),
393   S(f->maxstacksize),S(f->sizeupvalues));
394 printf("%d local%s, %d constant%s, %d function%s\n",
395   S(f->sizelocvars),S(f->sizek),S(f->sizep));
396}
397
398static void PrintDebug(const Proto* f)
399{
400 int i,n;
401 n=f->sizek;
402 printf("constants (%d) for %p:\n",n,VOID(f));
403 for (i=0; i<n; i++)
404 {
405  printf("\t%d\t",i+1);
406  PrintConstant(f,i);
407  printf("\n");
408 }
409 n=f->sizelocvars;
410 printf("locals (%d) for %p:\n",n,VOID(f));
411 for (i=0; i<n; i++)
412 {
413  printf("\t%d\t%s\t%d\t%d\n",
414  i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
415 }
416 n=f->sizeupvalues;
417 printf("upvalues (%d) for %p:\n",n,VOID(f));
418 for (i=0; i<n; i++)
419 {
420  printf("\t%d\t%s\t%d\t%d\n",
421  i,UPVALNAME(i),f->upvalues[i].instack,f->upvalues[i].idx);
422 }
423}
424
425static void PrintFunction(const Proto* f, int full)
426{
427 int i,n=f->sizep;
428 PrintHeader(f);
429 PrintCode(f);
430 if (full) PrintDebug(f);
431 for (i=0; i<n; i++) PrintFunction(f->p[i],full);
432}
Property changes on: trunk/src/lib/lua/luac.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lua.h
r0r22721
1/*
2** $Id: lua.h,v 1.285 2013/03/15 13:04:22 roberto Exp $
3** Lua - A Scripting Language
4** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
5** See Copyright Notice at the end of this file
6*/
7
8
9#ifndef lua_h
10#define lua_h
11
12#include <stdarg.h>
13#include <stddef.h>
14
15
16#include "luaconf.h"
17
18
19#define LUA_VERSION_MAJOR   "5"
20#define LUA_VERSION_MINOR   "2"
21#define LUA_VERSION_NUM      502
22#define LUA_VERSION_RELEASE   "2"
23
24#define LUA_VERSION   "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
25#define LUA_RELEASE   LUA_VERSION "." LUA_VERSION_RELEASE
26#define LUA_COPYRIGHT   LUA_RELEASE "  Copyright (C) 1994-2013 Lua.org, PUC-Rio"
27#define LUA_AUTHORS   "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
28
29
30/* mark for precompiled code ('<esc>Lua') */
31#define LUA_SIGNATURE   "\033Lua"
32
33/* option for multiple returns in 'lua_pcall' and 'lua_call' */
34#define LUA_MULTRET   (-1)
35
36
37/*
38** pseudo-indices
39*/
40#define LUA_REGISTRYINDEX   LUAI_FIRSTPSEUDOIDX
41#define lua_upvalueindex(i)   (LUA_REGISTRYINDEX - (i))
42
43
44/* thread status */
45#define LUA_OK      0
46#define LUA_YIELD   1
47#define LUA_ERRRUN   2
48#define LUA_ERRSYNTAX   3
49#define LUA_ERRMEM   4
50#define LUA_ERRGCMM   5
51#define LUA_ERRERR   6
52
53
54typedef struct lua_State lua_State;
55
56typedef int (*lua_CFunction) (lua_State *L);
57
58
59/*
60** functions that read/write blocks when loading/dumping Lua chunks
61*/
62typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
63
64typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
65
66
67/*
68** prototype for memory-allocation functions
69*/
70typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
71
72
73/*
74** basic types
75*/
76#define LUA_TNONE      (-1)
77
78#define LUA_TNIL      0
79#define LUA_TBOOLEAN      1
80#define LUA_TLIGHTUSERDATA   2
81#define LUA_TNUMBER      3
82#define LUA_TSTRING      4
83#define LUA_TTABLE      5
84#define LUA_TFUNCTION      6
85#define LUA_TUSERDATA      7
86#define LUA_TTHREAD      8
87
88#define LUA_NUMTAGS      9
89
90
91
92/* minimum Lua stack available to a C function */
93#define LUA_MINSTACK   20
94
95
96/* predefined values in the registry */
97#define LUA_RIDX_MAINTHREAD   1
98#define LUA_RIDX_GLOBALS   2
99#define LUA_RIDX_LAST      LUA_RIDX_GLOBALS
100
101
102/* type of numbers in Lua */
103typedef LUA_NUMBER lua_Number;
104
105
106/* type for integer functions */
107typedef LUA_INTEGER lua_Integer;
108
109/* unsigned integer type */
110typedef LUA_UNSIGNED lua_Unsigned;
111
112
113
114/*
115** generic extra include file
116*/
117#if defined(LUA_USER_H)
118#include LUA_USER_H
119#endif
120
121
122/*
123** RCS ident string
124*/
125extern const char lua_ident[];
126
127
128/*
129** state manipulation
130*/
131LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
132LUA_API void       (lua_close) (lua_State *L);
133LUA_API lua_State *(lua_newthread) (lua_State *L);
134
135LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
136
137
138LUA_API const lua_Number *(lua_version) (lua_State *L);
139
140
141/*
142** basic stack manipulation
143*/
144LUA_API int   (lua_absindex) (lua_State *L, int idx);
145LUA_API int   (lua_gettop) (lua_State *L);
146LUA_API void  (lua_settop) (lua_State *L, int idx);
147LUA_API void  (lua_pushvalue) (lua_State *L, int idx);
148LUA_API void  (lua_remove) (lua_State *L, int idx);
149LUA_API void  (lua_insert) (lua_State *L, int idx);
150LUA_API void  (lua_replace) (lua_State *L, int idx);
151LUA_API void  (lua_copy) (lua_State *L, int fromidx, int toidx);
152LUA_API int   (lua_checkstack) (lua_State *L, int sz);
153
154LUA_API void  (lua_xmove) (lua_State *from, lua_State *to, int n);
155
156
157/*
158** access functions (stack -> C)
159*/
160
161LUA_API int             (lua_isnumber) (lua_State *L, int idx);
162LUA_API int             (lua_isstring) (lua_State *L, int idx);
163LUA_API int             (lua_iscfunction) (lua_State *L, int idx);
164LUA_API int             (lua_isuserdata) (lua_State *L, int idx);
165LUA_API int             (lua_type) (lua_State *L, int idx);
166LUA_API const char     *(lua_typename) (lua_State *L, int tp);
167
168LUA_API lua_Number      (lua_tonumberx) (lua_State *L, int idx, int *isnum);
169LUA_API lua_Integer     (lua_tointegerx) (lua_State *L, int idx, int *isnum);
170LUA_API lua_Unsigned    (lua_tounsignedx) (lua_State *L, int idx, int *isnum);
171LUA_API int             (lua_toboolean) (lua_State *L, int idx);
172LUA_API const char     *(lua_tolstring) (lua_State *L, int idx, size_t *len);
173LUA_API size_t          (lua_rawlen) (lua_State *L, int idx);
174LUA_API lua_CFunction   (lua_tocfunction) (lua_State *L, int idx);
175LUA_API void          *(lua_touserdata) (lua_State *L, int idx);
176LUA_API lua_State      *(lua_tothread) (lua_State *L, int idx);
177LUA_API const void     *(lua_topointer) (lua_State *L, int idx);
178
179
180/*
181** Comparison and arithmetic functions
182*/
183
184#define LUA_OPADD   0   /* ORDER TM */
185#define LUA_OPSUB   1
186#define LUA_OPMUL   2
187#define LUA_OPDIV   3
188#define LUA_OPMOD   4
189#define LUA_OPPOW   5
190#define LUA_OPUNM   6
191
192LUA_API void  (lua_arith) (lua_State *L, int op);
193
194#define LUA_OPEQ   0
195#define LUA_OPLT   1
196#define LUA_OPLE   2
197
198LUA_API int   (lua_rawequal) (lua_State *L, int idx1, int idx2);
199LUA_API int   (lua_compare) (lua_State *L, int idx1, int idx2, int op);
200
201
202/*
203** push functions (C -> stack)
204*/
205LUA_API void        (lua_pushnil) (lua_State *L);
206LUA_API void        (lua_pushnumber) (lua_State *L, lua_Number n);
207LUA_API void        (lua_pushinteger) (lua_State *L, lua_Integer n);
208LUA_API void        (lua_pushunsigned) (lua_State *L, lua_Unsigned n);
209LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t l);
210LUA_API const char *(lua_pushstring) (lua_State *L, const char *s);
211LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
212                                                      va_list argp);
213LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
214LUA_API void  (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
215LUA_API void  (lua_pushboolean) (lua_State *L, int b);
216LUA_API void  (lua_pushlightuserdata) (lua_State *L, void *p);
217LUA_API int   (lua_pushthread) (lua_State *L);
218
219
220/*
221** get functions (Lua -> stack)
222*/
223LUA_API void  (lua_getglobal) (lua_State *L, const char *var);
224LUA_API void  (lua_gettable) (lua_State *L, int idx);
225LUA_API void  (lua_getfield) (lua_State *L, int idx, const char *k);
226LUA_API void  (lua_rawget) (lua_State *L, int idx);
227LUA_API void  (lua_rawgeti) (lua_State *L, int idx, int n);
228LUA_API void  (lua_rawgetp) (lua_State *L, int idx, const void *p);
229LUA_API void  (lua_createtable) (lua_State *L, int narr, int nrec);
230LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
231LUA_API int   (lua_getmetatable) (lua_State *L, int objindex);
232LUA_API void  (lua_getuservalue) (lua_State *L, int idx);
233
234
235/*
236** set functions (stack -> Lua)
237*/
238LUA_API void  (lua_setglobal) (lua_State *L, const char *var);
239LUA_API void  (lua_settable) (lua_State *L, int idx);
240LUA_API void  (lua_setfield) (lua_State *L, int idx, const char *k);
241LUA_API void  (lua_rawset) (lua_State *L, int idx);
242LUA_API void  (lua_rawseti) (lua_State *L, int idx, int n);
243LUA_API void  (lua_rawsetp) (lua_State *L, int idx, const void *p);
244LUA_API int   (lua_setmetatable) (lua_State *L, int objindex);
245LUA_API void  (lua_setuservalue) (lua_State *L, int idx);
246
247
248/*
249** 'load' and 'call' functions (load and run Lua code)
250*/
251LUA_API void  (lua_callk) (lua_State *L, int nargs, int nresults, int ctx,
252                           lua_CFunction k);
253#define lua_call(L,n,r)      lua_callk(L, (n), (r), 0, NULL)
254
255LUA_API int   (lua_getctx) (lua_State *L, int *ctx);
256
257LUA_API int   (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
258                            int ctx, lua_CFunction k);
259#define lua_pcall(L,n,r,f)   lua_pcallk(L, (n), (r), (f), 0, NULL)
260
261LUA_API int   (lua_load) (lua_State *L, lua_Reader reader, void *dt,
262                                        const char *chunkname,
263                                        const char *mode);
264
265LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
266
267
268/*
269** coroutine functions
270*/
271LUA_API int  (lua_yieldk) (lua_State *L, int nresults, int ctx,
272                           lua_CFunction k);
273#define lua_yield(L,n)      lua_yieldk(L, (n), 0, NULL)
274LUA_API int  (lua_resume) (lua_State *L, lua_State *from, int narg);
275LUA_API int  (lua_status) (lua_State *L);
276
277/*
278** garbage-collection function and options
279*/
280
281#define LUA_GCSTOP      0
282#define LUA_GCRESTART      1
283#define LUA_GCCOLLECT      2
284#define LUA_GCCOUNT      3
285#define LUA_GCCOUNTB      4
286#define LUA_GCSTEP      5
287#define LUA_GCSETPAUSE      6
288#define LUA_GCSETSTEPMUL   7
289#define LUA_GCSETMAJORINC   8
290#define LUA_GCISRUNNING      9
291#define LUA_GCGEN      10
292#define LUA_GCINC      11
293
294LUA_API int (lua_gc) (lua_State *L, int what, int data);
295
296
297/*
298** miscellaneous functions
299*/
300
301LUA_API int   (lua_error) (lua_State *L);
302
303LUA_API int   (lua_next) (lua_State *L, int idx);
304
305LUA_API void  (lua_concat) (lua_State *L, int n);
306LUA_API void  (lua_len)    (lua_State *L, int idx);
307
308LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
309LUA_API void      (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
310
311
312
313/*
314** ===============================================================
315** some useful macros
316** ===============================================================
317*/
318
319#define lua_tonumber(L,i)   lua_tonumberx(L,i,NULL)
320#define lua_tointeger(L,i)   lua_tointegerx(L,i,NULL)
321#define lua_tounsigned(L,i)   lua_tounsignedx(L,i,NULL)
322
323#define lua_pop(L,n)      lua_settop(L, -(n)-1)
324
325#define lua_newtable(L)      lua_createtable(L, 0, 0)
326
327#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
328
329#define lua_pushcfunction(L,f)   lua_pushcclosure(L, (f), 0)
330
331#define lua_isfunction(L,n)   (lua_type(L, (n)) == LUA_TFUNCTION)
332#define lua_istable(L,n)   (lua_type(L, (n)) == LUA_TTABLE)
333#define lua_islightuserdata(L,n)   (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
334#define lua_isnil(L,n)      (lua_type(L, (n)) == LUA_TNIL)
335#define lua_isboolean(L,n)   (lua_type(L, (n)) == LUA_TBOOLEAN)
336#define lua_isthread(L,n)   (lua_type(L, (n)) == LUA_TTHREAD)
337#define lua_isnone(L,n)      (lua_type(L, (n)) == LUA_TNONE)
338#define lua_isnoneornil(L, n)   (lua_type(L, (n)) <= 0)
339
340#define lua_pushliteral(L, s)   \
341   lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
342
343#define lua_pushglobaltable(L)  \
344   lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)
345
346#define lua_tostring(L,i)   lua_tolstring(L, (i), NULL)
347
348
349
350/*
351** {======================================================================
352** Debug API
353** =======================================================================
354*/
355
356
357/*
358** Event codes
359*/
360#define LUA_HOOKCALL   0
361#define LUA_HOOKRET   1
362#define LUA_HOOKLINE   2
363#define LUA_HOOKCOUNT   3
364#define LUA_HOOKTAILCALL 4
365
366
367/*
368** Event masks
369*/
370#define LUA_MASKCALL   (1 << LUA_HOOKCALL)
371#define LUA_MASKRET   (1 << LUA_HOOKRET)
372#define LUA_MASKLINE   (1 << LUA_HOOKLINE)
373#define LUA_MASKCOUNT   (1 << LUA_HOOKCOUNT)
374
375typedef struct lua_Debug lua_Debug;  /* activation record */
376
377
378/* Functions to be called by the debugger in specific events */
379typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
380
381
382LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar);
383LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar);
384LUA_API const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n);
385LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n);
386LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n);
387LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n);
388
389LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n);
390LUA_API void  (lua_upvaluejoin) (lua_State *L, int fidx1, int n1,
391                                               int fidx2, int n2);
392
393LUA_API int (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count);
394LUA_API lua_Hook (lua_gethook) (lua_State *L);
395LUA_API int (lua_gethookmask) (lua_State *L);
396LUA_API int (lua_gethookcount) (lua_State *L);
397
398
399struct lua_Debug {
400  int event;
401  const char *name;   /* (n) */
402  const char *namewhat;   /* (n) 'global', 'local', 'field', 'method' */
403  const char *what;   /* (S) 'Lua', 'C', 'main', 'tail' */
404  const char *source;   /* (S) */
405  int currentline;   /* (l) */
406  int linedefined;   /* (S) */
407  int lastlinedefined;   /* (S) */
408  unsigned char nups;   /* (u) number of upvalues */
409  unsigned char nparams;/* (u) number of parameters */
410  char isvararg;        /* (u) */
411  char istailcall;   /* (t) */
412  char short_src[LUA_IDSIZE]; /* (S) */
413  /* private part */
414  struct CallInfo *i_ci;  /* active function */
415};
416
417/* }====================================================================== */
418
419
420/******************************************************************************
421* Copyright (C) 1994-2013 Lua.org, PUC-Rio.
422*
423* Permission is hereby granted, free of charge, to any person obtaining
424* a copy of this software and associated documentation files (the
425* "Software"), to deal in the Software without restriction, including
426* without limitation the rights to use, copy, modify, merge, publish,
427* distribute, sublicense, and/or sell copies of the Software, and to
428* permit persons to whom the Software is furnished to do so, subject to
429* the following conditions:
430*
431* The above copyright notice and this permission notice shall be
432* included in all copies or substantial portions of the Software.
433*
434* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
435* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
436* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
437* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
438* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
439* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
440* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
441******************************************************************************/
442
443
444#endif
Property changes on: trunk/src/lib/lua/lua.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lcode.c
r0r22721
1/*
2** $Id: lcode.c,v 2.62 2012/08/16 17:34:28 roberto Exp $
3** Code generator for Lua
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdlib.h>
9
10#define lcode_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "lcode.h"
16#include "ldebug.h"
17#include "ldo.h"
18#include "lgc.h"
19#include "llex.h"
20#include "lmem.h"
21#include "lobject.h"
22#include "lopcodes.h"
23#include "lparser.h"
24#include "lstring.h"
25#include "ltable.h"
26#include "lvm.h"
27
28
29#define hasjumps(e)   ((e)->t != (e)->f)
30
31
32static int isnumeral(expdesc *e) {
33  return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
34}
35
36
37void luaK_nil (FuncState *fs, int from, int n) {
38  Instruction *previous;
39  int l = from + n - 1;  /* last register to set nil */
40  if (fs->pc > fs->lasttarget) {  /* no jumps to current position? */
41    previous = &fs->f->code[fs->pc-1];
42    if (GET_OPCODE(*previous) == OP_LOADNIL) {
43      int pfrom = GETARG_A(*previous);
44      int pl = pfrom + GETARG_B(*previous);
45      if ((pfrom <= from && from <= pl + 1) ||
46          (from <= pfrom && pfrom <= l + 1)) {  /* can connect both? */
47        if (pfrom < from) from = pfrom;  /* from = min(from, pfrom) */
48        if (pl > l) l = pl;  /* l = max(l, pl) */
49        SETARG_A(*previous, from);
50        SETARG_B(*previous, l - from);
51        return;
52      }
53    }  /* else go through */
54  }
55  luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0);  /* else no optimization */
56}
57
58
59int luaK_jump (FuncState *fs) {
60  int jpc = fs->jpc;  /* save list of jumps to here */
61  int j;
62  fs->jpc = NO_JUMP;
63  j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
64  luaK_concat(fs, &j, jpc);  /* keep them on hold */
65  return j;
66}
67
68
69void luaK_ret (FuncState *fs, int first, int nret) {
70  luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
71}
72
73
74static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
75  luaK_codeABC(fs, op, A, B, C);
76  return luaK_jump(fs);
77}
78
79
80static void fixjump (FuncState *fs, int pc, int dest) {
81  Instruction *jmp = &fs->f->code[pc];
82  int offset = dest-(pc+1);
83  lua_assert(dest != NO_JUMP);
84  if (abs(offset) > MAXARG_sBx)
85    luaX_syntaxerror(fs->ls, "control structure too long");
86  SETARG_sBx(*jmp, offset);
87}
88
89
90/*
91** returns current `pc' and marks it as a jump target (to avoid wrong
92** optimizations with consecutive instructions not in the same basic block).
93*/
94int luaK_getlabel (FuncState *fs) {
95  fs->lasttarget = fs->pc;
96  return fs->pc;
97}
98
99
100static int getjump (FuncState *fs, int pc) {
101  int offset = GETARG_sBx(fs->f->code[pc]);
102  if (offset == NO_JUMP)  /* point to itself represents end of list */
103    return NO_JUMP;  /* end of list */
104  else
105    return (pc+1)+offset;  /* turn offset into absolute position */
106}
107
108
109static Instruction *getjumpcontrol (FuncState *fs, int pc) {
110  Instruction *pi = &fs->f->code[pc];
111  if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
112    return pi-1;
113  else
114    return pi;
115}
116
117
118/*
119** check whether list has any jump that do not produce a value
120** (or produce an inverted value)
121*/
122static int need_value (FuncState *fs, int list) {
123  for (; list != NO_JUMP; list = getjump(fs, list)) {
124    Instruction i = *getjumpcontrol(fs, list);
125    if (GET_OPCODE(i) != OP_TESTSET) return 1;
126  }
127  return 0;  /* not found */
128}
129
130
131static int patchtestreg (FuncState *fs, int node, int reg) {
132  Instruction *i = getjumpcontrol(fs, node);
133  if (GET_OPCODE(*i) != OP_TESTSET)
134    return 0;  /* cannot patch other instructions */
135  if (reg != NO_REG && reg != GETARG_B(*i))
136    SETARG_A(*i, reg);
137  else  /* no register to put value or register already has the value */
138    *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
139
140  return 1;
141}
142
143
144static void removevalues (FuncState *fs, int list) {
145  for (; list != NO_JUMP; list = getjump(fs, list))
146      patchtestreg(fs, list, NO_REG);
147}
148
149
150static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
151                          int dtarget) {
152  while (list != NO_JUMP) {
153    int next = getjump(fs, list);
154    if (patchtestreg(fs, list, reg))
155      fixjump(fs, list, vtarget);
156    else
157      fixjump(fs, list, dtarget);  /* jump to default target */
158    list = next;
159  }
160}
161
162
163static void dischargejpc (FuncState *fs) {
164  patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
165  fs->jpc = NO_JUMP;
166}
167
168
169void luaK_patchlist (FuncState *fs, int list, int target) {
170  if (target == fs->pc)
171    luaK_patchtohere(fs, list);
172  else {
173    lua_assert(target < fs->pc);
174    patchlistaux(fs, list, target, NO_REG, target);
175  }
176}
177
178
179LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level) {
180  level++;  /* argument is +1 to reserve 0 as non-op */
181  while (list != NO_JUMP) {
182    int next = getjump(fs, list);
183    lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP &&
184                (GETARG_A(fs->f->code[list]) == 0 ||
185                 GETARG_A(fs->f->code[list]) >= level));
186    SETARG_A(fs->f->code[list], level);
187    list = next;
188  }
189}
190
191
192void luaK_patchtohere (FuncState *fs, int list) {
193  luaK_getlabel(fs);
194  luaK_concat(fs, &fs->jpc, list);
195}
196
197
198void luaK_concat (FuncState *fs, int *l1, int l2) {
199  if (l2 == NO_JUMP) return;
200  else if (*l1 == NO_JUMP)
201    *l1 = l2;
202  else {
203    int list = *l1;
204    int next;
205    while ((next = getjump(fs, list)) != NO_JUMP)  /* find last element */
206      list = next;
207    fixjump(fs, list, l2);
208  }
209}
210
211
212static int luaK_code (FuncState *fs, Instruction i) {
213  Proto *f = fs->f;
214  dischargejpc(fs);  /* `pc' will change */
215  /* put new instruction in code array */
216  luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
217                  MAX_INT, "opcodes");
218  f->code[fs->pc] = i;
219  /* save corresponding line information */
220  luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
221                  MAX_INT, "opcodes");
222  f->lineinfo[fs->pc] = fs->ls->lastline;
223  return fs->pc++;
224}
225
226
227int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
228  lua_assert(getOpMode(o) == iABC);
229  lua_assert(getBMode(o) != OpArgN || b == 0);
230  lua_assert(getCMode(o) != OpArgN || c == 0);
231  lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C);
232  return luaK_code(fs, CREATE_ABC(o, a, b, c));
233}
234
235
236int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
237  lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
238  lua_assert(getCMode(o) == OpArgN);
239  lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
240  return luaK_code(fs, CREATE_ABx(o, a, bc));
241}
242
243
244static int codeextraarg (FuncState *fs, int a) {
245  lua_assert(a <= MAXARG_Ax);
246  return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a));
247}
248
249
250int luaK_codek (FuncState *fs, int reg, int k) {
251  if (k <= MAXARG_Bx)
252    return luaK_codeABx(fs, OP_LOADK, reg, k);
253  else {
254    int p = luaK_codeABx(fs, OP_LOADKX, reg, 0);
255    codeextraarg(fs, k);
256    return p;
257  }
258}
259
260
261void luaK_checkstack (FuncState *fs, int n) {
262  int newstack = fs->freereg + n;
263  if (newstack > fs->f->maxstacksize) {
264    if (newstack >= MAXSTACK)
265      luaX_syntaxerror(fs->ls, "function or expression too complex");
266    fs->f->maxstacksize = cast_byte(newstack);
267  }
268}
269
270
271void luaK_reserveregs (FuncState *fs, int n) {
272  luaK_checkstack(fs, n);
273  fs->freereg += n;
274}
275
276
277static void freereg (FuncState *fs, int reg) {
278  if (!ISK(reg) && reg >= fs->nactvar) {
279    fs->freereg--;
280    lua_assert(reg == fs->freereg);
281  }
282}
283
284
285static void freeexp (FuncState *fs, expdesc *e) {
286  if (e->k == VNONRELOC)
287    freereg(fs, e->u.info);
288}
289
290
291static int addk (FuncState *fs, TValue *key, TValue *v) {
292  lua_State *L = fs->ls->L;
293  TValue *idx = luaH_set(L, fs->h, key);
294  Proto *f = fs->f;
295  int k, oldsize;
296  if (ttisnumber(idx)) {
297    lua_Number n = nvalue(idx);
298    lua_number2int(k, n);
299    if (luaV_rawequalobj(&f->k[k], v))
300      return k;
301    /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0");
302       go through and create a new entry for this value */
303  }
304  /* constant not found; create a new entry */
305  oldsize = f->sizek;
306  k = fs->nk;
307  /* numerical value does not need GC barrier;
308     table has no metatable, so it does not need to invalidate cache */
309  setnvalue(idx, cast_num(k));
310  luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
311  while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
312  setobj(L, &f->k[k], v);
313  fs->nk++;
314  luaC_barrier(L, f, v);
315  return k;
316}
317
318
319int luaK_stringK (FuncState *fs, TString *s) {
320  TValue o;
321  setsvalue(fs->ls->L, &o, s);
322  return addk(fs, &o, &o);
323}
324
325
326int luaK_numberK (FuncState *fs, lua_Number r) {
327  int n;
328  lua_State *L = fs->ls->L;
329  TValue o;
330  setnvalue(&o, r);
331  if (r == 0 || luai_numisnan(NULL, r)) {  /* handle -0 and NaN */
332    /* use raw representation as key to avoid numeric problems */
333    setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r)));
334    n = addk(fs, L->top - 1, &o);
335    L->top--;
336  }
337  else
338    n = addk(fs, &o, &o);  /* regular case */
339  return n;
340}
341
342
343static int boolK (FuncState *fs, int b) {
344  TValue o;
345  setbvalue(&o, b);
346  return addk(fs, &o, &o);
347}
348
349
350static int nilK (FuncState *fs) {
351  TValue k, v;
352  setnilvalue(&v);
353  /* cannot use nil as key; instead use table itself to represent nil */
354  sethvalue(fs->ls->L, &k, fs->h);
355  return addk(fs, &k, &v);
356}
357
358
359void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
360  if (e->k == VCALL) {  /* expression is an open function call? */
361    SETARG_C(getcode(fs, e), nresults+1);
362  }
363  else if (e->k == VVARARG) {
364    SETARG_B(getcode(fs, e), nresults+1);
365    SETARG_A(getcode(fs, e), fs->freereg);
366    luaK_reserveregs(fs, 1);
367  }
368}
369
370
371void luaK_setoneret (FuncState *fs, expdesc *e) {
372  if (e->k == VCALL) {  /* expression is an open function call? */
373    e->k = VNONRELOC;
374    e->u.info = GETARG_A(getcode(fs, e));
375  }
376  else if (e->k == VVARARG) {
377    SETARG_B(getcode(fs, e), 2);
378    e->k = VRELOCABLE;  /* can relocate its simple result */
379  }
380}
381
382
383void luaK_dischargevars (FuncState *fs, expdesc *e) {
384  switch (e->k) {
385    case VLOCAL: {
386      e->k = VNONRELOC;
387      break;
388    }
389    case VUPVAL: {
390      e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
391      e->k = VRELOCABLE;
392      break;
393    }
394    case VINDEXED: {
395      OpCode op = OP_GETTABUP;  /* assume 't' is in an upvalue */
396      freereg(fs, e->u.ind.idx);
397      if (e->u.ind.vt == VLOCAL) {  /* 't' is in a register? */
398        freereg(fs, e->u.ind.t);
399        op = OP_GETTABLE;
400      }
401      e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
402      e->k = VRELOCABLE;
403      break;
404    }
405    case VVARARG:
406    case VCALL: {
407      luaK_setoneret(fs, e);
408      break;
409    }
410    default: break;  /* there is one value available (somewhere) */
411  }
412}
413
414
415static int code_label (FuncState *fs, int A, int b, int jump) {
416  luaK_getlabel(fs);  /* those instructions may be jump targets */
417  return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
418}
419
420
421static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
422  luaK_dischargevars(fs, e);
423  switch (e->k) {
424    case VNIL: {
425      luaK_nil(fs, reg, 1);
426      break;
427    }
428    case VFALSE: case VTRUE: {
429      luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
430      break;
431    }
432    case VK: {
433      luaK_codek(fs, reg, e->u.info);
434      break;
435    }
436    case VKNUM: {
437      luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval));
438      break;
439    }
440    case VRELOCABLE: {
441      Instruction *pc = &getcode(fs, e);
442      SETARG_A(*pc, reg);
443      break;
444    }
445    case VNONRELOC: {
446      if (reg != e->u.info)
447        luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
448      break;
449    }
450    default: {
451      lua_assert(e->k == VVOID || e->k == VJMP);
452      return;  /* nothing to do... */
453    }
454  }
455  e->u.info = reg;
456  e->k = VNONRELOC;
457}
458
459
460static void discharge2anyreg (FuncState *fs, expdesc *e) {
461  if (e->k != VNONRELOC) {
462    luaK_reserveregs(fs, 1);
463    discharge2reg(fs, e, fs->freereg-1);
464  }
465}
466
467
468static void exp2reg (FuncState *fs, expdesc *e, int reg) {
469  discharge2reg(fs, e, reg);
470  if (e->k == VJMP)
471    luaK_concat(fs, &e->t, e->u.info);  /* put this jump in `t' list */
472  if (hasjumps(e)) {
473    int final;  /* position after whole expression */
474    int p_f = NO_JUMP;  /* position of an eventual LOAD false */
475    int p_t = NO_JUMP;  /* position of an eventual LOAD true */
476    if (need_value(fs, e->t) || need_value(fs, e->f)) {
477      int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
478      p_f = code_label(fs, reg, 0, 1);
479      p_t = code_label(fs, reg, 1, 0);
480      luaK_patchtohere(fs, fj);
481    }
482    final = luaK_getlabel(fs);
483    patchlistaux(fs, e->f, final, reg, p_f);
484    patchlistaux(fs, e->t, final, reg, p_t);
485  }
486  e->f = e->t = NO_JUMP;
487  e->u.info = reg;
488  e->k = VNONRELOC;
489}
490
491
492void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
493  luaK_dischargevars(fs, e);
494  freeexp(fs, e);
495  luaK_reserveregs(fs, 1);
496  exp2reg(fs, e, fs->freereg - 1);
497}
498
499
500int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
501  luaK_dischargevars(fs, e);
502  if (e->k == VNONRELOC) {
503    if (!hasjumps(e)) return e->u.info;  /* exp is already in a register */
504    if (e->u.info >= fs->nactvar) {  /* reg. is not a local? */
505      exp2reg(fs, e, e->u.info);  /* put value on it */
506      return e->u.info;
507    }
508  }
509  luaK_exp2nextreg(fs, e);  /* default */
510  return e->u.info;
511}
512
513
514void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
515  if (e->k != VUPVAL || hasjumps(e))
516    luaK_exp2anyreg(fs, e);
517}
518
519
520void luaK_exp2val (FuncState *fs, expdesc *e) {
521  if (hasjumps(e))
522    luaK_exp2anyreg(fs, e);
523  else
524    luaK_dischargevars(fs, e);
525}
526
527
528int luaK_exp2RK (FuncState *fs, expdesc *e) {
529  luaK_exp2val(fs, e);
530  switch (e->k) {
531    case VTRUE:
532    case VFALSE:
533    case VNIL: {
534      if (fs->nk <= MAXINDEXRK) {  /* constant fits in RK operand? */
535        e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
536        e->k = VK;
537        return RKASK(e->u.info);
538      }
539      else break;
540    }
541    case VKNUM: {
542      e->u.info = luaK_numberK(fs, e->u.nval);
543      e->k = VK;
544      /* go through */
545    }
546    case VK: {
547      if (e->u.info <= MAXINDEXRK)  /* constant fits in argC? */
548        return RKASK(e->u.info);
549      else break;
550    }
551    default: break;
552  }
553  /* not a constant in the right range: put it in a register */
554  return luaK_exp2anyreg(fs, e);
555}
556
557
558void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
559  switch (var->k) {
560    case VLOCAL: {
561      freeexp(fs, ex);
562      exp2reg(fs, ex, var->u.info);
563      return;
564    }
565    case VUPVAL: {
566      int e = luaK_exp2anyreg(fs, ex);
567      luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
568      break;
569    }
570    case VINDEXED: {
571      OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP;
572      int e = luaK_exp2RK(fs, ex);
573      luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
574      break;
575    }
576    default: {
577      lua_assert(0);  /* invalid var kind to store */
578      break;
579    }
580  }
581  freeexp(fs, ex);
582}
583
584
585void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
586  int ereg;
587  luaK_exp2anyreg(fs, e);
588  ereg = e->u.info;  /* register where 'e' was placed */
589  freeexp(fs, e);
590  e->u.info = fs->freereg;  /* base register for op_self */
591  e->k = VNONRELOC;
592  luaK_reserveregs(fs, 2);  /* function and 'self' produced by op_self */
593  luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key));
594  freeexp(fs, key);
595}
596
597
598static void invertjump (FuncState *fs, expdesc *e) {
599  Instruction *pc = getjumpcontrol(fs, e->u.info);
600  lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
601                                           GET_OPCODE(*pc) != OP_TEST);
602  SETARG_A(*pc, !(GETARG_A(*pc)));
603}
604
605
606static int jumponcond (FuncState *fs, expdesc *e, int cond) {
607  if (e->k == VRELOCABLE) {
608    Instruction ie = getcode(fs, e);
609    if (GET_OPCODE(ie) == OP_NOT) {
610      fs->pc--;  /* remove previous OP_NOT */
611      return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
612    }
613    /* else go through */
614  }
615  discharge2anyreg(fs, e);
616  freeexp(fs, e);
617  return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond);
618}
619
620
621void luaK_goiftrue (FuncState *fs, expdesc *e) {
622  int pc;  /* pc of last jump */
623  luaK_dischargevars(fs, e);
624  switch (e->k) {
625    case VJMP: {
626      invertjump(fs, e);
627      pc = e->u.info;
628      break;
629    }
630    case VK: case VKNUM: case VTRUE: {
631      pc = NO_JUMP;  /* always true; do nothing */
632      break;
633    }
634    default: {
635      pc = jumponcond(fs, e, 0);
636      break;
637    }
638  }
639  luaK_concat(fs, &e->f, pc);  /* insert last jump in `f' list */
640  luaK_patchtohere(fs, e->t);
641  e->t = NO_JUMP;
642}
643
644
645void luaK_goiffalse (FuncState *fs, expdesc *e) {
646  int pc;  /* pc of last jump */
647  luaK_dischargevars(fs, e);
648  switch (e->k) {
649    case VJMP: {
650      pc = e->u.info;
651      break;
652    }
653    case VNIL: case VFALSE: {
654      pc = NO_JUMP;  /* always false; do nothing */
655      break;
656    }
657    default: {
658      pc = jumponcond(fs, e, 1);
659      break;
660    }
661  }
662  luaK_concat(fs, &e->t, pc);  /* insert last jump in `t' list */
663  luaK_patchtohere(fs, e->f);
664  e->f = NO_JUMP;
665}
666
667
668static void codenot (FuncState *fs, expdesc *e) {
669  luaK_dischargevars(fs, e);
670  switch (e->k) {
671    case VNIL: case VFALSE: {
672      e->k = VTRUE;
673      break;
674    }
675    case VK: case VKNUM: case VTRUE: {
676      e->k = VFALSE;
677      break;
678    }
679    case VJMP: {
680      invertjump(fs, e);
681      break;
682    }
683    case VRELOCABLE:
684    case VNONRELOC: {
685      discharge2anyreg(fs, e);
686      freeexp(fs, e);
687      e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0);
688      e->k = VRELOCABLE;
689      break;
690    }
691    default: {
692      lua_assert(0);  /* cannot happen */
693      break;
694    }
695  }
696  /* interchange true and false lists */
697  { int temp = e->f; e->f = e->t; e->t = temp; }
698  removevalues(fs, e->f);
699  removevalues(fs, e->t);
700}
701
702
703void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
704  lua_assert(!hasjumps(t));
705  t->u.ind.t = t->u.info;
706  t->u.ind.idx = luaK_exp2RK(fs, k);
707  t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL
708                                 : check_exp(vkisinreg(t->k), VLOCAL);
709  t->k = VINDEXED;
710}
711
712
713static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
714  lua_Number r;
715  if (!isnumeral(e1) || !isnumeral(e2)) return 0;
716  if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0)
717    return 0;  /* do not attempt to divide by 0 */
718  r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval);
719  e1->u.nval = r;
720  return 1;
721}
722
723
724static void codearith (FuncState *fs, OpCode op,
725                       expdesc *e1, expdesc *e2, int line) {
726  if (constfolding(op, e1, e2))
727    return;
728  else {
729    int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
730    int o1 = luaK_exp2RK(fs, e1);
731    if (o1 > o2) {
732      freeexp(fs, e1);
733      freeexp(fs, e2);
734    }
735    else {
736      freeexp(fs, e2);
737      freeexp(fs, e1);
738    }
739    e1->u.info = luaK_codeABC(fs, op, 0, o1, o2);
740    e1->k = VRELOCABLE;
741    luaK_fixline(fs, line);
742  }
743}
744
745
746static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
747                                                          expdesc *e2) {
748  int o1 = luaK_exp2RK(fs, e1);
749  int o2 = luaK_exp2RK(fs, e2);
750  freeexp(fs, e2);
751  freeexp(fs, e1);
752  if (cond == 0 && op != OP_EQ) {
753    int temp;  /* exchange args to replace by `<' or `<=' */
754    temp = o1; o1 = o2; o2 = temp;  /* o1 <==> o2 */
755    cond = 1;
756  }
757  e1->u.info = condjump(fs, op, cond, o1, o2);
758  e1->k = VJMP;
759}
760
761
762void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
763  expdesc e2;
764  e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
765  switch (op) {
766    case OPR_MINUS: {
767      if (isnumeral(e))  /* minus constant? */
768        e->u.nval = luai_numunm(NULL, e->u.nval);  /* fold it */
769      else {
770        luaK_exp2anyreg(fs, e);
771        codearith(fs, OP_UNM, e, &e2, line);
772      }
773      break;
774    }
775    case OPR_NOT: codenot(fs, e); break;
776    case OPR_LEN: {
777      luaK_exp2anyreg(fs, e);  /* cannot operate on constants */
778      codearith(fs, OP_LEN, e, &e2, line);
779      break;
780    }
781    default: lua_assert(0);
782  }
783}
784
785
786void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
787  switch (op) {
788    case OPR_AND: {
789      luaK_goiftrue(fs, v);
790      break;
791    }
792    case OPR_OR: {
793      luaK_goiffalse(fs, v);
794      break;
795    }
796    case OPR_CONCAT: {
797      luaK_exp2nextreg(fs, v);  /* operand must be on the `stack' */
798      break;
799    }
800    case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
801    case OPR_MOD: case OPR_POW: {
802      if (!isnumeral(v)) luaK_exp2RK(fs, v);
803      break;
804    }
805    default: {
806      luaK_exp2RK(fs, v);
807      break;
808    }
809  }
810}
811
812
813void luaK_posfix (FuncState *fs, BinOpr op,
814                  expdesc *e1, expdesc *e2, int line) {
815  switch (op) {
816    case OPR_AND: {
817      lua_assert(e1->t == NO_JUMP);  /* list must be closed */
818      luaK_dischargevars(fs, e2);
819      luaK_concat(fs, &e2->f, e1->f);
820      *e1 = *e2;
821      break;
822    }
823    case OPR_OR: {
824      lua_assert(e1->f == NO_JUMP);  /* list must be closed */
825      luaK_dischargevars(fs, e2);
826      luaK_concat(fs, &e2->t, e1->t);
827      *e1 = *e2;
828      break;
829    }
830    case OPR_CONCAT: {
831      luaK_exp2val(fs, e2);
832      if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
833        lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1);
834        freeexp(fs, e1);
835        SETARG_B(getcode(fs, e2), e1->u.info);
836        e1->k = VRELOCABLE; e1->u.info = e2->u.info;
837      }
838      else {
839        luaK_exp2nextreg(fs, e2);  /* operand must be on the 'stack' */
840        codearith(fs, OP_CONCAT, e1, e2, line);
841      }
842      break;
843    }
844    case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
845    case OPR_MOD: case OPR_POW: {
846      codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line);
847      break;
848    }
849    case OPR_EQ: case OPR_LT: case OPR_LE: {
850      codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2);
851      break;
852    }
853    case OPR_NE: case OPR_GT: case OPR_GE: {
854      codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2);
855      break;
856    }
857    default: lua_assert(0);
858  }
859}
860
861
862void luaK_fixline (FuncState *fs, int line) {
863  fs->f->lineinfo[fs->pc - 1] = line;
864}
865
866
867void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
868  int c =  (nelems - 1)/LFIELDS_PER_FLUSH + 1;
869  int b = (tostore == LUA_MULTRET) ? 0 : tostore;
870  lua_assert(tostore != 0);
871  if (c <= MAXARG_C)
872    luaK_codeABC(fs, OP_SETLIST, base, b, c);
873  else if (c <= MAXARG_Ax) {
874    luaK_codeABC(fs, OP_SETLIST, base, b, 0);
875    codeextraarg(fs, c);
876  }
877  else
878    luaX_syntaxerror(fs->ls, "constructor too long");
879  fs->freereg = base + 1;  /* free registers with list values */
880}
881
Property changes on: trunk/src/lib/lua/lcode.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/lobject.h
r0r22721
1/*
2** $Id: lobject.h,v 2.71 2012/09/11 18:21:44 roberto Exp $
3** Type definitions for Lua objects
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lobject_h
9#define lobject_h
10
11
12#include <stdarg.h>
13
14
15#include "llimits.h"
16#include "lua.h"
17
18
19/*
20** Extra tags for non-values
21*/
22#define LUA_TPROTO   LUA_NUMTAGS
23#define LUA_TUPVAL   (LUA_NUMTAGS+1)
24#define LUA_TDEADKEY   (LUA_NUMTAGS+2)
25
26/*
27** number of all possible tags (including LUA_TNONE but excluding DEADKEY)
28*/
29#define LUA_TOTALTAGS   (LUA_TUPVAL+2)
30
31
32/*
33** tags for Tagged Values have the following use of bits:
34** bits 0-3: actual tag (a LUA_T* value)
35** bits 4-5: variant bits
36** bit 6: whether value is collectable
37*/
38
39#define VARBITS      (3 << 4)
40
41
42/*
43** LUA_TFUNCTION variants:
44** 0 - Lua function
45** 1 - light C function
46** 2 - regular C function (closure)
47*/
48
49/* Variant tags for functions */
50#define LUA_TLCL   (LUA_TFUNCTION | (0 << 4))  /* Lua closure */
51#define LUA_TLCF   (LUA_TFUNCTION | (1 << 4))  /* light C function */
52#define LUA_TCCL   (LUA_TFUNCTION | (2 << 4))  /* C closure */
53
54
55/* Variant tags for strings */
56#define LUA_TSHRSTR   (LUA_TSTRING | (0 << 4))  /* short strings */
57#define LUA_TLNGSTR   (LUA_TSTRING | (1 << 4))  /* long strings */
58
59
60/* Bit mark for collectable types */
61#define BIT_ISCOLLECTABLE   (1 << 6)
62
63/* mark a tag as collectable */
64#define ctb(t)         ((t) | BIT_ISCOLLECTABLE)
65
66
67/*
68** Union of all collectable objects
69*/
70typedef union GCObject GCObject;
71
72
73/*
74** Common Header for all collectable objects (in macro form, to be
75** included in other objects)
76*/
77#define CommonHeader   GCObject *next; lu_byte tt; lu_byte marked
78
79
80/*
81** Common header in struct form
82*/
83typedef struct GCheader {
84  CommonHeader;
85} GCheader;
86
87
88
89/*
90** Union of all Lua values
91*/
92typedef union Value Value;
93
94
95#define numfield   lua_Number n;    /* numbers */
96
97
98
99/*
100** Tagged Values. This is the basic representation of values in Lua,
101** an actual value plus a tag with its type.
102*/
103
104#define TValuefields   Value value_; int tt_
105
106typedef struct lua_TValue TValue;
107
108
109/* macro defining a nil value */
110#define NILCONSTANT   {NULL}, LUA_TNIL
111
112
113#define val_(o)      ((o)->value_)
114#define num_(o)      (val_(o).n)
115
116
117/* raw type tag of a TValue */
118#define rttype(o)   ((o)->tt_)
119
120/* tag with no variants (bits 0-3) */
121#define novariant(x)   ((x) & 0x0F)
122
123/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
124#define ttype(o)   (rttype(o) & 0x3F)
125
126/* type tag of a TValue with no variants (bits 0-3) */
127#define ttypenv(o)   (novariant(rttype(o)))
128
129
130/* Macros to test type */
131#define checktag(o,t)      (rttype(o) == (t))
132#define checktype(o,t)      (ttypenv(o) == (t))
133#define ttisnumber(o)      checktag((o), LUA_TNUMBER)
134#define ttisnil(o)      checktag((o), LUA_TNIL)
135#define ttisboolean(o)      checktag((o), LUA_TBOOLEAN)
136#define ttislightuserdata(o)   checktag((o), LUA_TLIGHTUSERDATA)
137#define ttisstring(o)      checktype((o), LUA_TSTRING)
138#define ttisshrstring(o)   checktag((o), ctb(LUA_TSHRSTR))
139#define ttislngstring(o)   checktag((o), ctb(LUA_TLNGSTR))
140#define ttistable(o)      checktag((o), ctb(LUA_TTABLE))
141#define ttisfunction(o)      checktype(o, LUA_TFUNCTION)
142#define ttisclosure(o)      ((rttype(o) & 0x1F) == LUA_TFUNCTION)
143#define ttisCclosure(o)      checktag((o), ctb(LUA_TCCL))
144#define ttisLclosure(o)      checktag((o), ctb(LUA_TLCL))
145#define ttislcf(o)      checktag((o), LUA_TLCF)
146#define ttisuserdata(o)      checktag((o), ctb(LUA_TUSERDATA))
147#define ttisthread(o)      checktag((o), ctb(LUA_TTHREAD))
148#define ttisdeadkey(o)      checktag((o), LUA_TDEADKEY)
149
150#define ttisequal(o1,o2)   (rttype(o1) == rttype(o2))
151
152/* Macros to access values */
153#define nvalue(o)   check_exp(ttisnumber(o), num_(o))
154#define gcvalue(o)   check_exp(iscollectable(o), val_(o).gc)
155#define pvalue(o)   check_exp(ttislightuserdata(o), val_(o).p)
156#define rawtsvalue(o)   check_exp(ttisstring(o), &val_(o).gc->ts)
157#define tsvalue(o)   (&rawtsvalue(o)->tsv)
158#define rawuvalue(o)   check_exp(ttisuserdata(o), &val_(o).gc->u)
159#define uvalue(o)   (&rawuvalue(o)->uv)
160#define clvalue(o)   check_exp(ttisclosure(o), &val_(o).gc->cl)
161#define clLvalue(o)   check_exp(ttisLclosure(o), &val_(o).gc->cl.l)
162#define clCvalue(o)   check_exp(ttisCclosure(o), &val_(o).gc->cl.c)
163#define fvalue(o)   check_exp(ttislcf(o), val_(o).f)
164#define hvalue(o)   check_exp(ttistable(o), &val_(o).gc->h)
165#define bvalue(o)   check_exp(ttisboolean(o), val_(o).b)
166#define thvalue(o)   check_exp(ttisthread(o), &val_(o).gc->th)
167/* a dead value may get the 'gc' field, but cannot access its contents */
168#define deadvalue(o)   check_exp(ttisdeadkey(o), cast(void *, val_(o).gc))
169
170#define l_isfalse(o)   (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
171
172
173#define iscollectable(o)   (rttype(o) & BIT_ISCOLLECTABLE)
174
175
176/* Macros for internal tests */
177#define righttt(obj)      (ttype(obj) == gcvalue(obj)->gch.tt)
178
179#define checkliveness(g,obj) \
180   lua_longassert(!iscollectable(obj) || \
181         (righttt(obj) && !isdead(g,gcvalue(obj))))
182
183
184/* Macros to set values */
185#define settt_(o,t)   ((o)->tt_=(t))
186
187#define setnvalue(obj,x) \
188  { TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); }
189
190#define setnilvalue(obj) settt_(obj, LUA_TNIL)
191
192#define setfvalue(obj,x) \
193  { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); }
194
195#define setpvalue(obj,x) \
196  { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); }
197
198#define setbvalue(obj,x) \
199  { TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); }
200
201#define setgcovalue(L,obj,x) \
202  { TValue *io=(obj); GCObject *i_g=(x); \
203    val_(io).gc=i_g; settt_(io, ctb(gch(i_g)->tt)); }
204
205#define setsvalue(L,obj,x) \
206  { TValue *io=(obj); \
207    TString *x_ = (x); \
208    val_(io).gc=cast(GCObject *, x_); settt_(io, ctb(x_->tsv.tt)); \
209    checkliveness(G(L),io); }
210
211#define setuvalue(L,obj,x) \
212  { TValue *io=(obj); \
213    val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TUSERDATA)); \
214    checkliveness(G(L),io); }
215
216#define setthvalue(L,obj,x) \
217  { TValue *io=(obj); \
218    val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); \
219    checkliveness(G(L),io); }
220
221#define setclLvalue(L,obj,x) \
222  { TValue *io=(obj); \
223    val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TLCL)); \
224    checkliveness(G(L),io); }
225
226#define setclCvalue(L,obj,x) \
227  { TValue *io=(obj); \
228    val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TCCL)); \
229    checkliveness(G(L),io); }
230
231#define sethvalue(L,obj,x) \
232  { TValue *io=(obj); \
233    val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTABLE)); \
234    checkliveness(G(L),io); }
235
236#define setdeadvalue(obj)   settt_(obj, LUA_TDEADKEY)
237
238
239
240#define setobj(L,obj1,obj2) \
241   { const TValue *io2=(obj2); TValue *io1=(obj1); \
242     io1->value_ = io2->value_; io1->tt_ = io2->tt_; \
243     checkliveness(G(L),io1); }
244
245
246/*
247** different types of assignments, according to destination
248*/
249
250/* from stack to (same) stack */
251#define setobjs2s   setobj
252/* to stack (not from same stack) */
253#define setobj2s   setobj
254#define setsvalue2s   setsvalue
255#define sethvalue2s   sethvalue
256#define setptvalue2s   setptvalue
257/* from table to same table */
258#define setobjt2t   setobj
259/* to table */
260#define setobj2t   setobj
261/* to new object */
262#define setobj2n   setobj
263#define setsvalue2n   setsvalue
264
265
266/* check whether a number is valid (useful only for NaN trick) */
267#define luai_checknum(L,o,c)   { /* empty */ }
268
269
270/*
271** {======================================================
272** NaN Trick
273** =======================================================
274*/
275#if defined(LUA_NANTRICK)
276
277/*
278** numbers are represented in the 'd_' field. All other values have the
279** value (NNMARK | tag) in 'tt__'. A number with such pattern would be
280** a "signaled NaN", which is never generated by regular operations by
281** the CPU (nor by 'strtod')
282*/
283
284/* allows for external implementation for part of the trick */
285#if !defined(NNMARK)   /* { */
286
287
288#if !defined(LUA_IEEEENDIAN)
289#error option 'LUA_NANTRICK' needs 'LUA_IEEEENDIAN'
290#endif
291
292
293#define NNMARK      0x7FF7A500
294#define NNMASK      0x7FFFFF00
295
296#undef TValuefields
297#undef NILCONSTANT
298
299#if (LUA_IEEEENDIAN == 0)   /* { */
300
301/* little endian */
302#define TValuefields  \
303   union { struct { Value v__; int tt__; } i; double d__; } u
304#define NILCONSTANT   {{{NULL}, tag2tt(LUA_TNIL)}}
305/* field-access macros */
306#define v_(o)      ((o)->u.i.v__)
307#define d_(o)      ((o)->u.d__)
308#define tt_(o)      ((o)->u.i.tt__)
309
310#else            /* }{ */
311
312/* big endian */
313#define TValuefields  \
314   union { struct { int tt__; Value v__; } i; double d__; } u
315#define NILCONSTANT   {{tag2tt(LUA_TNIL), {NULL}}}
316/* field-access macros */
317#define v_(o)      ((o)->u.i.v__)
318#define d_(o)      ((o)->u.d__)
319#define tt_(o)      ((o)->u.i.tt__)
320
321#endif            /* } */
322
323#endif         /* } */
324
325
326/* correspondence with standard representation */
327#undef val_
328#define val_(o)      v_(o)
329#undef num_
330#define num_(o)      d_(o)
331
332
333#undef numfield
334#define numfield   /* no such field; numbers are the entire struct */
335
336/* basic check to distinguish numbers from non-numbers */
337#undef ttisnumber
338#define ttisnumber(o)   ((tt_(o) & NNMASK) != NNMARK)
339
340#define tag2tt(t)   (NNMARK | (t))
341
342#undef rttype
343#define rttype(o)   (ttisnumber(o) ? LUA_TNUMBER : tt_(o) & 0xff)
344
345#undef settt_
346#define settt_(o,t)   (tt_(o) = tag2tt(t))
347
348#undef setnvalue
349#define setnvalue(obj,x) \
350   { TValue *io_=(obj); num_(io_)=(x); lua_assert(ttisnumber(io_)); }
351
352#undef setobj
353#define setobj(L,obj1,obj2) \
354   { const TValue *o2_=(obj2); TValue *o1_=(obj1); \
355     o1_->u = o2_->u; \
356     checkliveness(G(L),o1_); }
357
358
359/*
360** these redefinitions are not mandatory, but these forms are more efficient
361*/
362
363#undef checktag
364#undef checktype
365#define checktag(o,t)   (tt_(o) == tag2tt(t))
366#define checktype(o,t)   (ctb(tt_(o) | VARBITS) == ctb(tag2tt(t) | VARBITS))
367
368#undef ttisequal
369#define ttisequal(o1,o2)  \
370   (ttisnumber(o1) ? ttisnumber(o2) : (tt_(o1) == tt_(o2)))
371
372
373#undef luai_checknum
374#define luai_checknum(L,o,c)   { if (!ttisnumber(o)) c; }
375
376#endif
377/* }====================================================== */
378
379
380
381/*
382** {======================================================
383** types and prototypes
384** =======================================================
385*/
386
387
388union Value {
389  GCObject *gc;    /* collectable objects */
390  void *p;         /* light userdata */
391  int b;           /* booleans */
392  lua_CFunction f; /* light C functions */
393  numfield         /* numbers */
394};
395
396
397struct lua_TValue {
398  TValuefields;
399};
400
401
402typedef TValue *StkId;  /* index to stack elements */
403
404
405
406
407/*
408** Header for string value; string bytes follow the end of this structure
409*/
410typedef union TString {
411  L_Umaxalign dummy;  /* ensures maximum alignment for strings */
412  struct {
413    CommonHeader;
414    lu_byte extra;  /* reserved words for short strings; "has hash" for longs */
415    unsigned int hash;
416    size_t len;  /* number of characters in string */
417  } tsv;
418} TString;
419
420
421/* get the actual string (array of bytes) from a TString */
422#define getstr(ts)   cast(const char *, (ts) + 1)
423
424/* get the actual string (array of bytes) from a Lua value */
425#define svalue(o)       getstr(rawtsvalue(o))
426
427
428/*
429** Header for userdata; memory area follows the end of this structure
430*/
431typedef union Udata {
432  L_Umaxalign dummy;  /* ensures maximum alignment for `local' udata */
433  struct {
434    CommonHeader;
435    struct Table *metatable;
436    struct Table *env;
437    size_t len;  /* number of bytes */
438  } uv;
439} Udata;
440
441
442
443/*
444** Description of an upvalue for function prototypes
445*/
446typedef struct Upvaldesc {
447  TString *name;  /* upvalue name (for debug information) */
448  lu_byte instack;  /* whether it is in stack */
449  lu_byte idx;  /* index of upvalue (in stack or in outer function's list) */
450} Upvaldesc;
451
452
453/*
454** Description of a local variable for function prototypes
455** (used for debug information)
456*/
457typedef struct LocVar {
458  TString *varname;
459  int startpc;  /* first point where variable is active */
460  int endpc;    /* first point where variable is dead */
461} LocVar;
462
463
464/*
465** Function Prototypes
466*/
467typedef struct Proto {
468  CommonHeader;
469  TValue *k;  /* constants used by the function */
470  Instruction *code;
471  struct Proto **p;  /* functions defined inside the function */
472  int *lineinfo;  /* map from opcodes to source lines (debug information) */
473  LocVar *locvars;  /* information about local variables (debug information) */
474  Upvaldesc *upvalues;  /* upvalue information */
475  union Closure *cache;  /* last created closure with this prototype */
476  TString  *source;  /* used for debug information */
477  int sizeupvalues;  /* size of 'upvalues' */
478  int sizek;  /* size of `k' */
479  int sizecode;
480  int sizelineinfo;
481  int sizep;  /* size of `p' */
482  int sizelocvars;
483  int linedefined;
484  int lastlinedefined;
485  GCObject *gclist;
486  lu_byte numparams;  /* number of fixed parameters */
487  lu_byte is_vararg;
488  lu_byte maxstacksize;  /* maximum stack used by this function */
489} Proto;
490
491
492
493/*
494** Lua Upvalues
495*/
496typedef struct UpVal {
497  CommonHeader;
498  TValue *v;  /* points to stack or to its own value */
499  union {
500    TValue value;  /* the value (when closed) */
501    struct {  /* double linked list (when open) */
502      struct UpVal *prev;
503      struct UpVal *next;
504    } l;
505  } u;
506} UpVal;
507
508
509/*
510** Closures
511*/
512
513#define ClosureHeader \
514   CommonHeader; lu_byte nupvalues; GCObject *gclist
515
516typedef struct CClosure {
517  ClosureHeader;
518  lua_CFunction f;
519  TValue upvalue[1];  /* list of upvalues */
520} CClosure;
521
522
523typedef struct LClosure {
524  ClosureHeader;
525  struct Proto *p;
526  UpVal *upvals[1];  /* list of upvalues */
527} LClosure;
528
529
530typedef union Closure {
531  CClosure c;
532  LClosure l;
533} Closure;
534
535
536#define isLfunction(o)   ttisLclosure(o)
537
538#define getproto(o)   (clLvalue(o)->p)
539
540
541/*
542** Tables
543*/
544
545typedef union TKey {
546  struct {
547    TValuefields;
548    struct Node *next;  /* for chaining */
549  } nk;
550  TValue tvk;
551} TKey;
552
553
554typedef struct Node {
555  TValue i_val;
556  TKey i_key;
557} Node;
558
559
560typedef struct Table {
561  CommonHeader;
562  lu_byte flags;  /* 1<<p means tagmethod(p) is not present */
563  lu_byte lsizenode;  /* log2 of size of `node' array */
564  struct Table *metatable;
565  TValue *array;  /* array part */
566  Node *node;
567  Node *lastfree;  /* any free position is before this position */
568  GCObject *gclist;
569  int sizearray;  /* size of `array' array */
570} Table;
571
572
573
574/*
575** `module' operation for hashing (size is always a power of 2)
576*/
577#define lmod(s,size) \
578   (check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1)))))
579
580
581#define twoto(x)   (1<<(x))
582#define sizenode(t)   (twoto((t)->lsizenode))
583
584
585/*
586** (address of) a fixed nil value
587*/
588#define luaO_nilobject      (&luaO_nilobject_)
589
590
591LUAI_DDEC const TValue luaO_nilobject_;
592
593
594LUAI_FUNC int luaO_int2fb (unsigned int x);
595LUAI_FUNC int luaO_fb2int (int x);
596LUAI_FUNC int luaO_ceillog2 (unsigned int x);
597LUAI_FUNC lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2);
598LUAI_FUNC int luaO_str2d (const char *s, size_t len, lua_Number *result);
599LUAI_FUNC int luaO_hexavalue (int c);
600LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
601                                                       va_list argp);
602LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
603LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
604
605
606#endif
607
Property changes on: trunk/src/lib/lua/lobject.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lstring.h
r0r22721
1/*
2** $Id: lstring.h,v 1.49 2012/02/01 21:57:15 roberto Exp $
3** String table (keep all strings handled by Lua)
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lstring_h
8#define lstring_h
9
10#include "lgc.h"
11#include "lobject.h"
12#include "lstate.h"
13
14
15#define sizestring(s)   (sizeof(union TString)+((s)->len+1)*sizeof(char))
16
17#define sizeudata(u)   (sizeof(union Udata)+(u)->len)
18
19#define luaS_newliteral(L, s)   (luaS_newlstr(L, "" s, \
20                                 (sizeof(s)/sizeof(char))-1))
21
22#define luaS_fix(s)   l_setbit((s)->tsv.marked, FIXEDBIT)
23
24
25/*
26** test whether a string is a reserved word
27*/
28#define isreserved(s)   ((s)->tsv.tt == LUA_TSHRSTR && (s)->tsv.extra > 0)
29
30
31/*
32** equality for short strings, which are always internalized
33*/
34#define eqshrstr(a,b)   check_exp((a)->tsv.tt == LUA_TSHRSTR, (a) == (b))
35
36
37LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);
38LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b);
39LUAI_FUNC int luaS_eqstr (TString *a, TString *b);
40LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
41LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
42LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
43LUAI_FUNC TString *luaS_new (lua_State *L, const char *str);
44
45
46#endif
Property changes on: trunk/src/lib/lua/lstring.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/ldblib.c
r0r22721
1/*
2** $Id: ldblib.c,v 1.132 2012/01/19 20:14:44 roberto Exp $
3** Interface from Lua to its debug API
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#define ldblib_c
13#define LUA_LIB
14
15#include "lua.h"
16
17#include "lauxlib.h"
18#include "lualib.h"
19
20
21#define HOOKKEY      "_HKEY"
22
23
24
25static int db_getregistry (lua_State *L) {
26  lua_pushvalue(L, LUA_REGISTRYINDEX);
27  return 1;
28}
29
30
31static int db_getmetatable (lua_State *L) {
32  luaL_checkany(L, 1);
33  if (!lua_getmetatable(L, 1)) {
34    lua_pushnil(L);  /* no metatable */
35  }
36  return 1;
37}
38
39
40static int db_setmetatable (lua_State *L) {
41  int t = lua_type(L, 2);
42  luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
43                    "nil or table expected");
44  lua_settop(L, 2);
45  lua_setmetatable(L, 1);
46  return 1;  /* return 1st argument */
47}
48
49
50static int db_getuservalue (lua_State *L) {
51  if (lua_type(L, 1) != LUA_TUSERDATA)
52    lua_pushnil(L);
53  else
54    lua_getuservalue(L, 1);
55  return 1;
56}
57
58
59static int db_setuservalue (lua_State *L) {
60  if (lua_type(L, 1) == LUA_TLIGHTUSERDATA)
61    luaL_argerror(L, 1, "full userdata expected, got light userdata");
62  luaL_checktype(L, 1, LUA_TUSERDATA);
63  if (!lua_isnoneornil(L, 2))
64    luaL_checktype(L, 2, LUA_TTABLE);
65  lua_settop(L, 2);
66  lua_setuservalue(L, 1);
67  return 1;
68}
69
70
71static void settabss (lua_State *L, const char *i, const char *v) {
72  lua_pushstring(L, v);
73  lua_setfield(L, -2, i);
74}
75
76
77static void settabsi (lua_State *L, const char *i, int v) {
78  lua_pushinteger(L, v);
79  lua_setfield(L, -2, i);
80}
81
82
83static void settabsb (lua_State *L, const char *i, int v) {
84  lua_pushboolean(L, v);
85  lua_setfield(L, -2, i);
86}
87
88
89static lua_State *getthread (lua_State *L, int *arg) {
90  if (lua_isthread(L, 1)) {
91    *arg = 1;
92    return lua_tothread(L, 1);
93  }
94  else {
95    *arg = 0;
96    return L;
97  }
98}
99
100
101static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
102  if (L == L1) {
103    lua_pushvalue(L, -2);
104    lua_remove(L, -3);
105  }
106  else
107    lua_xmove(L1, L, 1);
108  lua_setfield(L, -2, fname);
109}
110
111
112static int db_getinfo (lua_State *L) {
113  lua_Debug ar;
114  int arg;
115  lua_State *L1 = getthread(L, &arg);
116  const char *options = luaL_optstring(L, arg+2, "flnStu");
117  if (lua_isnumber(L, arg+1)) {
118    if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) {
119      lua_pushnil(L);  /* level out of range */
120      return 1;
121    }
122  }
123  else if (lua_isfunction(L, arg+1)) {
124    lua_pushfstring(L, ">%s", options);
125    options = lua_tostring(L, -1);
126    lua_pushvalue(L, arg+1);
127    lua_xmove(L, L1, 1);
128  }
129  else
130    return luaL_argerror(L, arg+1, "function or level expected");
131  if (!lua_getinfo(L1, options, &ar))
132    return luaL_argerror(L, arg+2, "invalid option");
133  lua_createtable(L, 0, 2);
134  if (strchr(options, 'S')) {
135    settabss(L, "source", ar.source);
136    settabss(L, "short_src", ar.short_src);
137    settabsi(L, "linedefined", ar.linedefined);
138    settabsi(L, "lastlinedefined", ar.lastlinedefined);
139    settabss(L, "what", ar.what);
140  }
141  if (strchr(options, 'l'))
142    settabsi(L, "currentline", ar.currentline);
143  if (strchr(options, 'u')) {
144    settabsi(L, "nups", ar.nups);
145    settabsi(L, "nparams", ar.nparams);
146    settabsb(L, "isvararg", ar.isvararg);
147  }
148  if (strchr(options, 'n')) {
149    settabss(L, "name", ar.name);
150    settabss(L, "namewhat", ar.namewhat);
151  }
152  if (strchr(options, 't'))
153    settabsb(L, "istailcall", ar.istailcall);
154  if (strchr(options, 'L'))
155    treatstackoption(L, L1, "activelines");
156  if (strchr(options, 'f'))
157    treatstackoption(L, L1, "func");
158  return 1;  /* return table */
159}
160
161
162static int db_getlocal (lua_State *L) {
163  int arg;
164  lua_State *L1 = getthread(L, &arg);
165  lua_Debug ar;
166  const char *name;
167  int nvar = luaL_checkint(L, arg+2);  /* local-variable index */
168  if (lua_isfunction(L, arg + 1)) {  /* function argument? */
169    lua_pushvalue(L, arg + 1);  /* push function */
170    lua_pushstring(L, lua_getlocal(L, NULL, nvar));  /* push local name */
171    return 1;
172  }
173  else {  /* stack-level argument */
174    if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar))  /* out of range? */
175      return luaL_argerror(L, arg+1, "level out of range");
176    name = lua_getlocal(L1, &ar, nvar);
177    if (name) {
178      lua_xmove(L1, L, 1);  /* push local value */
179      lua_pushstring(L, name);  /* push name */
180      lua_pushvalue(L, -2);  /* re-order */
181      return 2;
182    }
183    else {
184      lua_pushnil(L);  /* no name (nor value) */
185      return 1;
186    }
187  }
188}
189
190
191static int db_setlocal (lua_State *L) {
192  int arg;
193  lua_State *L1 = getthread(L, &arg);
194  lua_Debug ar;
195  if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar))  /* out of range? */
196    return luaL_argerror(L, arg+1, "level out of range");
197  luaL_checkany(L, arg+3);
198  lua_settop(L, arg+3);
199  lua_xmove(L, L1, 1);
200  lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2)));
201  return 1;
202}
203
204
205static int auxupvalue (lua_State *L, int get) {
206  const char *name;
207  int n = luaL_checkint(L, 2);
208  luaL_checktype(L, 1, LUA_TFUNCTION);
209  name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
210  if (name == NULL) return 0;
211  lua_pushstring(L, name);
212  lua_insert(L, -(get+1));
213  return get + 1;
214}
215
216
217static int db_getupvalue (lua_State *L) {
218  return auxupvalue(L, 1);
219}
220
221
222static int db_setupvalue (lua_State *L) {
223  luaL_checkany(L, 3);
224  return auxupvalue(L, 0);
225}
226
227
228static int checkupval (lua_State *L, int argf, int argnup) {
229  lua_Debug ar;
230  int nup = luaL_checkint(L, argnup);
231  luaL_checktype(L, argf, LUA_TFUNCTION);
232  lua_pushvalue(L, argf);
233  lua_getinfo(L, ">u", &ar);
234  luaL_argcheck(L, 1 <= nup && nup <= ar.nups, argnup, "invalid upvalue index");
235  return nup;
236}
237
238
239static int db_upvalueid (lua_State *L) {
240  int n = checkupval(L, 1, 2);
241  lua_pushlightuserdata(L, lua_upvalueid(L, 1, n));
242  return 1;
243}
244
245
246static int db_upvaluejoin (lua_State *L) {
247  int n1 = checkupval(L, 1, 2);
248  int n2 = checkupval(L, 3, 4);
249  luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected");
250  luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected");
251  lua_upvaluejoin(L, 1, n1, 3, n2);
252  return 0;
253}
254
255
256#define gethooktable(L)   luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY)
257
258
259static void hookf (lua_State *L, lua_Debug *ar) {
260  static const char *const hooknames[] =
261    {"call", "return", "line", "count", "tail call"};
262  gethooktable(L);
263  lua_pushthread(L);
264  lua_rawget(L, -2);
265  if (lua_isfunction(L, -1)) {
266    lua_pushstring(L, hooknames[(int)ar->event]);
267    if (ar->currentline >= 0)
268      lua_pushinteger(L, ar->currentline);
269    else lua_pushnil(L);
270    lua_assert(lua_getinfo(L, "lS", ar));
271    lua_call(L, 2, 0);
272  }
273}
274
275
276static int makemask (const char *smask, int count) {
277  int mask = 0;
278  if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
279  if (strchr(smask, 'r')) mask |= LUA_MASKRET;
280  if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
281  if (count > 0) mask |= LUA_MASKCOUNT;
282  return mask;
283}
284
285
286static char *unmakemask (int mask, char *smask) {
287  int i = 0;
288  if (mask & LUA_MASKCALL) smask[i++] = 'c';
289  if (mask & LUA_MASKRET) smask[i++] = 'r';
290  if (mask & LUA_MASKLINE) smask[i++] = 'l';
291  smask[i] = '\0';
292  return smask;
293}
294
295
296static int db_sethook (lua_State *L) {
297  int arg, mask, count;
298  lua_Hook func;
299  lua_State *L1 = getthread(L, &arg);
300  if (lua_isnoneornil(L, arg+1)) {
301    lua_settop(L, arg+1);
302    func = NULL; mask = 0; count = 0;  /* turn off hooks */
303  }
304  else {
305    const char *smask = luaL_checkstring(L, arg+2);
306    luaL_checktype(L, arg+1, LUA_TFUNCTION);
307    count = luaL_optint(L, arg+3, 0);
308    func = hookf; mask = makemask(smask, count);
309  }
310  if (gethooktable(L) == 0) {  /* creating hook table? */
311    lua_pushstring(L, "k");
312    lua_setfield(L, -2, "__mode");  /** hooktable.__mode = "k" */
313    lua_pushvalue(L, -1);
314    lua_setmetatable(L, -2);  /* setmetatable(hooktable) = hooktable */
315  }
316  lua_pushthread(L1); lua_xmove(L1, L, 1);
317  lua_pushvalue(L, arg+1);
318  lua_rawset(L, -3);  /* set new hook */
319  lua_sethook(L1, func, mask, count);  /* set hooks */
320  return 0;
321}
322
323
324static int db_gethook (lua_State *L) {
325  int arg;
326  lua_State *L1 = getthread(L, &arg);
327  char buff[5];
328  int mask = lua_gethookmask(L1);
329  lua_Hook hook = lua_gethook(L1);
330  if (hook != NULL && hook != hookf)  /* external hook? */
331    lua_pushliteral(L, "external hook");
332  else {
333    gethooktable(L);
334    lua_pushthread(L1); lua_xmove(L1, L, 1);
335    lua_rawget(L, -2);   /* get hook */
336    lua_remove(L, -2);  /* remove hook table */
337  }
338  lua_pushstring(L, unmakemask(mask, buff));
339  lua_pushinteger(L, lua_gethookcount(L1));
340  return 3;
341}
342
343
344static int db_debug (lua_State *L) {
345  for (;;) {
346    char buffer[250];
347    luai_writestringerror("%s", "lua_debug> ");
348    if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
349        strcmp(buffer, "cont\n") == 0)
350      return 0;
351    if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
352        lua_pcall(L, 0, 0, 0))
353      luai_writestringerror("%s\n", lua_tostring(L, -1));
354    lua_settop(L, 0);  /* remove eventual returns */
355  }
356}
357
358
359static int db_traceback (lua_State *L) {
360  int arg;
361  lua_State *L1 = getthread(L, &arg);
362  const char *msg = lua_tostring(L, arg + 1);
363  if (msg == NULL && !lua_isnoneornil(L, arg + 1))  /* non-string 'msg'? */
364    lua_pushvalue(L, arg + 1);  /* return it untouched */
365  else {
366    int level = luaL_optint(L, arg + 2, (L == L1) ? 1 : 0);
367    luaL_traceback(L, L1, msg, level);
368  }
369  return 1;
370}
371
372
373static const luaL_Reg dblib[] = {
374  {"debug", db_debug},
375  {"getuservalue", db_getuservalue},
376  {"gethook", db_gethook},
377  {"getinfo", db_getinfo},
378  {"getlocal", db_getlocal},
379  {"getregistry", db_getregistry},
380  {"getmetatable", db_getmetatable},
381  {"getupvalue", db_getupvalue},
382  {"upvaluejoin", db_upvaluejoin},
383  {"upvalueid", db_upvalueid},
384  {"setuservalue", db_setuservalue},
385  {"sethook", db_sethook},
386  {"setlocal", db_setlocal},
387  {"setmetatable", db_setmetatable},
388  {"setupvalue", db_setupvalue},
389  {"traceback", db_traceback},
390  {NULL, NULL}
391};
392
393
394LUAMOD_API int luaopen_debug (lua_State *L) {
395  luaL_newlib(L, dblib);
396  return 1;
397}
398
Property changes on: trunk/src/lib/lua/ldblib.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/lmem.c
r0r22721
1/*
2** $Id: lmem.c,v 1.84 2012/05/23 15:41:53 roberto Exp $
3** Interface to Memory Manager
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stddef.h>
9
10#define lmem_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "ldebug.h"
16#include "ldo.h"
17#include "lgc.h"
18#include "lmem.h"
19#include "lobject.h"
20#include "lstate.h"
21
22
23
24/*
25** About the realloc function:
26** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
27** (`osize' is the old size, `nsize' is the new size)
28**
29** * frealloc(ud, NULL, x, s) creates a new block of size `s' (no
30** matter 'x').
31**
32** * frealloc(ud, p, x, 0) frees the block `p'
33** (in this specific case, frealloc must return NULL);
34** particularly, frealloc(ud, NULL, 0, 0) does nothing
35** (which is equivalent to free(NULL) in ANSI C)
36**
37** frealloc returns NULL if it cannot create or reallocate the area
38** (any reallocation to an equal or smaller size cannot fail!)
39*/
40
41
42
43#define MINSIZEARRAY   4
44
45
46void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
47                     int limit, const char *what) {
48  void *newblock;
49  int newsize;
50  if (*size >= limit/2) {  /* cannot double it? */
51    if (*size >= limit)  /* cannot grow even a little? */
52      luaG_runerror(L, "too many %s (limit is %d)", what, limit);
53    newsize = limit;  /* still have at least one free place */
54  }
55  else {
56    newsize = (*size)*2;
57    if (newsize < MINSIZEARRAY)
58      newsize = MINSIZEARRAY;  /* minimum size */
59  }
60  newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
61  *size = newsize;  /* update only when everything else is OK */
62  return newblock;
63}
64
65
66l_noret luaM_toobig (lua_State *L) {
67  luaG_runerror(L, "memory allocation error: block too big");
68}
69
70
71
72/*
73** generic allocation routine.
74*/
75void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
76  void *newblock;
77  global_State *g = G(L);
78  size_t realosize = (block) ? osize : 0;
79  lua_assert((realosize == 0) == (block == NULL));
80#if defined(HARDMEMTESTS)
81  if (nsize > realosize && g->gcrunning)
82    luaC_fullgc(L, 1);  /* force a GC whenever possible */
83#endif
84  newblock = (*g->frealloc)(g->ud, block, osize, nsize);
85  if (newblock == NULL && nsize > 0) {
86    api_check(L, nsize > realosize,
87                 "realloc cannot fail when shrinking a block");
88    if (g->gcrunning) {
89      luaC_fullgc(L, 1);  /* try to free some memory... */
90      newblock = (*g->frealloc)(g->ud, block, osize, nsize);  /* try again */
91    }
92    if (newblock == NULL)
93      luaD_throw(L, LUA_ERRMEM);
94  }
95  lua_assert((nsize == 0) == (newblock == NULL));
96  g->GCdebt = (g->GCdebt + nsize) - realosize;
97  return newblock;
98}
99
Property changes on: trunk/src/lib/lua/lmem.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/lcode.h
r0r22721
1/*
2** $Id: lcode.h,v 1.58 2011/08/30 16:26:41 roberto Exp $
3** Code generator for Lua
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lcode_h
8#define lcode_h
9
10#include "llex.h"
11#include "lobject.h"
12#include "lopcodes.h"
13#include "lparser.h"
14
15
16/*
17** Marks the end of a patch list. It is an invalid value both as an absolute
18** address, and as a list link (would link an element to itself).
19*/
20#define NO_JUMP (-1)
21
22
23/*
24** grep "ORDER OPR" if you change these enums  (ORDER OP)
25*/
26typedef enum BinOpr {
27  OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
28  OPR_CONCAT,
29  OPR_EQ, OPR_LT, OPR_LE,
30  OPR_NE, OPR_GT, OPR_GE,
31  OPR_AND, OPR_OR,
32  OPR_NOBINOPR
33} BinOpr;
34
35
36typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
37
38
39#define getcode(fs,e)   ((fs)->f->code[(e)->u.info])
40
41#define luaK_codeAsBx(fs,o,A,sBx)   luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
42
43#define luaK_setmultret(fs,e)   luaK_setreturns(fs, e, LUA_MULTRET)
44
45#define luaK_jumpto(fs,t)   luaK_patchlist(fs, luaK_jump(fs), t)
46
47LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
48LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
49LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k);
50LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
51LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
52LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
53LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
54LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
55LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
56LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
57LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
58LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);
59LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
60LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
61LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
62LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
63LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
64LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
65LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e);
66LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
67LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
68LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
69LUAI_FUNC int luaK_jump (FuncState *fs);
70LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
71LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
72LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
73LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level);
74LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
75LUAI_FUNC int luaK_getlabel (FuncState *fs);
76LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line);
77LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
78LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1,
79                            expdesc *v2, int line);
80LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
81
82
83#endif
Property changes on: trunk/src/lib/lua/lcode.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lstate.c
r0r22721
1/*
2** $Id: lstate.c,v 2.99 2012/10/02 17:40:53 roberto Exp $
3** Global State
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stddef.h>
9#include <string.h>
10
11#define lstate_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 "llex.h"
22#include "lmem.h"
23#include "lstate.h"
24#include "lstring.h"
25#include "ltable.h"
26#include "ltm.h"
27
28
29#if !defined(LUAI_GCPAUSE)
30#define LUAI_GCPAUSE   200  /* 200% */
31#endif
32
33#if !defined(LUAI_GCMAJOR)
34#define LUAI_GCMAJOR   200  /* 200% */
35#endif
36
37#if !defined(LUAI_GCMUL)
38#define LUAI_GCMUL   200 /* GC runs 'twice the speed' of memory allocation */
39#endif
40
41
42#define MEMERRMSG   "not enough memory"
43
44
45/*
46** a macro to help the creation of a unique random seed when a state is
47** created; the seed is used to randomize hashes.
48*/
49#if !defined(luai_makeseed)
50#include <time.h>
51#define luai_makeseed()      cast(unsigned int, time(NULL))
52#endif
53
54
55
56/*
57** thread state + extra space
58*/
59typedef struct LX {
60#if defined(LUAI_EXTRASPACE)
61  char buff[LUAI_EXTRASPACE];
62#endif
63  lua_State l;
64} LX;
65
66
67/*
68** Main thread combines a thread state and the global state
69*/
70typedef struct LG {
71  LX l;
72  global_State g;
73} LG;
74
75
76
77#define fromstate(L)   (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))
78
79
80/*
81** Compute an initial seed as random as possible. In ANSI, rely on
82** Address Space Layout Randomization (if present) to increase
83** randomness..
84*/
85#define addbuff(b,p,e) \
86  { size_t t = cast(size_t, e); \
87    memcpy(buff + p, &t, sizeof(t)); p += sizeof(t); }
88
89static unsigned int makeseed (lua_State *L) {
90  char buff[4 * sizeof(size_t)];
91  unsigned int h = luai_makeseed();
92  int p = 0;
93  addbuff(buff, p, L);  /* heap variable */
94  addbuff(buff, p, &h);  /* local variable */
95  addbuff(buff, p, luaO_nilobject);  /* global variable */
96  addbuff(buff, p, &lua_newstate);  /* public function */
97  lua_assert(p == sizeof(buff));
98  return luaS_hash(buff, p, h);
99}
100
101
102/*
103** set GCdebt to a new value keeping the value (totalbytes + GCdebt)
104** invariant
105*/
106void luaE_setdebt (global_State *g, l_mem debt) {
107  g->totalbytes -= (debt - g->GCdebt);
108  g->GCdebt = debt;
109}
110
111
112CallInfo *luaE_extendCI (lua_State *L) {
113  CallInfo *ci = luaM_new(L, CallInfo);
114  lua_assert(L->ci->next == NULL);
115  L->ci->next = ci;
116  ci->previous = L->ci;
117  ci->next = NULL;
118  return ci;
119}
120
121
122void luaE_freeCI (lua_State *L) {
123  CallInfo *ci = L->ci;
124  CallInfo *next = ci->next;
125  ci->next = NULL;
126  while ((ci = next) != NULL) {
127    next = ci->next;
128    luaM_free(L, ci);
129  }
130}
131
132
133static void stack_init (lua_State *L1, lua_State *L) {
134  int i; CallInfo *ci;
135  /* initialize stack array */
136  L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue);
137  L1->stacksize = BASIC_STACK_SIZE;
138  for (i = 0; i < BASIC_STACK_SIZE; i++)
139    setnilvalue(L1->stack + i);  /* erase new stack */
140  L1->top = L1->stack;
141  L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
142  /* initialize first ci */
143  ci = &L1->base_ci;
144  ci->next = ci->previous = NULL;
145  ci->callstatus = 0;
146  ci->func = L1->top;
147  setnilvalue(L1->top++);  /* 'function' entry for this 'ci' */
148  ci->top = L1->top + LUA_MINSTACK;
149  L1->ci = ci;
150}
151
152
153static void freestack (lua_State *L) {
154  if (L->stack == NULL)
155    return;  /* stack not completely built yet */
156  L->ci = &L->base_ci;  /* free the entire 'ci' list */
157  luaE_freeCI(L);
158  luaM_freearray(L, L->stack, L->stacksize);  /* free stack array */
159}
160
161
162/*
163** Create registry table and its predefined values
164*/
165static void init_registry (lua_State *L, global_State *g) {
166  TValue mt;
167  /* create registry */
168  Table *registry = luaH_new(L);
169  sethvalue(L, &g->l_registry, registry);
170  luaH_resize(L, registry, LUA_RIDX_LAST, 0);
171  /* registry[LUA_RIDX_MAINTHREAD] = L */
172  setthvalue(L, &mt, L);
173  luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt);
174  /* registry[LUA_RIDX_GLOBALS] = table of globals */
175  sethvalue(L, &mt, luaH_new(L));
176  luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt);
177}
178
179
180/*
181** open parts of the state that may cause memory-allocation errors
182*/
183static void f_luaopen (lua_State *L, void *ud) {
184  global_State *g = G(L);
185  UNUSED(ud);
186  stack_init(L, L);  /* init stack */
187  init_registry(L, g);
188  luaS_resize(L, MINSTRTABSIZE);  /* initial size of string table */
189  luaT_init(L);
190  luaX_init(L);
191  /* pre-create memory-error message */
192  g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
193  luaS_fix(g->memerrmsg);  /* it should never be collected */
194  g->gcrunning = 1;  /* allow gc */
195}
196
197
198/*
199** preinitialize a state with consistent values without allocating
200** any memory (to avoid errors)
201*/
202static void preinit_state (lua_State *L, global_State *g) {
203  G(L) = g;
204  L->stack = NULL;
205  L->ci = NULL;
206  L->stacksize = 0;
207  L->errorJmp = NULL;
208  L->nCcalls = 0;
209  L->hook = NULL;
210  L->hookmask = 0;
211  L->basehookcount = 0;
212  L->allowhook = 1;
213  resethookcount(L);
214  L->openupval = NULL;
215  L->nny = 1;
216  L->status = LUA_OK;
217  L->errfunc = 0;
218}
219
220
221static void close_state (lua_State *L) {
222  global_State *g = G(L);
223  luaF_close(L, L->stack);  /* close all upvalues for this thread */
224  luaC_freeallobjects(L);  /* collect all objects */
225  luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
226  luaZ_freebuffer(L, &g->buff);
227  freestack(L);
228  lua_assert(gettotalbytes(g) == sizeof(LG));
229  (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0);  /* free main block */
230}
231
232
233LUA_API lua_State *lua_newthread (lua_State *L) {
234  lua_State *L1;
235  lua_lock(L);
236  luaC_checkGC(L);
237  L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th;
238  setthvalue(L, L->top, L1);
239  api_incr_top(L);
240  preinit_state(L1, G(L));
241  L1->hookmask = L->hookmask;
242  L1->basehookcount = L->basehookcount;
243  L1->hook = L->hook;
244  resethookcount(L1);
245  luai_userstatethread(L, L1);
246  stack_init(L1, L);  /* init stack */
247  lua_unlock(L);
248  return L1;
249}
250
251
252void luaE_freethread (lua_State *L, lua_State *L1) {
253  LX *l = fromstate(L1);
254  luaF_close(L1, L1->stack);  /* close all upvalues for this thread */
255  lua_assert(L1->openupval == NULL);
256  luai_userstatefree(L, L1);
257  freestack(L1);
258  luaM_free(L, l);
259}
260
261
262LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
263  int i;
264  lua_State *L;
265  global_State *g;
266  LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG)));
267  if (l == NULL) return NULL;
268  L = &l->l.l;
269  g = &l->g;
270  L->next = NULL;
271  L->tt = LUA_TTHREAD;
272  g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
273  L->marked = luaC_white(g);
274  g->gckind = KGC_NORMAL;
275  preinit_state(L, g);
276  g->frealloc = f;
277  g->ud = ud;
278  g->mainthread = L;
279  g->seed = makeseed(L);
280  g->uvhead.u.l.prev = &g->uvhead;
281  g->uvhead.u.l.next = &g->uvhead;
282  g->gcrunning = 0;  /* no GC while building state */
283  g->GCestimate = 0;
284  g->strt.size = 0;
285  g->strt.nuse = 0;
286  g->strt.hash = NULL;
287  setnilvalue(&g->l_registry);
288  luaZ_initbuffer(L, &g->buff);
289  g->panic = NULL;
290  g->version = lua_version(NULL);
291  g->gcstate = GCSpause;
292  g->allgc = NULL;
293  g->finobj = NULL;
294  g->tobefnz = NULL;
295  g->sweepgc = g->sweepfin = NULL;
296  g->gray = g->grayagain = NULL;
297  g->weak = g->ephemeron = g->allweak = NULL;
298  g->totalbytes = sizeof(LG);
299  g->GCdebt = 0;
300  g->gcpause = LUAI_GCPAUSE;
301  g->gcmajorinc = LUAI_GCMAJOR;
302  g->gcstepmul = LUAI_GCMUL;
303  for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
304  if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
305    /* memory allocation error: free partial state */
306    close_state(L);
307    L = NULL;
308  }
309  else
310    luai_userstateopen(L);
311  return L;
312}
313
314
315LUA_API void lua_close (lua_State *L) {
316  L = G(L)->mainthread;  /* only the main thread can be closed */
317  lua_lock(L);
318  luai_userstateclose(L);
319  close_state(L);
320}
321
322
Property changes on: trunk/src/lib/lua/lstate.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/Makefile
r0r22721
1# Makefile for building Lua
2# See ../doc/readme.html for installation and customization instructions.
3
4# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
5
6# Your platform. See PLATS for possible values.
7PLAT= none
8
9CC= gcc
10CFLAGS= -O2 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS)
11LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
12LIBS= -lm $(SYSLIBS) $(MYLIBS)
13
14AR= ar rcu
15RANLIB= ranlib
16RM= rm -f
17
18SYSCFLAGS=
19SYSLDFLAGS=
20SYSLIBS=
21
22MYCFLAGS=
23MYLDFLAGS=
24MYLIBS=
25MYOBJS=
26
27# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
28
29PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris
30
31LUA_A=   liblua.a
32CORE_O=   lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \
33   lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \
34   ltm.o lundump.o lvm.o lzio.o
35LIB_O=   lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \
36   lmathlib.o loslib.o lstrlib.o ltablib.o loadlib.o linit.o
37BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS)
38
39LUA_T=   lua
40LUA_O=   lua.o
41
42LUAC_T=   luac
43LUAC_O=   luac.o
44
45ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O)
46ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T)
47ALL_A= $(LUA_A)
48
49# Targets start here.
50default: $(PLAT)
51
52all:   $(ALL_T)
53
54o:   $(ALL_O)
55
56a:   $(ALL_A)
57
58$(LUA_A): $(BASE_O)
59   $(AR) $@ $(BASE_O)
60   $(RANLIB) $@
61
62$(LUA_T): $(LUA_O) $(LUA_A)
63   $(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
64
65$(LUAC_T): $(LUAC_O) $(LUA_A)
66   $(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS)
67
68clean:
69   $(RM) $(ALL_T) $(ALL_O)
70
71depend:
72   @$(CC) $(CFLAGS) -MM l*.c
73
74echo:
75   @echo "PLAT= $(PLAT)"
76   @echo "CC= $(CC)"
77   @echo "CFLAGS= $(CFLAGS)"
78   @echo "LDFLAGS= $(SYSLDFLAGS)"
79   @echo "LIBS= $(LIBS)"
80   @echo "AR= $(AR)"
81   @echo "RANLIB= $(RANLIB)"
82   @echo "RM= $(RM)"
83
84# Convenience targets for popular platforms
85ALL= all
86
87none:
88   @echo "Please do 'make PLATFORM' where PLATFORM is one of these:"
89   @echo "   $(PLATS)"
90
91aix:
92   $(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall"
93
94ansi:
95   $(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI"
96
97bsd:
98   $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E"
99
100freebsd:
101   $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -lreadline"
102
103generic: $(ALL)
104
105linux:
106   $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"
107
108macosx:
109   $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline"
110
111mingw:
112   $(MAKE) "LUA_A=lua52.dll" "LUA_T=lua.exe" \
113   "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \
114   "SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe
115   $(MAKE) "LUAC_T=luac.exe" luac.exe
116
117posix:
118   $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX"
119
120solaris:
121   $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl"
122
123# list targets that do not create files (but not all makes understand .PHONY)
124.PHONY: all $(PLATS) default o a clean depend echo none
125
126# DO NOT DELETE
127
128lapi.o: lapi.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \
129 lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h ltable.h lundump.h \
130 lvm.h
131lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h
132lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h
133lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h
134lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \
135 lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \
136 lstring.h ltable.h lvm.h
137lcorolib.o: lcorolib.c lua.h luaconf.h lauxlib.h lualib.h
138lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h
139ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h
140ldebug.o: ldebug.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \
141 ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h ldebug.h ldo.h \
142 lfunc.h lstring.h lgc.h ltable.h lvm.h
143ldo.o: ldo.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \
144 lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h \
145 lstring.h ltable.h lundump.h lvm.h
146ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \
147 lzio.h lmem.h lundump.h
148lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h \
149 lstate.h ltm.h lzio.h lmem.h
150lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
151 lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
152linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h
153liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h
154llex.o: llex.c lua.h luaconf.h lctype.h llimits.h ldo.h lobject.h \
155 lstate.h ltm.h lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h
156lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h
157lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
158 ltm.h lzio.h lmem.h ldo.h lgc.h
159loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h
160lobject.o: lobject.c lua.h luaconf.h lctype.h llimits.h ldebug.h lstate.h \
161 lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h lvm.h
162lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h
163loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h
164lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \
165 lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lfunc.h \
166 lstring.h lgc.h ltable.h
167lstate.o: lstate.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \
168 ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h lstring.h \
169 ltable.h
170lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \
171 ltm.h lzio.h lstring.h lgc.h
172lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h
173ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
174 ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h
175ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h
176ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \
177 lmem.h lstring.h lgc.h ltable.h
178lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h
179luac.o: luac.c lua.h luaconf.h lauxlib.h lobject.h llimits.h lstate.h \
180 ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h
181lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \
182 llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h
183lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
184 lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h
185lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \
186 lzio.h
187
Property changes on: trunk/src/lib/lua/Makefile
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/lmathlib.c
r0r22721
1/*
2** $Id: lmathlib.c,v 1.83 2013/03/07 18:21:32 roberto Exp $
3** Standard mathematical library
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdlib.h>
9#include <math.h>
10
11#define lmathlib_c
12#define LUA_LIB
13
14#include "lua.h"
15
16#include "lauxlib.h"
17#include "lualib.h"
18
19
20#undef PI
21#define PI   ((lua_Number)(3.1415926535897932384626433832795))
22#define RADIANS_PER_DEGREE   ((lua_Number)(PI/180.0))
23
24
25
26static int math_abs (lua_State *L) {
27  lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1)));
28  return 1;
29}
30
31static int math_sin (lua_State *L) {
32  lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1)));
33  return 1;
34}
35
36static int math_sinh (lua_State *L) {
37  lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1)));
38  return 1;
39}
40
41static int math_cos (lua_State *L) {
42  lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1)));
43  return 1;
44}
45
46static int math_cosh (lua_State *L) {
47  lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1)));
48  return 1;
49}
50
51static int math_tan (lua_State *L) {
52  lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1)));
53  return 1;
54}
55
56static int math_tanh (lua_State *L) {
57  lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1)));
58  return 1;
59}
60
61static int math_asin (lua_State *L) {
62  lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1)));
63  return 1;
64}
65
66static int math_acos (lua_State *L) {
67  lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1)));
68  return 1;
69}
70
71static int math_atan (lua_State *L) {
72  lua_pushnumber(L, l_mathop(atan)(luaL_checknumber(L, 1)));
73  return 1;
74}
75
76static int math_atan2 (lua_State *L) {
77  lua_pushnumber(L, l_mathop(atan2)(luaL_checknumber(L, 1),
78                                luaL_checknumber(L, 2)));
79  return 1;
80}
81
82static int math_ceil (lua_State *L) {
83  lua_pushnumber(L, l_mathop(ceil)(luaL_checknumber(L, 1)));
84  return 1;
85}
86
87static int math_floor (lua_State *L) {
88  lua_pushnumber(L, l_mathop(floor)(luaL_checknumber(L, 1)));
89  return 1;
90}
91
92static int math_fmod (lua_State *L) {
93  lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1),
94                               luaL_checknumber(L, 2)));
95  return 1;
96}
97
98static int math_modf (lua_State *L) {
99  lua_Number ip;
100  lua_Number fp = l_mathop(modf)(luaL_checknumber(L, 1), &ip);
101  lua_pushnumber(L, ip);
102  lua_pushnumber(L, fp);
103  return 2;
104}
105
106static int math_sqrt (lua_State *L) {
107  lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1)));
108  return 1;
109}
110
111static int math_pow (lua_State *L) {
112  lua_Number x = luaL_checknumber(L, 1);
113  lua_Number y = luaL_checknumber(L, 2);
114  lua_pushnumber(L, l_mathop(pow)(x, y));
115  return 1;
116}
117
118static int math_log (lua_State *L) {
119  lua_Number x = luaL_checknumber(L, 1);
120  lua_Number res;
121  if (lua_isnoneornil(L, 2))
122    res = l_mathop(log)(x);
123  else {
124    lua_Number base = luaL_checknumber(L, 2);
125    if (base == (lua_Number)10.0) res = l_mathop(log10)(x);
126    else res = l_mathop(log)(x)/l_mathop(log)(base);
127  }
128  lua_pushnumber(L, res);
129  return 1;
130}
131
132#if defined(LUA_COMPAT_LOG10)
133static int math_log10 (lua_State *L) {
134  lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1)));
135  return 1;
136}
137#endif
138
139static int math_exp (lua_State *L) {
140  lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1)));
141  return 1;
142}
143
144static int math_deg (lua_State *L) {
145  lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
146  return 1;
147}
148
149static int math_rad (lua_State *L) {
150  lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
151  return 1;
152}
153
154static int math_frexp (lua_State *L) {
155  int e;
156  lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e));
157  lua_pushinteger(L, e);
158  return 2;
159}
160
161static int math_ldexp (lua_State *L) {
162  lua_Number x = luaL_checknumber(L, 1);
163  int ep = luaL_checkint(L, 2);
164  lua_pushnumber(L, l_mathop(ldexp)(x, ep));
165  return 1;
166}
167
168
169
170static int math_min (lua_State *L) {
171  int n = lua_gettop(L);  /* number of arguments */
172  lua_Number dmin = luaL_checknumber(L, 1);
173  int i;
174  for (i=2; i<=n; i++) {
175    lua_Number d = luaL_checknumber(L, i);
176    if (d < dmin)
177      dmin = d;
178  }
179  lua_pushnumber(L, dmin);
180  return 1;
181}
182
183
184static int math_max (lua_State *L) {
185  int n = lua_gettop(L);  /* number of arguments */
186  lua_Number dmax = luaL_checknumber(L, 1);
187  int i;
188  for (i=2; i<=n; i++) {
189    lua_Number d = luaL_checknumber(L, i);
190    if (d > dmax)
191      dmax = d;
192  }
193  lua_pushnumber(L, dmax);
194  return 1;
195}
196
197
198static int math_random (lua_State *L) {
199  /* the `%' avoids the (rare) case of r==1, and is needed also because on
200     some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
201  lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
202  switch (lua_gettop(L)) {  /* check number of arguments */
203    case 0: {  /* no arguments */
204      lua_pushnumber(L, r);  /* Number between 0 and 1 */
205      break;
206    }
207    case 1: {  /* only upper limit */
208      lua_Number u = luaL_checknumber(L, 1);
209      luaL_argcheck(L, (lua_Number)1.0 <= u, 1, "interval is empty");
210      lua_pushnumber(L, l_mathop(floor)(r*u) + (lua_Number)(1.0));  /* [1, u] */
211      break;
212    }
213    case 2: {  /* lower and upper limits */
214      lua_Number l = luaL_checknumber(L, 1);
215      lua_Number u = luaL_checknumber(L, 2);
216      luaL_argcheck(L, l <= u, 2, "interval is empty");
217      lua_pushnumber(L, l_mathop(floor)(r*(u-l+1)) + l);  /* [l, u] */
218      break;
219    }
220    default: return luaL_error(L, "wrong number of arguments");
221  }
222  return 1;
223}
224
225
226static int math_randomseed (lua_State *L) {
227  srand(luaL_checkunsigned(L, 1));
228  (void)rand(); /* discard first value to avoid undesirable correlations */
229  return 0;
230}
231
232
233static const luaL_Reg mathlib[] = {
234  {"abs",   math_abs},
235  {"acos",  math_acos},
236  {"asin",  math_asin},
237  {"atan2", math_atan2},
238  {"atan",  math_atan},
239  {"ceil",  math_ceil},
240  {"cosh",   math_cosh},
241  {"cos",   math_cos},
242  {"deg",   math_deg},
243  {"exp",   math_exp},
244  {"floor", math_floor},
245  {"fmod",   math_fmod},
246  {"frexp", math_frexp},
247  {"ldexp", math_ldexp},
248#if defined(LUA_COMPAT_LOG10)
249  {"log10", math_log10},
250#endif
251  {"log",   math_log},
252  {"max",   math_max},
253  {"min",   math_min},
254  {"modf",   math_modf},
255  {"pow",   math_pow},
256  {"rad",   math_rad},
257  {"random",     math_random},
258  {"randomseed", math_randomseed},
259  {"sinh",   math_sinh},
260  {"sin",   math_sin},
261  {"sqrt",  math_sqrt},
262  {"tanh",   math_tanh},
263  {"tan",   math_tan},
264  {NULL, NULL}
265};
266
267
268/*
269** Open math library
270*/
271LUAMOD_API int luaopen_math (lua_State *L) {
272  luaL_newlib(L, mathlib);
273  lua_pushnumber(L, PI);
274  lua_setfield(L, -2, "pi");
275  lua_pushnumber(L, HUGE_VAL);
276  lua_setfield(L, -2, "huge");
277  return 1;
278}
279
Property changes on: trunk/src/lib/lua/lmathlib.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/lua/luaconf.h
r0r22721
1/*
2** $Id: luaconf.h,v 1.176 2013/03/16 21:10:18 roberto Exp $
3** Configuration file for Lua
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lconfig_h
9#define lconfig_h
10
11#include <limits.h>
12#include <stddef.h>
13
14
15/*
16** ==================================================================
17** Search for "@@" to find all configurable definitions.
18** ===================================================================
19*/
20
21
22/*
23@@ LUA_ANSI controls the use of non-ansi features.
24** CHANGE it (define it) if you want Lua to avoid the use of any
25** non-ansi feature or library.
26*/
27#if !defined(LUA_ANSI) && defined(__STRICT_ANSI__)
28#define LUA_ANSI
29#endif
30
31
32#if !defined(LUA_ANSI) && defined(_WIN32) && !defined(_WIN32_WCE)
33#define LUA_WIN      /* enable goodies for regular Windows platforms */
34#endif
35
36#if defined(LUA_WIN)
37#define LUA_DL_DLL
38#define LUA_USE_AFORMAT      /* assume 'printf' handles 'aA' specifiers */
39#endif
40
41
42
43#if defined(LUA_USE_LINUX)
44#define LUA_USE_POSIX
45#define LUA_USE_DLOPEN      /* needs an extra library: -ldl */
46#define LUA_USE_READLINE   /* needs some extra libraries */
47#define LUA_USE_STRTODHEX   /* assume 'strtod' handles hex formats */
48#define LUA_USE_AFORMAT      /* assume 'printf' handles 'aA' specifiers */
49#define LUA_USE_LONGLONG   /* assume support for long long */
50#endif
51
52#if defined(LUA_USE_MACOSX)
53#define LUA_USE_POSIX
54#define LUA_USE_DLOPEN      /* does not need -ldl */
55#define LUA_USE_READLINE   /* needs an extra library: -lreadline */
56#define LUA_USE_STRTODHEX   /* assume 'strtod' handles hex formats */
57#define LUA_USE_AFORMAT      /* assume 'printf' handles 'aA' specifiers */
58#define LUA_USE_LONGLONG   /* assume support for long long */
59#endif
60
61
62
63/*
64@@ LUA_USE_POSIX includes all functionality listed as X/Open System
65@* Interfaces Extension (XSI).
66** CHANGE it (define it) if your system is XSI compatible.
67*/
68#if defined(LUA_USE_POSIX)
69#define LUA_USE_MKSTEMP
70#define LUA_USE_ISATTY
71#define LUA_USE_POPEN
72#define LUA_USE_ULONGJMP
73#define LUA_USE_GMTIME_R
74#endif
75
76
77
78/*
79@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
80@* Lua libraries.
81@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
82@* C libraries.
83** CHANGE them if your machine has a non-conventional directory
84** hierarchy or if you want to install your libraries in
85** non-conventional directories.
86*/
87#if defined(_WIN32)   /* { */
88/*
89** In Windows, any exclamation mark ('!') in the path is replaced by the
90** path of the directory of the executable file of the current process.
91*/
92#define LUA_LDIR   "!\\lua\\"
93#define LUA_CDIR   "!\\"
94#define LUA_PATH_DEFAULT  \
95      LUA_LDIR"?.lua;"  LUA_LDIR"?\\init.lua;" \
96      LUA_CDIR"?.lua;"  LUA_CDIR"?\\init.lua;" ".\\?.lua"
97#define LUA_CPATH_DEFAULT \
98      LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll"
99
100#else         /* }{ */
101
102#define LUA_VDIR   LUA_VERSION_MAJOR "." LUA_VERSION_MINOR "/"
103#define LUA_ROOT   "/usr/local/"
104#define LUA_LDIR   LUA_ROOT "share/lua/" LUA_VDIR
105#define LUA_CDIR   LUA_ROOT "lib/lua/" LUA_VDIR
106#define LUA_PATH_DEFAULT  \
107      LUA_LDIR"?.lua;"  LUA_LDIR"?/init.lua;" \
108      LUA_CDIR"?.lua;"  LUA_CDIR"?/init.lua;" "./?.lua"
109#define LUA_CPATH_DEFAULT \
110      LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so"
111#endif         /* } */
112
113
114/*
115@@ LUA_DIRSEP is the directory separator (for submodules).
116** CHANGE it if your machine does not use "/" as the directory separator
117** and is not Windows. (On Windows Lua automatically uses "\".)
118*/
119#if defined(_WIN32)
120#define LUA_DIRSEP   "\\"
121#else
122#define LUA_DIRSEP   "/"
123#endif
124
125
126/*
127@@ LUA_ENV is the name of the variable that holds the current
128@@ environment, used to access global names.
129** CHANGE it if you do not like this name.
130*/
131#define LUA_ENV      "_ENV"
132
133
134/*
135@@ LUA_API is a mark for all core API functions.
136@@ LUALIB_API is a mark for all auxiliary library functions.
137@@ LUAMOD_API is a mark for all standard library opening functions.
138** CHANGE them if you need to define those functions in some special way.
139** For instance, if you want to create one Windows DLL with the core and
140** the libraries, you may want to use the following definition (define
141** LUA_BUILD_AS_DLL to get it).
142*/
143#if defined(LUA_BUILD_AS_DLL)   /* { */
144
145#if defined(LUA_CORE) || defined(LUA_LIB)   /* { */
146#define LUA_API __declspec(dllexport)
147#else                  /* }{ */
148#define LUA_API __declspec(dllimport)
149#endif                  /* } */
150
151#else            /* }{ */
152
153#define LUA_API      extern
154
155#endif            /* } */
156
157
158/* more often than not the libs go together with the core */
159#define LUALIB_API   LUA_API
160#define LUAMOD_API   LUALIB_API
161
162
163/*
164@@ LUAI_FUNC is a mark for all extern functions that are not to be
165@* exported to outside modules.
166@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables
167@* that are not to be exported to outside modules (LUAI_DDEF for
168@* definitions and LUAI_DDEC for declarations).
169** CHANGE them if you need to mark them in some special way. Elf/gcc
170** (versions 3.2 and later) mark them as "hidden" to optimize access
171** when Lua is compiled as a shared library. Not all elf targets support
172** this attribute. Unfortunately, gcc does not offer a way to check
173** whether the target offers that support, and those without support
174** give a warning about it. To avoid these warnings, change to the
175** default definition.
176*/
177#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
178    defined(__ELF__)      /* { */
179#define LUAI_FUNC   __attribute__((visibility("hidden"))) extern
180#define LUAI_DDEC   LUAI_FUNC
181#define LUAI_DDEF   /* empty */
182
183#else            /* }{ */
184#define LUAI_FUNC   extern
185#define LUAI_DDEC   extern
186#define LUAI_DDEF   /* empty */
187#endif            /* } */
188
189
190
191/*
192@@ LUA_QL describes how error messages quote program elements.
193** CHANGE it if you want a different appearance.
194*/
195#define LUA_QL(x)   "'" x "'"
196#define LUA_QS      LUA_QL("%s")
197
198
199/*
200@@ LUA_IDSIZE gives the maximum size for the description of the source
201@* of a function in debug information.
202** CHANGE it if you want a different size.
203*/
204#define LUA_IDSIZE   60
205
206
207/*
208@@ luai_writestring/luai_writeline define how 'print' prints its results.
209** They are only used in libraries and the stand-alone program. (The #if
210** avoids including 'stdio.h' everywhere.)
211*/
212#if defined(LUA_LIB) || defined(lua_c)
213#include <stdio.h>
214#define luai_writestring(s,l)   fwrite((s), sizeof(char), (l), stdout)
215#define luai_writeline()   (luai_writestring("\n", 1), fflush(stdout))
216#endif
217
218/*
219@@ luai_writestringerror defines how to print error messages.
220** (A format string with one argument is enough for Lua...)
221*/
222#define luai_writestringerror(s,p) \
223   (fprintf(stderr, (s), (p)), fflush(stderr))
224
225
226/*
227@@ LUAI_MAXSHORTLEN is the maximum length for short strings, that is,
228** strings that are internalized. (Cannot be smaller than reserved words
229** or tags for metamethods, as these strings must be internalized;
230** #("function") = 8, #("__newindex") = 10.)
231*/
232#define LUAI_MAXSHORTLEN        40
233
234
235
236/*
237** {==================================================================
238** Compatibility with previous versions
239** ===================================================================
240*/
241
242/*
243@@ LUA_COMPAT_ALL controls all compatibility options.
244** You can define it to get all options, or change specific options
245** to fit your specific needs.
246*/
247#if defined(LUA_COMPAT_ALL)   /* { */
248
249/*
250@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.
251** You can replace it with 'table.unpack'.
252*/
253#define LUA_COMPAT_UNPACK
254
255/*
256@@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'.
257** You can replace it with 'package.searchers'.
258*/
259#define LUA_COMPAT_LOADERS
260
261/*
262@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall.
263** You can call your C function directly (with light C functions).
264*/
265#define lua_cpcall(L,f,u)  \
266   (lua_pushcfunction(L, (f)), \
267    lua_pushlightuserdata(L,(u)), \
268    lua_pcall(L,1,0,0))
269
270
271/*
272@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library.
273** You can rewrite 'log10(x)' as 'log(x, 10)'.
274*/
275#define LUA_COMPAT_LOG10
276
277/*
278@@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base
279** library. You can rewrite 'loadstring(s)' as 'load(s)'.
280*/
281#define LUA_COMPAT_LOADSTRING
282
283/*
284@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library.
285*/
286#define LUA_COMPAT_MAXN
287
288/*
289@@ The following macros supply trivial compatibility for some
290** changes in the API. The macros themselves document how to
291** change your code to avoid using them.
292*/
293#define lua_strlen(L,i)      lua_rawlen(L, (i))
294
295#define lua_objlen(L,i)      lua_rawlen(L, (i))
296
297#define lua_equal(L,idx1,idx2)      lua_compare(L,(idx1),(idx2),LUA_OPEQ)
298#define lua_lessthan(L,idx1,idx2)   lua_compare(L,(idx1),(idx2),LUA_OPLT)
299
300/*
301@@ LUA_COMPAT_MODULE controls compatibility with previous
302** module functions 'module' (Lua) and 'luaL_register' (C).
303*/
304#define LUA_COMPAT_MODULE
305
306#endif            /* } */
307
308/* }================================================================== */
309
310
311
312/*
313@@ LUAI_BITSINT defines the number of bits in an int.
314** CHANGE here if Lua cannot automatically detect the number of bits of
315** your machine. Probably you do not need to change this.
316*/
317/* avoid overflows in comparison */
318#if INT_MAX-20 < 32760      /* { */
319#define LUAI_BITSINT   16
320#elif INT_MAX > 2147483640L   /* }{ */
321/* int has at least 32 bits */
322#define LUAI_BITSINT   32
323#else            /* }{ */
324#error "you must define LUA_BITSINT with number of bits in an integer"
325#endif            /* } */
326
327
328/*
329@@ LUA_INT32 is an signed integer with exactly 32 bits.
330@@ LUAI_UMEM is an unsigned integer big enough to count the total
331@* memory used by Lua.
332@@ LUAI_MEM is a signed integer big enough to count the total memory
333@* used by Lua.
334** CHANGE here if for some weird reason the default definitions are not
335** good enough for your machine. Probably you do not need to change
336** this.
337*/
338#if LUAI_BITSINT >= 32      /* { */
339#define LUA_INT32   int
340#define LUAI_UMEM   size_t
341#define LUAI_MEM   ptrdiff_t
342#else            /* }{ */
343/* 16-bit ints */
344#define LUA_INT32   long
345#define LUAI_UMEM   unsigned long
346#define LUAI_MEM   long
347#endif            /* } */
348
349
350/*
351@@ LUAI_MAXSTACK limits the size of the Lua stack.
352** CHANGE it if you need a different limit. This limit is arbitrary;
353** its only purpose is to stop Lua to consume unlimited stack
354** space (and to reserve some numbers for pseudo-indices).
355*/
356#if LUAI_BITSINT >= 32
357#define LUAI_MAXSTACK      1000000
358#else
359#define LUAI_MAXSTACK      15000
360#endif
361
362/* reserve some space for error handling */
363#define LUAI_FIRSTPSEUDOIDX   (-LUAI_MAXSTACK - 1000)
364
365
366
367
368/*
369@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
370** CHANGE it if it uses too much C-stack space.
371*/
372#define LUAL_BUFFERSIZE      BUFSIZ
373
374
375
376
377/*
378** {==================================================================
379@@ LUA_NUMBER is the type of numbers in Lua.
380** CHANGE the following definitions only if you want to build Lua
381** with a number type different from double. You may also need to
382** change lua_number2int & lua_number2integer.
383** ===================================================================
384*/
385
386#define LUA_NUMBER_DOUBLE
387#define LUA_NUMBER   double
388
389/*
390@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
391@* over a number.
392*/
393#define LUAI_UACNUMBER   double
394
395
396/*
397@@ LUA_NUMBER_SCAN is the format for reading numbers.
398@@ LUA_NUMBER_FMT is the format for writing numbers.
399@@ lua_number2str converts a number to a string.
400@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
401*/
402#define LUA_NUMBER_SCAN      "%lf"
403#define LUA_NUMBER_FMT      "%.14g"
404#define lua_number2str(s,n)   sprintf((s), LUA_NUMBER_FMT, (n))
405#define LUAI_MAXNUMBER2STR   32 /* 16 digits, sign, point, and \0 */
406
407
408/*
409@@ l_mathop allows the addition of an 'l' or 'f' to all math operations
410*/
411#define l_mathop(x)      (x)
412
413
414/*
415@@ lua_str2number converts a decimal numeric string to a number.
416@@ lua_strx2number converts an hexadecimal numeric string to a number.
417** In C99, 'strtod' does both conversions. C89, however, has no function
418** to convert floating hexadecimal strings to numbers. For these
419** systems, you can leave 'lua_strx2number' undefined and Lua will
420** provide its own implementation.
421*/
422#define lua_str2number(s,p)   strtod((s), (p))
423
424#if defined(LUA_USE_STRTODHEX)
425#define lua_strx2number(s,p)   strtod((s), (p))
426#endif
427
428
429/*
430@@ The luai_num* macros define the primitive operations over numbers.
431*/
432
433/* the following operations need the math library */
434#if defined(lobject_c) || defined(lvm_c)
435#include <math.h>
436#define luai_nummod(L,a,b)   ((a) - l_mathop(floor)((a)/(b))*(b))
437#define luai_numpow(L,a,b)   (l_mathop(pow)(a,b))
438#endif
439
440/* these are quite standard operations */
441#if defined(LUA_CORE)
442#define luai_numadd(L,a,b)   ((a)+(b))
443#define luai_numsub(L,a,b)   ((a)-(b))
444#define luai_nummul(L,a,b)   ((a)*(b))
445#define luai_numdiv(L,a,b)   ((a)/(b))
446#define luai_numunm(L,a)   (-(a))
447#define luai_numeq(a,b)      ((a)==(b))
448#define luai_numlt(L,a,b)   ((a)<(b))
449#define luai_numle(L,a,b)   ((a)<=(b))
450#define luai_numisnan(L,a)   (!luai_numeq((a), (a)))
451#endif
452
453
454
455/*
456@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
457** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
458** machines, ptrdiff_t gives a good choice between int or long.)
459*/
460#define LUA_INTEGER   ptrdiff_t
461
462/*
463@@ LUA_UNSIGNED is the integral type used by lua_pushunsigned/lua_tounsigned.
464** It must have at least 32 bits.
465*/
466#define LUA_UNSIGNED   unsigned LUA_INT32
467
468
469
470/*
471** Some tricks with doubles
472*/
473
474#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI)   /* { */
475/*
476** The next definitions activate some tricks to speed up the
477** conversion from doubles to integer types, mainly to LUA_UNSIGNED.
478**
479@@ LUA_MSASMTRICK uses Microsoft assembler to avoid clashes with a
480** DirectX idiosyncrasy.
481**
482@@ LUA_IEEE754TRICK uses a trick that should work on any machine
483** using IEEE754 with a 32-bit integer type.
484**
485@@ LUA_IEEELL extends the trick to LUA_INTEGER; should only be
486** defined when LUA_INTEGER is a 32-bit integer.
487**
488@@ LUA_IEEEENDIAN is the endianness of doubles in your machine
489** (0 for little endian, 1 for big endian); if not defined, Lua will
490** check it dynamically for LUA_IEEE754TRICK (but not for LUA_NANTRICK).
491**
492@@ LUA_NANTRICK controls the use of a trick to pack all types into
493** a single double value, using NaN values to represent non-number
494** values. The trick only works on 32-bit machines (ints and pointers
495** are 32-bit values) with numbers represented as IEEE 754-2008 doubles
496** with conventional endianess (12345678 or 87654321), in CPUs that do
497** not produce signaling NaN values (all NaNs are quiet).
498*/
499
500/* Microsoft compiler on a Pentium (32 bit) ? */
501#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86)   /* { */
502
503#define LUA_MSASMTRICK
504#define LUA_IEEEENDIAN      0
505#define LUA_NANTRICK
506
507
508/* pentium 32 bits? */
509#elif defined(__i386__) || defined(__i386) || defined(__X86__) /* }{ */
510
511#define LUA_IEEE754TRICK
512#define LUA_IEEELL
513#define LUA_IEEEENDIAN      0
514#define LUA_NANTRICK
515
516/* pentium 64 bits? */
517#elif defined(__x86_64)                  /* }{ */
518
519#define LUA_IEEE754TRICK
520#define LUA_IEEEENDIAN      0
521
522#elif defined(__POWERPC__) || defined(__ppc__)         /* }{ */
523
524#define LUA_IEEE754TRICK
525#define LUA_IEEEENDIAN      1
526
527#else                        /* }{ */
528
529/* assume IEEE754 and a 32-bit integer type */
530#define LUA_IEEE754TRICK
531
532#endif                        /* } */
533
534#endif                     /* } */
535
536/* }================================================================== */
537
538
539
540
541/* =================================================================== */
542
543/*
544** Local configuration. You can use this space to add your redefinitions
545** without modifying the main part of the file.
546*/
547
548
549
550#endif
551
Property changes on: trunk/src/lib/lua/luaconf.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lib.mak
r22720r22721
2323   $(LIBOBJ)/libflac \
2424   $(LIBOBJ)/lib7z \
2525   $(LIBOBJ)/portmidi \
26   $(LIBOBJ)/lua \
2627
2728
2829#-------------------------------------------------
r22720r22721
427428   @echo Compiling $<...
428429   $(CC) $(CDEFS) $(PMOPTS) $(CCOMFLAGS) $(CONLYFLAGS) -I$(LIBSRC)/portmidi/ -c $< -o $@
429430
431#-------------------------------------------------
432# LUA library objects
433#-------------------------------------------------
434
435LUAOBJS = \
436   $(LIBOBJ)/lua/lapi.o \
437   $(LIBOBJ)/lua/lcode.o \
438   $(LIBOBJ)/lua/lctype.o \
439   $(LIBOBJ)/lua/ldebug.o \
440   $(LIBOBJ)/lua/ldo.o \
441   $(LIBOBJ)/lua/ldump.o \
442   $(LIBOBJ)/lua/lfunc.o \
443   $(LIBOBJ)/lua/lgc.o \
444   $(LIBOBJ)/lua/llex.o \
445   $(LIBOBJ)/lua/lmem.o \
446   $(LIBOBJ)/lua/lobject.o \
447   $(LIBOBJ)/lua/lopcodes.o \
448   $(LIBOBJ)/lua/lparser.o \
449   $(LIBOBJ)/lua/lstate.o \
450   $(LIBOBJ)/lua/lstring.o \
451   $(LIBOBJ)/lua/ltable.o \
452   $(LIBOBJ)/lua/ltm.o \
453   $(LIBOBJ)/lua/lundump.o \
454   $(LIBOBJ)/lua/lvm.o \
455   $(LIBOBJ)/lua/lzio.o \
456   $(LIBOBJ)/lua/lauxlib.o \
457   $(LIBOBJ)/lua/lbaselib.o \
458   $(LIBOBJ)/lua/lbitlib.o \
459   $(LIBOBJ)/lua/lcorolib.o \
460   $(LIBOBJ)/lua/ldblib.o \
461   $(LIBOBJ)/lua/liolib.o \
462   $(LIBOBJ)/lua/lmathlib.o \
463   $(LIBOBJ)/lua/loslib.o \
464   $(LIBOBJ)/lua/lstrlib.o \
465   $(LIBOBJ)/lua/ltablib.o \
466   $(LIBOBJ)/lua/loadlib.o \
467   $(LIBOBJ)/lua/linit.o \
468
469$(OBJ)/liblua.a: $(LUAOBJS)
470
471$(LIBOBJ)/lua/%.o: $(LIBSRC)/lua/%.c | $(OSPREBUILD)
472   @echo Compiling $<...
473   $(CC) $(CDEFS) $(CCOMFLAGS) $(CONLYFLAGS) -DLUA_COMPAT_ALL -c $< -o $@
trunk/src/emu/luaengine.c
r0r22721
1/***************************************************************************
2
3    luaengine.c
4
5    Controls execution of the core MAME system.
6
7****************************************************************************
8
9    Copyright Miodrag Milanovic
10    All rights reserved.
11
12    Redistribution and use in source and binary forms, with or without
13    modification, are permitted provided that the following conditions are
14    met:
15
16        * Redistributions of source code must retain the above copyright
17          notice, this list of conditions and the following disclaimer.
18        * Redistributions in binary form must reproduce the above copyright
19          notice, this list of conditions and the following disclaimer in
20          the documentation and/or other materials provided with the
21          distribution.
22        * Neither the name 'MAME' nor the names of its contributors may be
23          used to endorse or promote products derived from this software
24          without specific prior written permission.
25
26    THIS SOFTWARE IS PROVIDED BY MIODRAG MILANOVIC ''AS IS'' AND ANY EXPRESS OR
27    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29    DISCLAIMED. IN NO EVENT SHALL MIODRAG MILANOVIC BE LIABLE FOR ANY DIRECT,
30    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
35    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36    POSSIBILITY OF SUCH DAMAGE.
37
38***************************************************************************/
39
40#include "emu.h"
41#include "emuopts.h"
42#include "osdepend.h"
43#include "lua/lua.hpp"
44
45
46lua_engine* lua_engine::luaThis = NULL;
47
48//**************************************************************************
49//  LUA ENGINE
50//**************************************************************************
51
52//-------------------------------------------------
53//  emu_gamename - returns game full name
54//-------------------------------------------------
55
56int lua_engine::emu_gamename(lua_State *L) {
57   lua_pushstring(L, luaThis->machine().system().description);
58   return 1;
59}
60
61static const struct luaL_Reg emu_funcs [] =
62{
63  { "gamename", lua_engine::emu_gamename },
64  { NULL, NULL }  /* sentinel */
65};
66
67//-------------------------------------------------
68//  luaopen_emu - connect emu section lib
69//-------------------------------------------------
70
71int luaopen_emu ( lua_State * L )
72{
73  luaL_newlib(L, emu_funcs);
74  return 1;
75}
76
77//-------------------------------------------------
78//  hook - lua hook to make slice execution of
79//  script possible
80//-------------------------------------------------
81
82void hook(lua_State* l, lua_Debug* ar)
83{
84    lua_yield(l, 0);
85}
86
87//-------------------------------------------------
88//  lua_engine - constructor
89//-------------------------------------------------
90
91lua_engine::lua_engine(running_machine &machine)
92   : m_machine(machine)
93{
94   luaThis = this;
95   m_lua_state = NULL;
96}
97
98//-------------------------------------------------
99//  ~lua_engine - destructor
100//-------------------------------------------------
101
102lua_engine::~lua_engine()
103{
104   close();
105}
106
107//-------------------------------------------------
108//  initialize - initialize lua hookup to emu engine
109//-------------------------------------------------
110
111void lua_engine::initialize()
112{
113   machine().add_notifier(MACHINE_NOTIFY_FRAME, machine_notify_delegate(FUNC(lua_engine::lua_execute), this));
114}
115
116//-------------------------------------------------
117//  close - close and cleanup of lua engine
118//-------------------------------------------------
119
120void lua_engine::close()
121{
122   if (m_lua_state) {
123      // close the Lua state   
124      lua_close(m_lua_state);
125      mame_printf_verbose("[LUA] End executing script\n");     
126      m_lua_state = NULL;
127   }
128}
129
130//-------------------------------------------------
131//  report_errors - report lua error in execution
132//-------------------------------------------------
133
134void lua_engine::report_errors(int status)
135{
136  if ( status!=0 ) {
137    mame_printf_error("[LUA ERROR] %s\n",lua_tostring(m_lua_state, -1));
138    lua_pop(m_lua_state, 1); // remove error message
139   
140   close(); // close in case of error
141  }
142}
143
144
145//-------------------------------------------------
146//  execute - setup lua VM and load script
147//-------------------------------------------------
148
149void lua_engine::execute(const char *filename)
150{
151   close();
152   
153   // create new Lua state   
154   m_lua_state = luaL_newstate();       
155   luaL_openlibs(m_lua_state);
156   luaL_requiref(m_lua_state, "emu", luaopen_emu, 1);   
157   lua_sethook(m_lua_state, hook, LUA_MASKLINE, 0);     
158
159   int s = luaL_loadfile(m_lua_state, filename);       
160   report_errors(s);
161
162   mame_printf_verbose("[LUA] Start executing script\n");
163}
164
165//-------------------------------------------------
166//  lua_execute - execute slice of lua script
167//  this callback is hooked to frame notification
168//-------------------------------------------------
169
170void lua_engine::lua_execute()
171{
172   if (m_lua_state==NULL) return;
173   
174   int s = lua_resume(m_lua_state, m_lua_state, 0);
175   
176   if (s != LUA_YIELD) {
177      report_errors(s);   
178      close();
179   }
180}
Property changes on: trunk/src/emu/luaengine.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/luaengine.h
r0r22721
1/***************************************************************************
2
3    luaengine.h
4
5    Controls execution of the core MAME system.
6
7****************************************************************************
8
9    Copyright Miodrag Milanovic
10    All rights reserved.
11
12    Redistribution and use in source and binary forms, with or without
13    modification, are permitted provided that the following conditions are
14    met:
15
16        * Redistributions of source code must retain the above copyright
17          notice, this list of conditions and the following disclaimer.
18        * Redistributions in binary form must reproduce the above copyright
19          notice, this list of conditions and the following disclaimer in
20          the documentation and/or other materials provided with the
21          distribution.
22        * Neither the name 'MAME' nor the names of its contributors may be
23          used to endorse or promote products derived from this software
24          without specific prior written permission.
25
26    THIS SOFTWARE IS PROVIDED BY MIODRAG MILANOVIC ''AS IS'' AND ANY EXPRESS OR
27    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29    DISCLAIMED. IN NO EVENT SHALL MIODRAG MILANOVIC BE LIABLE FOR ANY DIRECT,
30    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
35    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36    POSSIBILITY OF SUCH DAMAGE.
37
38***************************************************************************/
39
40#pragma once
41
42#ifndef __EMU_H__
43#error Dont include this file directly; include emu.h instead.
44#endif
45
46#ifndef __LUA_ENGINE_H__
47#define __LUA_ENGINE_H__
48
49struct lua_State;
50
51class lua_engine
52{
53public:
54   // construction/destruction
55   lua_engine(running_machine &machine);
56   ~lua_engine();
57
58   // getters
59   running_machine &machine() const { return m_machine; }
60
61   void initialize();
62   void lua_execute();
63   void report_errors(int status);
64   
65   void execute(const char *filename);
66   
67   void close();
68   
69   //static
70   static int emu_gamename(lua_State *L);
71private:   
72   // internal state
73   running_machine &   m_machine;                          // reference to our machine
74   lua_State*          m_lua_state;
75   
76   static lua_engine*  luaThis;
77};
78
79#endif  /* __LUA_ENGINE_H__ */
Property changes on: trunk/src/emu/luaengine.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/emuopts.c
r22720r22721
197197   { OPTION_UI_MOUSE,                                   "0",         OPTION_BOOLEAN,    "display ui mouse cursor" },
198198   { OPTION_AUTOBOOT_COMMAND ";ab",                     NULL,        OPTION_STRING,     "command to execute after machine boot" },
199199   { OPTION_AUTOBOOT_DELAY,                             "2",         OPTION_INTEGER,    "timer delay in sec to trigger command execution on autoboot" },
200   { OPTION_AUTOBOOT_SCRIPT ";script",                  NULL,        OPTION_STRING,     "lua script to execute after machine boot" },
200201   { NULL }
201202};
202203
trunk/src/emu/emuopts.h
r22720r22721
201201
202202#define OPTION_AUTOBOOT_COMMAND      "autoboot_command"
203203#define OPTION_AUTOBOOT_DELAY      "autoboot_delay"
204#define OPTION_AUTOBOOT_SCRIPT      "autoboot_script"
204205
205206//**************************************************************************
206207//  TYPE DEFINITIONS
r22720r22721
357358   
358359   const char *autoboot_command() const { return value(OPTION_AUTOBOOT_COMMAND); }
359360   int autoboot_delay() const { return int_value(OPTION_AUTOBOOT_DELAY); }
361   const char *autoboot_script() const { return value(OPTION_AUTOBOOT_SCRIPT); }
360362
361363   // device-specific options
362364   const char *device_option(device_image_interface &image);
trunk/src/emu/emu.h
r22720r22721
121121// networking
122122#include "network.h"
123123
124// lua engine
125#include "luaengine.h"
126
124127// the running machine
125128#include "machine.h"
126129#include "driver.h"
trunk/src/emu/machine.c
r22720r22721
176176      m_save(*this),
177177      m_memory(*this),
178178      m_ioport(*this),
179      m_scheduler(*this)
179      m_scheduler(*this),
180      m_lua_engine(*this)
180181{
181182   memset(gfx, 0, sizeof(gfx));
182183   memset(&m_base_time, 0, sizeof(m_base_time));
r22720r22721
234235
235236TIMER_CALLBACK_MEMBER(running_machine::autoboot_callback)
236237{
238   if (strlen(options().autoboot_script())!=0) {
239      m_lua_engine.execute(options().autoboot_script());
240   }
237241   if (strlen(options().autoboot_command())!=0) {
238242      astring val = astring(options().autoboot_command());
239243      val.replace("\\n","\n");
r22720r22721
332336   // set up the cheat engine
333337   m_cheat = auto_alloc(*this, cheat_manager(*this));
334338
335   /* allocate a timer */
339   // allocate autoboot timer
336340   m_autoboot_timer = scheduler().timer_alloc(timer_expired_delegate(FUNC(running_machine::autoboot_callback), this));
337341
342   // initialize lua
343   m_lua_engine.initialize();
344
338345   // disallow save state registrations starting here
339346   m_save.allow_registration(false);
340347}
trunk/src/emu/machine.h
r22720r22721
418418   ioport_manager          m_ioport;               // I/O port manager
419419   device_scheduler        m_scheduler;            // scheduler object
420420   emu_timer              *m_autoboot_timer;      // autoboot timer
421   lua_engine            m_lua_engine;         // LUA engine
421422};
422423
423424
trunk/src/emu/emu.mak
r22720r22721
8383   $(EMUOBJ)/info.o \
8484   $(EMUOBJ)/input.o \
8585   $(EMUOBJ)/ioport.o \
86   $(EMUOBJ)/luaengine.o \
8687   $(EMUOBJ)/mame.o \
8788   $(EMUOBJ)/machine.o \
8889   $(EMUOBJ)/mconfig.o \

Previous 199869 Revisions Next


© 1997-2024 The MAME Team