summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Quirk <richard.quirk@gmail.com>2014-03-19 19:31:31 +0100
committerMarcin Bukat <marcin.bukat@gmail.com>2014-04-02 20:31:54 +0200
commit36378988ad4059982742f05f5eb50580b456840a (patch)
treeee70be810d894566c5e351f21a1ebb79be742a85
parent020f16a1c7d5bc9a302671cef03f56ac735e20c5 (diff)
downloadrockbox-36378988ad4059982742f05f5eb50580b456840a.tar.gz
rockbox-36378988ad4059982742f05f5eb50580b456840a.zip
Update lua plugin to 5.2.3
Prior to this patch the Lua plugin used version 5.1.4. This change reduces the number of modifications in the Lua source using some new defines and because the upstream source is now more flexible. Unless otherwise stated, l*.[ch] files are taken unmodified from the upstream lua-5.2.3. fscanf.c: file descriptors in rockbox are just ints, they are hidden behind a void* now so liolib requires less modifications. fscanf is updated to use void* too. getc.c: this is a new file required for getc implementation in lauxlib.c lauxlib.c: LoadF replaced FILE* with int, the rockbox file descriptor int are cast to FILE* (actually void* due to typedef). getc uses the PREFIX version. stdin is not used, as per 5.1.4. lbaselib.c: now uses strspn in the number parsing. print uses DEBUGF now rather than being commented out. lbitlib.c: use the built-in version from 5.2.3 rather than Reuben Thomas's external library. Backwards compatible and adds some new bit operations. ldo.c: the LUAI_THROW/TRY defines are now in the core lua code, so have been removed from rockconf.h liolib.c: here the implementation has changed to use the LStream from the original source, and cast the FILE* pointers to int. This has reduced the number of modifications from the upstream version. llex.c: the only change from upstream is to remove the locale include. lmathlib.c: updated from the 5.2.3 version and re-applied the changes that were made vs 5.1.4 for random numbers and to remove unsupported float functions. loadlib.c: upstream version, with the 5.1.4 changes for missing functions. lobject.c: upstream version, with ctype.h added and sprintf changed to snprintf. loslib.c: upstream version with locale.h removed and 5.1.4 changes for unsupportable functions. lstrlib.c: sprintf changed to snprintf. ltable.c: upstream with the hashnum function from 5.1.4 to avoid frexp in luai_hashnum. luaconf.h: updated to 5.2.3 version, restored relevant parts from the original 5.1.4 configuration. The COMPAT defines that are no longer available are not included. lundump.c: VERSION macro conflicts with the core Rockbox equivalent. rocklib.c: luaL_reg is no longer available, replaced by luaL_Reg equivalent. Moved checkboolean/optboolean functions to this file and out of core lua files. luaL_getn is no longer available, replaced by luaL_rawlen. luaL_register is deprecated, use the newlib/setfuncs replacements. rli_init has to be called before setting up the newlib to avoid overwriting the rb table. rocklib_aux.pl: use rli_checkboolean from rocklib.c. rocklua.c: new default bits library used, update the library loading code with idiomatic 5.2 code. strcspn.c: no longer needed, but strspn.c is required for strspn in lbaselib.c Change-Id: I0c7945c755f79083afe98ec117e1e8cf13de2651 Reviewed-on: http://gerrit.rockbox.org/774 Tested: Richard Quirk <richard.quirk@gmail.com> Reviewed-by: Marcin Bukat <marcin.bukat@gmail.com>
-rw-r--r--apps/plugins/lua/SOURCES3
-rw-r--r--apps/plugins/lua/fscanf.c6
-rw-r--r--apps/plugins/lua/getc.c10
-rw-r--r--apps/plugins/lua/lapi.c867
-rw-r--r--apps/plugins/lua/lapi.h14
-rw-r--r--apps/plugins/lua/lauxlib.c974
-rw-r--r--apps/plugins/lua/lauxlib.h130
-rw-r--r--apps/plugins/lua/lbaselib.c571
-rw-r--r--apps/plugins/lua/lbitlib.c268
-rw-r--r--apps/plugins/lua/lcode.c400
-rw-r--r--apps/plugins/lua/lcode.h21
-rw-r--r--apps/plugins/lua/lctype.h95
-rw-r--r--apps/plugins/lua/ldebug.c625
-rw-r--r--apps/plugins/lua/ldebug.h27
-rw-r--r--apps/plugins/lua/ldo.c671
-rw-r--r--apps/plugins/lua/ldo.h33
-rw-r--r--apps/plugins/lua/ldump.c43
-rw-r--r--apps/plugins/lua/lfunc.c81
-rw-r--r--apps/plugins/lua/lfunc.h7
-rw-r--r--apps/plugins/lua/lgc.c1417
-rw-r--r--apps/plugins/lua/lgc.h159
-rw-r--r--apps/plugins/lua/liolib.c536
-rw-r--r--apps/plugins/lua/llex.c368
-rw-r--r--apps/plugins/lua/llex.h27
-rw-r--r--apps/plugins/lua/llimits.h221
-rw-r--r--apps/plugins/lua/lmathlib.c92
-rw-r--r--apps/plugins/lua/lmem.c45
-rw-r--r--apps/plugins/lua/lmem.h28
-rw-r--r--apps/plugins/lua/loadlib.c650
-rw-r--r--apps/plugins/lua/lobject.c250
-rw-r--r--apps/plugins/lua/lobject.h460
-rw-r--r--apps/plugins/lua/lopcodes.c31
-rw-r--r--apps/plugins/lua/lopcodes.h106
-rw-r--r--apps/plugins/lua/loslib.c223
-rw-r--r--apps/plugins/lua/lparser.c1015
-rw-r--r--apps/plugins/lua/lparser.h75
-rw-r--r--apps/plugins/lua/lstate.c273
-rw-r--r--apps/plugins/lua/lstate.h149
-rw-r--r--apps/plugins/lua/lstring.c174
-rw-r--r--apps/plugins/lua/lstring.h21
-rw-r--r--apps/plugins/lua/lstrlib.c580
-rw-r--r--apps/plugins/lua/ltable.c194
-rw-r--r--apps/plugins/lua/ltable.h19
-rw-r--r--apps/plugins/lua/ltablib.c140
-rw-r--r--apps/plugins/lua/ltm.c20
-rw-r--r--apps/plugins/lua/ltm.h9
-rw-r--r--apps/plugins/lua/lua.h224
-rw-r--r--apps/plugins/lua/luaconf.h678
-rw-r--r--apps/plugins/lua/luadir.c4
-rw-r--r--apps/plugins/lua/lualib.h30
-rw-r--r--apps/plugins/lua/lundump.c142
-rw-r--r--apps/plugins/lua/lundump.h22
-rw-r--r--apps/plugins/lua/lvm.c914
-rw-r--r--apps/plugins/lua/lvm.h26
-rw-r--r--apps/plugins/lua/lzio.c34
-rw-r--r--apps/plugins/lua/lzio.h8
-rw-r--r--apps/plugins/lua/rockconf.h25
-rw-r--r--apps/plugins/lua/rocklib.c28
-rw-r--r--apps/plugins/lua/rocklib.h1
-rwxr-xr-xapps/plugins/lua/rocklib_aux.pl3
-rw-r--r--apps/plugins/lua/rocklibc.h4
-rw-r--r--apps/plugins/lua/rocklua.c14
-rw-r--r--apps/plugins/lua/strcspn.c17
-rw-r--r--apps/plugins/lua/strspn.c19
64 files changed, 8838 insertions, 5483 deletions
diff --git a/apps/plugins/lua/SOURCES b/apps/plugins/lua/SOURCES
index baebfabe65..e3d9947e1e 100644
--- a/apps/plugins/lua/SOURCES
+++ b/apps/plugins/lua/SOURCES
@@ -31,12 +31,13 @@ rocklib.c
31tlsf_helper.c 31tlsf_helper.c
32fscanf.c 32fscanf.c
33gmtime.c 33gmtime.c
34strcspn.c 34strspn.c
35strftime.c 35strftime.c
36strncat.c 36strncat.c
37strpbrk.c 37strpbrk.c
38strtoul.c 38strtoul.c
39strtol.c 39strtol.c
40strstr.c 40strstr.c
41getc.c
41rocklua.c 42rocklua.c
42luadir.c 43luadir.c
diff --git a/apps/plugins/lua/fscanf.c b/apps/plugins/lua/fscanf.c
index 9f5f129d3c..ee42daeab7 100644
--- a/apps/plugins/lua/fscanf.c
+++ b/apps/plugins/lua/fscanf.c
@@ -266,7 +266,7 @@ static int scan(int (*peek)(void *userp),
266 266
267static int fspeek(void *userp) 267static int fspeek(void *userp)
268{ 268{
269 int fd = *((int*) userp); 269 int fd = ((int) userp);
270 char buf = 0; 270 char buf = 0;
271 if(rb->read(fd, &buf, 1) == 1) 271 if(rb->read(fd, &buf, 1) == 1)
272 rb->lseek(fd, -1, SEEK_CUR); 272 rb->lseek(fd, -1, SEEK_CUR);
@@ -275,11 +275,11 @@ static int fspeek(void *userp)
275 275
276static void fspop(void *userp) 276static void fspop(void *userp)
277{ 277{
278 int fd = *((int*) userp); 278 int fd = ((int) userp);
279 rb->lseek(fd, 1, SEEK_CUR); 279 rb->lseek(fd, 1, SEEK_CUR);
280} 280}
281 281
282int PREFIX(fscanf)(int fd, const char *fmt, ...) 282int PREFIX(fscanf)(void *fd, const char *fmt, ...)
283{ 283{
284 int r; 284 int r;
285 va_list ap; 285 va_list ap;
diff --git a/apps/plugins/lua/getc.c b/apps/plugins/lua/getc.c
new file mode 100644
index 0000000000..84a280e2c2
--- /dev/null
+++ b/apps/plugins/lua/getc.c
@@ -0,0 +1,10 @@
1#include "rocklibc.h"
2
3int PREFIX(getc)(int fd)
4{
5 unsigned char c;
6 if (rb->read(fd, &c, 1))
7 return c;
8 else
9 return EOF;
10}
diff --git a/apps/plugins/lua/lapi.c b/apps/plugins/lua/lapi.c
index 487d6b173a..d011431ead 100644
--- a/apps/plugins/lua/lapi.c
+++ b/apps/plugins/lua/lapi.c
@@ -1,12 +1,10 @@
1/* 1/*
2** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $ 2** $Id: lapi.c,v 2.171.1.1 2013/04/12 18:48:47 roberto Exp $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
6 6
7 7
8/* #include <assert.h> */
9#include <math.h>
10#include <stdarg.h> 8#include <stdarg.h>
11#include <string.h> 9#include <string.h>
12 10
@@ -32,76 +30,80 @@
32 30
33 31
34const char lua_ident[] = 32const char lua_ident[] =
35 "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n" 33 "$LuaVersion: " LUA_COPYRIGHT " $"
36 "$Authors: " LUA_AUTHORS " $\n" 34 "$LuaAuthors: " LUA_AUTHORS " $";
37 "$URL: www.lua.org $\n";
38 35
39 36
37/* value at a non-valid index */
38#define NONVALIDVALUE cast(TValue *, luaO_nilobject)
40 39
41#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) 40/* corresponding test */
41#define isvalid(o) ((o) != luaO_nilobject)
42 42
43#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject) 43/* test for pseudo index */
44#define ispseudo(i) ((i) <= LUA_REGISTRYINDEX)
44 45
45#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;} 46/* test for valid but not pseudo index */
47#define isstackindex(i, o) (isvalid(o) && !ispseudo(i))
46 48
49#define api_checkvalidindex(L, o) api_check(L, isvalid(o), "invalid index")
47 50
51#define api_checkstackindex(L, i, o) \
52 api_check(L, isstackindex(i, o), "index not in the stack")
48 53
49static TValue *index2adr (lua_State *L, int idx) { 54
55static TValue *index2addr (lua_State *L, int idx) {
56 CallInfo *ci = L->ci;
50 if (idx > 0) { 57 if (idx > 0) {
51 TValue *o = L->base + (idx - 1); 58 TValue *o = ci->func + idx;
52 api_check(L, idx <= L->ci->top - L->base); 59 api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
53 if (o >= L->top) return cast(TValue *, luaO_nilobject); 60 if (o >= L->top) return NONVALIDVALUE;
54 else return o; 61 else return o;
55 } 62 }
56 else if (idx > LUA_REGISTRYINDEX) { 63 else if (!ispseudo(idx)) { /* negative index */
57 api_check(L, idx != 0 && -idx <= L->top - L->base); 64 api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
58 return L->top + idx; 65 return L->top + idx;
59 } 66 }
60 else switch (idx) { /* pseudo-indices */ 67 else if (idx == LUA_REGISTRYINDEX)
61 case LUA_REGISTRYINDEX: return registry(L); 68 return &G(L)->l_registry;
62 case LUA_ENVIRONINDEX: { 69 else { /* upvalues */
63 Closure *func = curr_func(L); 70 idx = LUA_REGISTRYINDEX - idx;
64 sethvalue(L, &L->env, func->c.env); 71 api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
65 return &L->env; 72 if (ttislcf(ci->func)) /* light C function? */
66 } 73 return NONVALIDVALUE; /* it has no upvalues */
67 case LUA_GLOBALSINDEX: return gt(L); 74 else {
68 default: { 75 CClosure *func = clCvalue(ci->func);
69 Closure *func = curr_func(L); 76 return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE;
70 idx = LUA_GLOBALSINDEX - idx;
71 return (idx <= func->c.nupvalues)
72 ? &func->c.upvalue[idx-1]
73 : cast(TValue *, luaO_nilobject);
74 } 77 }
75 } 78 }
76} 79}
77 80
78 81
79static Table *getcurrenv (lua_State *L) { 82/*
80 if (L->ci == L->base_ci) /* no enclosing function? */ 83** to be called by 'lua_checkstack' in protected mode, to grow stack
81 return hvalue(gt(L)); /* use global table as environment */ 84** capturing memory errors
82 else { 85*/
83 Closure *func = curr_func(L); 86static void growstack (lua_State *L, void *ud) {
84 return func->c.env; 87 int size = *(int *)ud;
85 } 88 luaD_growstack(L, size);
86}
87
88
89void luaA_pushobject (lua_State *L, const TValue *o) {
90 setobj2s(L, L->top, o);
91 api_incr_top(L);
92} 89}
93 90
94 91
95LUA_API int lua_checkstack (lua_State *L, int size) { 92LUA_API int lua_checkstack (lua_State *L, int size) {
96 int res = 1; 93 int res;
94 CallInfo *ci = L->ci;
97 lua_lock(L); 95 lua_lock(L);
98 if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) 96 if (L->stack_last - L->top > size) /* stack large enough? */
99 res = 0; /* stack overflow */ 97 res = 1; /* yes; check is OK */
100 else if (size > 0) { 98 else { /* no; need to grow stack */
101 luaD_checkstack(L, size); 99 int inuse = cast_int(L->top - L->stack) + EXTRA_STACK;
102 if (L->ci->top < L->top + size) 100 if (inuse > LUAI_MAXSTACK - size) /* can grow without overflow? */
103 L->ci->top = L->top + size; 101 res = 0; /* no */
102 else /* try to grow stack */
103 res = (luaD_rawrunprotected(L, &growstack, &size) == LUA_OK);
104 } 104 }
105 if (res && ci->top < L->top + size)
106 ci->top = L->top + size; /* adjust frame top */
105 lua_unlock(L); 107 lua_unlock(L);
106 return res; 108 return res;
107} 109}
@@ -112,8 +114,8 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
112 if (from == to) return; 114 if (from == to) return;
113 lua_lock(to); 115 lua_lock(to);
114 api_checknelems(from, n); 116 api_checknelems(from, n);
115 api_check(from, G(from) == G(to)); 117 api_check(from, G(from) == G(to), "moving among independent states");
116 api_check(from, to->ci->top - to->top >= n); 118 api_check(from, to->ci->top - to->top >= n, "not enough elements to move");
117 from->top -= n; 119 from->top -= n;
118 for (i = 0; i < n; i++) { 120 for (i = 0; i < n; i++) {
119 setobj2s(to, to->top++, from->top + i); 121 setobj2s(to, to->top++, from->top + i);
@@ -122,11 +124,6 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
122} 124}
123 125
124 126
125LUA_API void lua_setlevel (lua_State *from, lua_State *to) {
126 to->nCcalls = from->nCcalls;
127}
128
129
130LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { 127LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
131 lua_CFunction old; 128 lua_CFunction old;
132 lua_lock(L); 129 lua_lock(L);
@@ -137,16 +134,10 @@ LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
137} 134}
138 135
139 136
140LUA_API lua_State *lua_newthread (lua_State *L) { 137LUA_API const lua_Number *lua_version (lua_State *L) {
141 lua_State *L1; 138 static const lua_Number version = LUA_VERSION_NUM;
142 lua_lock(L); 139 if (L == NULL) return &version;
143 luaC_checkGC(L); 140 else return G(L)->version;
144 L1 = luaE_newthread(L);
145 setthvalue(L, L->top, L1);
146 api_incr_top(L);
147 lua_unlock(L);
148 luai_userstatethread(L, L1);
149 return L1;
150} 141}
151 142
152 143
@@ -156,21 +147,32 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
156*/ 147*/
157 148
158 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
159LUA_API int lua_gettop (lua_State *L) { 160LUA_API int lua_gettop (lua_State *L) {
160 return cast_int(L->top - L->base); 161 return cast_int(L->top - (L->ci->func + 1));
161} 162}
162 163
163 164
164LUA_API void lua_settop (lua_State *L, int idx) { 165LUA_API void lua_settop (lua_State *L, int idx) {
166 StkId func = L->ci->func;
165 lua_lock(L); 167 lua_lock(L);
166 if (idx >= 0) { 168 if (idx >= 0) {
167 api_check(L, idx <= L->stack_last - L->base); 169 api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
168 while (L->top < L->base + idx) 170 while (L->top < (func + 1) + idx)
169 setnilvalue(L->top++); 171 setnilvalue(L->top++);
170 L->top = L->base + idx; 172 L->top = (func + 1) + idx;
171 } 173 }
172 else { 174 else {
173 api_check(L, -(idx+1) <= (L->top - L->base)); 175 api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
174 L->top += idx+1; /* `subtract' index (index is negative) */ 176 L->top += idx+1; /* `subtract' index (index is negative) */
175 } 177 }
176 lua_unlock(L); 178 lua_unlock(L);
@@ -180,8 +182,8 @@ LUA_API void lua_settop (lua_State *L, int idx) {
180LUA_API void lua_remove (lua_State *L, int idx) { 182LUA_API void lua_remove (lua_State *L, int idx) {
181 StkId p; 183 StkId p;
182 lua_lock(L); 184 lua_lock(L);
183 p = index2adr(L, idx); 185 p = index2addr(L, idx);
184 api_checkvalidindex(L, p); 186 api_checkstackindex(L, idx, p);
185 while (++p < L->top) setobjs2s(L, p-1, p); 187 while (++p < L->top) setobjs2s(L, p-1, p);
186 L->top--; 188 L->top--;
187 lua_unlock(L); 189 lua_unlock(L);
@@ -192,42 +194,47 @@ LUA_API void lua_insert (lua_State *L, int idx) {
192 StkId p; 194 StkId p;
193 StkId q; 195 StkId q;
194 lua_lock(L); 196 lua_lock(L);
195 p = index2adr(L, idx); 197 p = index2addr(L, idx);
196 api_checkvalidindex(L, p); 198 api_checkstackindex(L, idx, p);
197 for (q = L->top; q>p; q--) setobjs2s(L, q, q-1); 199 for (q = L->top; q > p; q--) /* use L->top as a temporary */
200 setobjs2s(L, q, q - 1);
198 setobjs2s(L, p, L->top); 201 setobjs2s(L, p, L->top);
199 lua_unlock(L); 202 lua_unlock(L);
200} 203}
201 204
202 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
203LUA_API void lua_replace (lua_State *L, int idx) { 217LUA_API void lua_replace (lua_State *L, int idx) {
204 StkId o;
205 lua_lock(L); 218 lua_lock(L);
206 /* explicit test for incompatible code */
207 if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci)
208 luaG_runerror(L, "no calling environment");
209 api_checknelems(L, 1); 219 api_checknelems(L, 1);
210 o = index2adr(L, idx); 220 moveto(L, L->top - 1, idx);
211 api_checkvalidindex(L, o);
212 if (idx == LUA_ENVIRONINDEX) {
213 Closure *func = curr_func(L);
214 api_check(L, ttistable(L->top - 1));
215 func->c.env = hvalue(L->top - 1);
216 luaC_barrier(L, func, L->top - 1);
217 }
218 else {
219 setobj(L, o, L->top - 1);
220 if (idx < LUA_GLOBALSINDEX) /* function upvalue? */
221 luaC_barrier(L, curr_func(L), L->top - 1);
222 }
223 L->top--; 221 L->top--;
224 lua_unlock(L); 222 lua_unlock(L);
225} 223}
226 224
227 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
228LUA_API void lua_pushvalue (lua_State *L, int idx) { 235LUA_API void lua_pushvalue (lua_State *L, int idx) {
229 lua_lock(L); 236 lua_lock(L);
230 setobj2s(L, L->top, index2adr(L, idx)); 237 setobj2s(L, L->top, index2addr(L, idx));
231 api_incr_top(L); 238 api_incr_top(L);
232 lua_unlock(L); 239 lua_unlock(L);
233} 240}
@@ -240,26 +247,26 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) {
240 247
241 248
242LUA_API int lua_type (lua_State *L, int idx) { 249LUA_API int lua_type (lua_State *L, int idx) {
243 StkId o = index2adr(L, idx); 250 StkId o = index2addr(L, idx);
244 return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); 251 return (isvalid(o) ? ttypenv(o) : LUA_TNONE);
245} 252}
246 253
247 254
248LUA_API const char *lua_typename (lua_State *L, int t) { 255LUA_API const char *lua_typename (lua_State *L, int t) {
249 UNUSED(L); 256 UNUSED(L);
250 return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; 257 return ttypename(t);
251} 258}
252 259
253 260
254LUA_API int lua_iscfunction (lua_State *L, int idx) { 261LUA_API int lua_iscfunction (lua_State *L, int idx) {
255 StkId o = index2adr(L, idx); 262 StkId o = index2addr(L, idx);
256 return iscfunction(o); 263 return (ttislcf(o) || (ttisCclosure(o)));
257} 264}
258 265
259 266
260LUA_API int lua_isnumber (lua_State *L, int idx) { 267LUA_API int lua_isnumber (lua_State *L, int idx) {
261 TValue n; 268 TValue n;
262 const TValue *o = index2adr(L, idx); 269 const TValue *o = index2addr(L, idx);
263 return tonumber(o, &n); 270 return tonumber(o, &n);
264} 271}
265 272
@@ -271,77 +278,116 @@ LUA_API int lua_isstring (lua_State *L, int idx) {
271 278
272 279
273LUA_API int lua_isuserdata (lua_State *L, int idx) { 280LUA_API int lua_isuserdata (lua_State *L, int idx) {
274 const TValue *o = index2adr(L, idx); 281 const TValue *o = index2addr(L, idx);
275 return (ttisuserdata(o) || ttislightuserdata(o)); 282 return (ttisuserdata(o) || ttislightuserdata(o));
276} 283}
277 284
278 285
279LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { 286LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
280 StkId o1 = index2adr(L, index1); 287 StkId o1 = index2addr(L, index1);
281 StkId o2 = index2adr(L, index2); 288 StkId o2 = index2addr(L, index2);
282 return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 289 return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0;
283 : luaO_rawequalObj(o1, o2);
284} 290}
285 291
286 292
287LUA_API int lua_equal (lua_State *L, int index1, int index2) { 293LUA_API void lua_arith (lua_State *L, int op) {
288 StkId o1, o2; 294 StkId o1; /* 1st operand */
289 int i; 295 StkId o2; /* 2nd operand */
290 lua_lock(L); /* may call tag method */ 296 lua_lock(L);
291 o1 = index2adr(L, index1); 297 if (op != LUA_OPUNM) /* all other operations expect two operands */
292 o2 = index2adr(L, index2); 298 api_checknelems(L, 2);
293 i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2); 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--;
294 lua_unlock(L); 312 lua_unlock(L);
295 return i;
296} 313}
297 314
298 315
299LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { 316LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
300 StkId o1, o2; 317 StkId o1, o2;
301 int i; 318 int i = 0;
302 lua_lock(L); /* may call tag method */ 319 lua_lock(L); /* may call tag method */
303 o1 = index2adr(L, index1); 320 o1 = index2addr(L, index1);
304 o2 = index2adr(L, index2); 321 o2 = index2addr(L, index2);
305 i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 322 if (isvalid(o1) && isvalid(o2)) {
306 : luaV_lessthan(L, o1, 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 }
307 lua_unlock(L); 330 lua_unlock(L);
308 return i; 331 return i;
309} 332}
310 333
311 334
312 335LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum) {
313LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
314 TValue n; 336 TValue n;
315 const TValue *o = index2adr(L, idx); 337 const TValue *o = index2addr(L, idx);
316 if (tonumber(o, &n)) 338 if (tonumber(o, &n)) {
339 if (isnum) *isnum = 1;
317 return nvalue(o); 340 return nvalue(o);
318 else 341 }
342 else {
343 if (isnum) *isnum = 0;
319 return 0; 344 return 0;
345 }
320} 346}
321 347
322 348
323LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) { 349LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) {
324 TValue n; 350 TValue n;
325 const TValue *o = index2adr(L, idx); 351 const TValue *o = index2addr(L, idx);
326 if (tonumber(o, &n)) { 352 if (tonumber(o, &n)) {
327 lua_Integer res; 353 lua_Integer res;
328 lua_Number num = nvalue(o); 354 lua_Number num = nvalue(o);
329 lua_number2integer(res, num); 355 lua_number2integer(res, num);
356 if (isnum) *isnum = 1;
330 return res; 357 return res;
331 } 358 }
332 else 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;
333 return 0; 378 return 0;
379 }
334} 380}
335 381
336 382
337LUA_API int lua_toboolean (lua_State *L, int idx) { 383LUA_API int lua_toboolean (lua_State *L, int idx) {
338 const TValue *o = index2adr(L, idx); 384 const TValue *o = index2addr(L, idx);
339 return !l_isfalse(o); 385 return !l_isfalse(o);
340} 386}
341 387
342 388
343LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { 389LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
344 StkId o = index2adr(L, idx); 390 StkId o = index2addr(L, idx);
345 if (!ttisstring(o)) { 391 if (!ttisstring(o)) {
346 lua_lock(L); /* `luaV_tostring' may create a new string */ 392 lua_lock(L); /* `luaV_tostring' may create a new string */
347 if (!luaV_tostring(L, o)) { /* conversion failed? */ 393 if (!luaV_tostring(L, o)) { /* conversion failed? */
@@ -350,7 +396,7 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
350 return NULL; 396 return NULL;
351 } 397 }
352 luaC_checkGC(L); 398 luaC_checkGC(L);
353 o = index2adr(L, idx); /* previous call may reallocate the stack */ 399 o = index2addr(L, idx); /* previous call may reallocate the stack */
354 lua_unlock(L); 400 lua_unlock(L);
355 } 401 }
356 if (len != NULL) *len = tsvalue(o)->len; 402 if (len != NULL) *len = tsvalue(o)->len;
@@ -358,33 +404,29 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
358} 404}
359 405
360 406
361LUA_API size_t lua_objlen (lua_State *L, int idx) { 407LUA_API size_t lua_rawlen (lua_State *L, int idx) {
362 StkId o = index2adr(L, idx); 408 StkId o = index2addr(L, idx);
363 switch (ttype(o)) { 409 switch (ttypenv(o)) {
364 case LUA_TSTRING: return tsvalue(o)->len; 410 case LUA_TSTRING: return tsvalue(o)->len;
365 case LUA_TUSERDATA: return uvalue(o)->len; 411 case LUA_TUSERDATA: return uvalue(o)->len;
366 case LUA_TTABLE: return luaH_getn(hvalue(o)); 412 case LUA_TTABLE: return luaH_getn(hvalue(o));
367 case LUA_TNUMBER: {
368 size_t l;
369 lua_lock(L); /* `luaV_tostring' may create a new string */
370 l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
371 lua_unlock(L);
372 return l;
373 }
374 default: return 0; 413 default: return 0;
375 } 414 }
376} 415}
377 416
378 417
379LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { 418LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
380 StkId o = index2adr(L, idx); 419 StkId o = index2addr(L, idx);
381 return (!iscfunction(o)) ? NULL : clvalue(o)->c.f; 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 */
382} 424}
383 425
384 426
385LUA_API void *lua_touserdata (lua_State *L, int idx) { 427LUA_API void *lua_touserdata (lua_State *L, int idx) {
386 StkId o = index2adr(L, idx); 428 StkId o = index2addr(L, idx);
387 switch (ttype(o)) { 429 switch (ttypenv(o)) {
388 case LUA_TUSERDATA: return (rawuvalue(o) + 1); 430 case LUA_TUSERDATA: return (rawuvalue(o) + 1);
389 case LUA_TLIGHTUSERDATA: return pvalue(o); 431 case LUA_TLIGHTUSERDATA: return pvalue(o);
390 default: return NULL; 432 default: return NULL;
@@ -393,16 +435,18 @@ LUA_API void *lua_touserdata (lua_State *L, int idx) {
393 435
394 436
395LUA_API lua_State *lua_tothread (lua_State *L, int idx) { 437LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
396 StkId o = index2adr(L, idx); 438 StkId o = index2addr(L, idx);
397 return (!ttisthread(o)) ? NULL : thvalue(o); 439 return (!ttisthread(o)) ? NULL : thvalue(o);
398} 440}
399 441
400 442
401LUA_API const void *lua_topointer (lua_State *L, int idx) { 443LUA_API const void *lua_topointer (lua_State *L, int idx) {
402 StkId o = index2adr(L, idx); 444 StkId o = index2addr(L, idx);
403 switch (ttype(o)) { 445 switch (ttype(o)) {
404 case LUA_TTABLE: return hvalue(o); 446 case LUA_TTABLE: return hvalue(o);
405 case LUA_TFUNCTION: return clvalue(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)));
406 case LUA_TTHREAD: return thvalue(o); 450 case LUA_TTHREAD: return thvalue(o);
407 case LUA_TUSERDATA: 451 case LUA_TUSERDATA:
408 case LUA_TLIGHTUSERDATA: 452 case LUA_TLIGHTUSERDATA:
@@ -429,6 +473,8 @@ LUA_API void lua_pushnil (lua_State *L) {
429LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { 473LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
430 lua_lock(L); 474 lua_lock(L);
431 setnvalue(L->top, n); 475 setnvalue(L->top, n);
476 luai_checknum(L, L->top,
477 luaG_runerror(L, "C API - attempt to push a signaling NaN"));
432 api_incr_top(L); 478 api_incr_top(L);
433 lua_unlock(L); 479 lua_unlock(L);
434} 480}
@@ -442,20 +488,43 @@ LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
442} 488}
443 489
444 490
445LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { 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;
446 lua_lock(L); 503 lua_lock(L);
447 luaC_checkGC(L); 504 luaC_checkGC(L);
448 setsvalue2s(L, L->top, luaS_newlstr(L, s, len)); 505 ts = luaS_newlstr(L, s, len);
506 setsvalue2s(L, L->top, ts);
449 api_incr_top(L); 507 api_incr_top(L);
450 lua_unlock(L); 508 lua_unlock(L);
509 return getstr(ts);
451} 510}
452 511
453 512
454LUA_API void lua_pushstring (lua_State *L, const char *s) { 513LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
455 if (s == NULL) 514 if (s == NULL) {
456 lua_pushnil(L); 515 lua_pushnil(L);
457 else 516 return NULL;
458 lua_pushlstring(L, s, strlen(s)); 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 }
459} 528}
460 529
461 530
@@ -484,17 +553,22 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
484 553
485 554
486LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { 555LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
487 Closure *cl;
488 lua_lock(L); 556 lua_lock(L);
489 luaC_checkGC(L); 557 if (n == 0) {
490 api_checknelems(L, n); 558 setfvalue(L->top, fn);
491 cl = luaF_newCclosure(L, n, getcurrenv(L)); 559 }
492 cl->c.f = fn; 560 else {
493 L->top -= n; 561 Closure *cl;
494 while (n--) 562 api_checknelems(L, n);
495 setobj2n(L, &cl->c.upvalue[n], L->top+n); 563 api_check(L, n <= MAXUPVAL, "upvalue index too large");
496 setclvalue(L, L->top, cl); 564 luaC_checkGC(L);
497 lua_assert(iswhite(obj2gco(cl))); 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 }
498 api_incr_top(L); 572 api_incr_top(L);
499 lua_unlock(L); 573 lua_unlock(L);
500} 574}
@@ -531,11 +605,21 @@ LUA_API int lua_pushthread (lua_State *L) {
531*/ 605*/
532 606
533 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
534LUA_API void lua_gettable (lua_State *L, int idx) { 619LUA_API void lua_gettable (lua_State *L, int idx) {
535 StkId t; 620 StkId t;
536 lua_lock(L); 621 lua_lock(L);
537 t = index2adr(L, idx); 622 t = index2addr(L, idx);
538 api_checkvalidindex(L, t);
539 luaV_gettable(L, t, L->top - 1, L->top - 1); 623 luaV_gettable(L, t, L->top - 1, L->top - 1);
540 lua_unlock(L); 624 lua_unlock(L);
541} 625}
@@ -543,13 +627,11 @@ LUA_API void lua_gettable (lua_State *L, int idx) {
543 627
544LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { 628LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
545 StkId t; 629 StkId t;
546 TValue key;
547 lua_lock(L); 630 lua_lock(L);
548 t = index2adr(L, idx); 631 t = index2addr(L, idx);
549 api_checkvalidindex(L, t); 632 setsvalue2s(L, L->top, luaS_new(L, k));
550 setsvalue(L, &key, luaS_new(L, k));
551 luaV_gettable(L, t, &key, L->top);
552 api_incr_top(L); 633 api_incr_top(L);
634 luaV_gettable(L, t, L->top - 1, L->top - 1);
553 lua_unlock(L); 635 lua_unlock(L);
554} 636}
555 637
@@ -557,29 +639,46 @@ LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
557LUA_API void lua_rawget (lua_State *L, int idx) { 639LUA_API void lua_rawget (lua_State *L, int idx) {
558 StkId t; 640 StkId t;
559 lua_lock(L); 641 lua_lock(L);
560 t = index2adr(L, idx); 642 t = index2addr(L, idx);
561 api_check(L, ttistable(t)); 643 api_check(L, ttistable(t), "table expected");
562 setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); 644 setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
563 lua_unlock(L); 645 lua_unlock(L);
564} 646}
565 647
566 648
567LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { 649LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
568 StkId o; 650 StkId t;
569 lua_lock(L); 651 lua_lock(L);
570 o = index2adr(L, idx); 652 t = index2addr(L, idx);
571 api_check(L, ttistable(o)); 653 api_check(L, ttistable(t), "table expected");
572 setobj2s(L, L->top, luaH_getnum(hvalue(o), n)); 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));
573 api_incr_top(L); 668 api_incr_top(L);
574 lua_unlock(L); 669 lua_unlock(L);
575} 670}
576 671
577 672
578LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { 673LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
674 Table *t;
579 lua_lock(L); 675 lua_lock(L);
580 luaC_checkGC(L); 676 luaC_checkGC(L);
581 sethvalue(L, L->top, luaH_new(L, narray, nrec)); 677 t = luaH_new(L);
678 sethvalue(L, L->top, t);
582 api_incr_top(L); 679 api_incr_top(L);
680 if (narray > 0 || nrec > 0)
681 luaH_resize(L, t, narray, nrec);
583 lua_unlock(L); 682 lua_unlock(L);
584} 683}
585 684
@@ -589,8 +688,8 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
589 Table *mt = NULL; 688 Table *mt = NULL;
590 int res; 689 int res;
591 lua_lock(L); 690 lua_lock(L);
592 obj = index2adr(L, objindex); 691 obj = index2addr(L, objindex);
593 switch (ttype(obj)) { 692 switch (ttypenv(obj)) {
594 case LUA_TTABLE: 693 case LUA_TTABLE:
595 mt = hvalue(obj)->metatable; 694 mt = hvalue(obj)->metatable;
596 break; 695 break;
@@ -598,7 +697,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
598 mt = uvalue(obj)->metatable; 697 mt = uvalue(obj)->metatable;
599 break; 698 break;
600 default: 699 default:
601 mt = G(L)->mt[ttype(obj)]; 700 mt = G(L)->mt[ttypenv(obj)];
602 break; 701 break;
603 } 702 }
604 if (mt == NULL) 703 if (mt == NULL)
@@ -613,25 +712,15 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
613} 712}
614 713
615 714
616LUA_API void lua_getfenv (lua_State *L, int idx) { 715LUA_API void lua_getuservalue (lua_State *L, int idx) {
617 StkId o; 716 StkId o;
618 lua_lock(L); 717 lua_lock(L);
619 o = index2adr(L, idx); 718 o = index2addr(L, idx);
620 api_checkvalidindex(L, o); 719 api_check(L, ttisuserdata(o), "userdata expected");
621 switch (ttype(o)) { 720 if (uvalue(o)->env) {
622 case LUA_TFUNCTION: 721 sethvalue(L, L->top, uvalue(o)->env);
623 sethvalue(L, L->top, clvalue(o)->c.env); 722 } else
624 break; 723 setnilvalue(L->top);
625 case LUA_TUSERDATA:
626 sethvalue(L, L->top, uvalue(o)->env);
627 break;
628 case LUA_TTHREAD:
629 setobj2s(L, L->top, gt(thvalue(o)));
630 break;
631 default:
632 setnilvalue(L->top);
633 break;
634 }
635 api_incr_top(L); 724 api_incr_top(L);
636 lua_unlock(L); 725 lua_unlock(L);
637} 726}
@@ -642,12 +731,24 @@ LUA_API void lua_getfenv (lua_State *L, int idx) {
642*/ 731*/
643 732
644 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
645LUA_API void lua_settable (lua_State *L, int idx) { 747LUA_API void lua_settable (lua_State *L, int idx) {
646 StkId t; 748 StkId t;
647 lua_lock(L); 749 lua_lock(L);
648 api_checknelems(L, 2); 750 api_checknelems(L, 2);
649 t = index2adr(L, idx); 751 t = index2addr(L, idx);
650 api_checkvalidindex(L, t);
651 luaV_settable(L, t, L->top - 2, L->top - 1); 752 luaV_settable(L, t, L->top - 2, L->top - 1);
652 L->top -= 2; /* pop index and value */ 753 L->top -= 2; /* pop index and value */
653 lua_unlock(L); 754 lua_unlock(L);
@@ -656,14 +757,12 @@ LUA_API void lua_settable (lua_State *L, int idx) {
656 757
657LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { 758LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
658 StkId t; 759 StkId t;
659 TValue key;
660 lua_lock(L); 760 lua_lock(L);
661 api_checknelems(L, 1); 761 api_checknelems(L, 1);
662 t = index2adr(L, idx); 762 t = index2addr(L, idx);
663 api_checkvalidindex(L, t); 763 setsvalue2s(L, L->top++, luaS_new(L, k));
664 setsvalue(L, &key, luaS_new(L, k)); 764 luaV_settable(L, t, L->top - 1, L->top - 2);
665 luaV_settable(L, t, &key, L->top - 1); 765 L->top -= 2; /* pop value and key */
666 L->top--; /* pop value */
667 lua_unlock(L); 766 lua_unlock(L);
668} 767}
669 768
@@ -672,23 +771,39 @@ LUA_API void lua_rawset (lua_State *L, int idx) {
672 StkId t; 771 StkId t;
673 lua_lock(L); 772 lua_lock(L);
674 api_checknelems(L, 2); 773 api_checknelems(L, 2);
675 t = index2adr(L, idx); 774 t = index2addr(L, idx);
676 api_check(L, ttistable(t)); 775 api_check(L, ttistable(t), "table expected");
677 setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); 776 setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
678 luaC_barriert(L, hvalue(t), L->top-1); 777 invalidateTMcache(hvalue(t));
778 luaC_barrierback(L, gcvalue(t), L->top-1);
679 L->top -= 2; 779 L->top -= 2;
680 lua_unlock(L); 780 lua_unlock(L);
681} 781}
682 782
683 783
684LUA_API void lua_rawseti (lua_State *L, int idx, int n) { 784LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
685 StkId o; 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;
686 lua_lock(L); 800 lua_lock(L);
687 api_checknelems(L, 1); 801 api_checknelems(L, 1);
688 o = index2adr(L, idx); 802 t = index2addr(L, idx);
689 api_check(L, ttistable(o)); 803 api_check(L, ttistable(t), "table expected");
690 setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1); 804 setpvalue(&k, cast(void *, p));
691 luaC_barriert(L, hvalue(o), L->top-1); 805 setobj2t(L, luaH_set(L, hvalue(t), &k), L->top - 1);
806 luaC_barrierback(L, gcvalue(t), L->top - 1);
692 L->top--; 807 L->top--;
693 lua_unlock(L); 808 lua_unlock(L);
694} 809}
@@ -699,29 +814,32 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
699 Table *mt; 814 Table *mt;
700 lua_lock(L); 815 lua_lock(L);
701 api_checknelems(L, 1); 816 api_checknelems(L, 1);
702 obj = index2adr(L, objindex); 817 obj = index2addr(L, objindex);
703 api_checkvalidindex(L, obj);
704 if (ttisnil(L->top - 1)) 818 if (ttisnil(L->top - 1))
705 mt = NULL; 819 mt = NULL;
706 else { 820 else {
707 api_check(L, ttistable(L->top - 1)); 821 api_check(L, ttistable(L->top - 1), "table expected");
708 mt = hvalue(L->top - 1); 822 mt = hvalue(L->top - 1);
709 } 823 }
710 switch (ttype(obj)) { 824 switch (ttypenv(obj)) {
711 case LUA_TTABLE: { 825 case LUA_TTABLE: {
712 hvalue(obj)->metatable = mt; 826 hvalue(obj)->metatable = mt;
713 if (mt) 827 if (mt) {
714 luaC_objbarriert(L, hvalue(obj), mt); 828 luaC_objbarrierback(L, gcvalue(obj), mt);
829 luaC_checkfinalizer(L, gcvalue(obj), mt);
830 }
715 break; 831 break;
716 } 832 }
717 case LUA_TUSERDATA: { 833 case LUA_TUSERDATA: {
718 uvalue(obj)->metatable = mt; 834 uvalue(obj)->metatable = mt;
719 if (mt) 835 if (mt) {
720 luaC_objbarrier(L, rawuvalue(obj), mt); 836 luaC_objbarrier(L, rawuvalue(obj), mt);
837 luaC_checkfinalizer(L, gcvalue(obj), mt);
838 }
721 break; 839 break;
722 } 840 }
723 default: { 841 default: {
724 G(L)->mt[ttype(obj)] = mt; 842 G(L)->mt[ttypenv(obj)] = mt;
725 break; 843 break;
726 } 844 }
727 } 845 }
@@ -731,32 +849,21 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
731} 849}
732 850
733 851
734LUA_API int lua_setfenv (lua_State *L, int idx) { 852LUA_API void lua_setuservalue (lua_State *L, int idx) {
735 StkId o; 853 StkId o;
736 int res = 1;
737 lua_lock(L); 854 lua_lock(L);
738 api_checknelems(L, 1); 855 api_checknelems(L, 1);
739 o = index2adr(L, idx); 856 o = index2addr(L, idx);
740 api_checkvalidindex(L, o); 857 api_check(L, ttisuserdata(o), "userdata expected");
741 api_check(L, ttistable(L->top - 1)); 858 if (ttisnil(L->top - 1))
742 switch (ttype(o)) { 859 uvalue(o)->env = NULL;
743 case LUA_TFUNCTION: 860 else {
744 clvalue(o)->c.env = hvalue(L->top - 1); 861 api_check(L, ttistable(L->top - 1), "table expected");
745 break; 862 uvalue(o)->env = hvalue(L->top - 1);
746 case LUA_TUSERDATA: 863 luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
747 uvalue(o)->env = hvalue(L->top - 1);
748 break;
749 case LUA_TTHREAD:
750 sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1));
751 break;
752 default:
753 res = 0;
754 break;
755 } 864 }
756 if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
757 L->top--; 865 L->top--;
758 lua_unlock(L); 866 lua_unlock(L);
759 return res;
760} 867}
761 868
762 869
@@ -765,21 +872,37 @@ LUA_API int lua_setfenv (lua_State *L, int idx) {
765*/ 872*/
766 873
767 874
768#define adjustresults(L,nres) \ 875#define checkresults(L,na,nr) \
769 { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; } 876 api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
877 "results from function overflow current stack size")
770 878
771 879
772#define checkresults(L,na,nr) \ 880LUA_API int lua_getctx (lua_State *L, int *ctx) {
773 api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) 881 if (L->ci->callstatus & CIST_YIELDED) {
774 882 if (ctx) *ctx = L->ci->u.c.ctx;
883 return L->ci->u.c.status;
884 }
885 else return LUA_OK;
886}
775 887
776LUA_API void lua_call (lua_State *L, int nargs, int nresults) { 888
889LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx,
890 lua_CFunction k) {
777 StkId func; 891 StkId func;
778 lua_lock(L); 892 lua_lock(L);
893 api_check(L, k == NULL || !isLua(L->ci),
894 "cannot use continuations inside hooks");
779 api_checknelems(L, nargs+1); 895 api_checknelems(L, nargs+1);
896 api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
780 checkresults(L, nargs, nresults); 897 checkresults(L, nargs, nresults);
781 func = L->top - (nargs+1); 898 func = L->top - (nargs+1);
782 luaD_call(L, func, nresults); 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 */
783 adjustresults(L, nresults); 906 adjustresults(L, nresults);
784 lua_unlock(L); 907 lua_unlock(L);
785} 908}
@@ -797,76 +920,75 @@ struct CallS { /* data to `f_call' */
797 920
798static void f_call (lua_State *L, void *ud) { 921static void f_call (lua_State *L, void *ud) {
799 struct CallS *c = cast(struct CallS *, ud); 922 struct CallS *c = cast(struct CallS *, ud);
800 luaD_call(L, c->func, c->nresults); 923 luaD_call(L, c->func, c->nresults, 0);
801} 924}
802 925
803 926
804 927
805LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { 928LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
929 int ctx, lua_CFunction k) {
806 struct CallS c; 930 struct CallS c;
807 int status; 931 int status;
808 ptrdiff_t func; 932 ptrdiff_t func;
809 lua_lock(L); 933 lua_lock(L);
934 api_check(L, k == NULL || !isLua(L->ci),
935 "cannot use continuations inside hooks");
810 api_checknelems(L, nargs+1); 936 api_checknelems(L, nargs+1);
937 api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
811 checkresults(L, nargs, nresults); 938 checkresults(L, nargs, nresults);
812 if (errfunc == 0) 939 if (errfunc == 0)
813 func = 0; 940 func = 0;
814 else { 941 else {
815 StkId o = index2adr(L, errfunc); 942 StkId o = index2addr(L, errfunc);
816 api_checkvalidindex(L, o); 943 api_checkstackindex(L, errfunc, o);
817 func = savestack(L, o); 944 func = savestack(L, o);
818 } 945 }
819 c.func = L->top - (nargs+1); /* function to be called */ 946 c.func = L->top - (nargs+1); /* function to be called */
820 c.nresults = nresults; 947 if (k == NULL || L->nny > 0) { /* no continuation or no yieldable? */
821 status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); 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 }
822 adjustresults(L, nresults); 967 adjustresults(L, nresults);
823 lua_unlock(L); 968 lua_unlock(L);
824 return status; 969 return status;
825} 970}
826 971
827 972
828/*
829** Execute a protected C call.
830*/
831struct CCallS { /* data to `f_Ccall' */
832 lua_CFunction func;
833 void *ud;
834};
835
836
837static void f_Ccall (lua_State *L, void *ud) {
838 struct CCallS *c = cast(struct CCallS *, ud);
839 Closure *cl;
840 cl = luaF_newCclosure(L, 0, getcurrenv(L));
841 cl->c.f = c->func;
842 setclvalue(L, L->top, cl); /* push function */
843 api_incr_top(L);
844 setpvalue(L->top, c->ud); /* push only argument */
845 api_incr_top(L);
846 luaD_call(L, L->top - 2, 0);
847}
848
849
850LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
851 struct CCallS c;
852 int status;
853 lua_lock(L);
854 c.func = func;
855 c.ud = ud;
856 status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
857 lua_unlock(L);
858 return status;
859}
860
861
862LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, 973LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
863 const char *chunkname) { 974 const char *chunkname, const char *mode) {
864 ZIO z; 975 ZIO z;
865 int status; 976 int status;
866 lua_lock(L); 977 lua_lock(L);
867 if (!chunkname) chunkname = "?"; 978 if (!chunkname) chunkname = "?";
868 luaZ_init(L, &z, reader, data); 979 luaZ_init(L, &z, reader, data);
869 status = luaD_protectedparser(L, &z, chunkname); 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 }
870 lua_unlock(L); 992 lua_unlock(L);
871 return status; 993 return status;
872} 994}
@@ -879,7 +1001,7 @@ LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
879 api_checknelems(L, 1); 1001 api_checknelems(L, 1);
880 o = L->top - 1; 1002 o = L->top - 1;
881 if (isLfunction(o)) 1003 if (isLfunction(o))
882 status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0); 1004 status = luaU_dump(L, getproto(o), writer, data, 0);
883 else 1005 else
884 status = 1; 1006 status = 1;
885 lua_unlock(L); 1007 lua_unlock(L);
@@ -887,7 +1009,7 @@ LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
887} 1009}
888 1010
889 1011
890LUA_API int lua_status (lua_State *L) { 1012LUA_API int lua_status (lua_State *L) {
891 return L->status; 1013 return L->status;
892} 1014}
893 1015
@@ -903,38 +1025,40 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
903 g = G(L); 1025 g = G(L);
904 switch (what) { 1026 switch (what) {
905 case LUA_GCSTOP: { 1027 case LUA_GCSTOP: {
906 g->GCthreshold = MAX_LUMEM; 1028 g->gcrunning = 0;
907 break; 1029 break;
908 } 1030 }
909 case LUA_GCRESTART: { 1031 case LUA_GCRESTART: {
910 g->GCthreshold = g->totalbytes; 1032 luaE_setdebt(g, 0);
1033 g->gcrunning = 1;
911 break; 1034 break;
912 } 1035 }
913 case LUA_GCCOLLECT: { 1036 case LUA_GCCOLLECT: {
914 luaC_fullgc(L); 1037 luaC_fullgc(L, 0);
915 break; 1038 break;
916 } 1039 }
917 case LUA_GCCOUNT: { 1040 case LUA_GCCOUNT: {
918 /* GC values are expressed in Kbytes: #bytes/2^10 */ 1041 /* GC values are expressed in Kbytes: #bytes/2^10 */
919 res = cast_int(g->totalbytes >> 10); 1042 res = cast_int(gettotalbytes(g) >> 10);
920 break; 1043 break;
921 } 1044 }
922 case LUA_GCCOUNTB: { 1045 case LUA_GCCOUNTB: {
923 res = cast_int(g->totalbytes & 0x3ff); 1046 res = cast_int(gettotalbytes(g) & 0x3ff);
924 break; 1047 break;
925 } 1048 }
926 case LUA_GCSTEP: { 1049 case LUA_GCSTEP: {
927 lu_mem a = (cast(lu_mem, data) << 10); 1050 if (g->gckind == KGC_GEN) { /* generational mode? */
928 if (a <= g->totalbytes) 1051 res = (g->GCestimate == 0); /* true if it will do major collection */
929 g->GCthreshold = g->totalbytes - a; 1052 luaC_forcestep(L); /* do a single step */
930 else 1053 }
931 g->GCthreshold = 0; 1054 else {
932 while (g->GCthreshold <= g->totalbytes) { 1055 lu_mem debt = cast(lu_mem, data) * 1024 - GCSTEPSIZE;
933 luaC_step(L); 1056 if (g->gcrunning)
934 if (g->gcstate == GCSpause) { /* end of cycle? */ 1057 debt += g->GCdebt; /* include current debt */
935 res = 1; /* signal it */ 1058 luaE_setdebt(g, debt);
936 break; 1059 luaC_forcestep(L);
937 } 1060 if (g->gcstate == GCSpause) /* end of cycle? */
1061 res = 1; /* signal it */
938 } 1062 }
939 break; 1063 break;
940 } 1064 }
@@ -943,11 +1067,28 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
943 g->gcpause = data; 1067 g->gcpause = data;
944 break; 1068 break;
945 } 1069 }
1070 case LUA_GCSETMAJORINC: {
1071 res = g->gcmajorinc;
1072 g->gcmajorinc = data;
1073 break;
1074 }
946 case LUA_GCSETSTEPMUL: { 1075 case LUA_GCSETSTEPMUL: {
947 res = g->gcstepmul; 1076 res = g->gcstepmul;
948 g->gcstepmul = data; 1077 g->gcstepmul = data;
949 break; 1078 break;
950 } 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 }
951 default: res = -1; /* invalid option */ 1092 default: res = -1; /* invalid option */
952 } 1093 }
953 lua_unlock(L); 1094 lua_unlock(L);
@@ -965,7 +1106,7 @@ LUA_API int lua_error (lua_State *L) {
965 lua_lock(L); 1106 lua_lock(L);
966 api_checknelems(L, 1); 1107 api_checknelems(L, 1);
967 luaG_errormsg(L); 1108 luaG_errormsg(L);
968 lua_unlock(L); 1109 /* code unreachable; will unlock when control actually leaves the kernel */
969 return 0; /* to avoid warnings */ 1110 return 0; /* to avoid warnings */
970} 1111}
971 1112
@@ -974,8 +1115,8 @@ LUA_API int lua_next (lua_State *L, int idx) {
974 StkId t; 1115 StkId t;
975 int more; 1116 int more;
976 lua_lock(L); 1117 lua_lock(L);
977 t = index2adr(L, idx); 1118 t = index2addr(L, idx);
978 api_check(L, ttistable(t)); 1119 api_check(L, ttistable(t), "table expected");
979 more = luaH_next(L, hvalue(t), L->top - 1); 1120 more = luaH_next(L, hvalue(t), L->top - 1);
980 if (more) { 1121 if (more) {
981 api_incr_top(L); 1122 api_incr_top(L);
@@ -992,8 +1133,7 @@ LUA_API void lua_concat (lua_State *L, int n) {
992 api_checknelems(L, n); 1133 api_checknelems(L, n);
993 if (n >= 2) { 1134 if (n >= 2) {
994 luaC_checkGC(L); 1135 luaC_checkGC(L);
995 luaV_concat(L, n, cast_int(L->top - L->base) - 1); 1136 luaV_concat(L, n);
996 L->top -= (n-1);
997 } 1137 }
998 else if (n == 0) { /* push empty string */ 1138 else if (n == 0) { /* push empty string */
999 setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); 1139 setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
@@ -1004,6 +1144,16 @@ LUA_API void lua_concat (lua_State *L, int n) {
1004} 1144}
1005 1145
1006 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
1007LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { 1157LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
1008 lua_Alloc f; 1158 lua_Alloc f;
1009 lua_lock(L); 1159 lua_lock(L);
@@ -1026,7 +1176,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
1026 Udata *u; 1176 Udata *u;
1027 lua_lock(L); 1177 lua_lock(L);
1028 luaC_checkGC(L); 1178 luaC_checkGC(L);
1029 u = luaS_newudata(L, size, getcurrenv(L)); 1179 u = luaS_newudata(L, size, NULL);
1030 setuvalue(L, L->top, u); 1180 setuvalue(L, L->top, u);
1031 api_incr_top(L); 1181 api_incr_top(L);
1032 lua_unlock(L); 1182 lua_unlock(L);
@@ -1035,30 +1185,36 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
1035 1185
1036 1186
1037 1187
1038 1188static const char *aux_upvalue (StkId fi, int n, TValue **val,
1039static const char *aux_upvalue (StkId fi, int n, TValue **val) { 1189 GCObject **owner) {
1040 Closure *f; 1190 switch (ttype(fi)) {
1041 if (!ttisfunction(fi)) return NULL; 1191 case LUA_TCCL: { /* C closure */
1042 f = clvalue(fi); 1192 CClosure *f = clCvalue(fi);
1043 if (f->c.isC) { 1193 if (!(1 <= n && n <= f->nupvalues)) return NULL;
1044 if (!(1 <= n && n <= f->c.nupvalues)) return NULL; 1194 *val = &f->upvalue[n-1];
1045 *val = &f->c.upvalue[n-1]; 1195 if (owner) *owner = obj2gco(f);
1046 return ""; 1196 return "";
1047 } 1197 }
1048 else { 1198 case LUA_TLCL: { /* Lua closure */
1049 Proto *p = f->l.p; 1199 LClosure *f = clLvalue(fi);
1050 if (!(1 <= n && n <= p->sizeupvalues)) return NULL; 1200 TString *name;
1051 *val = f->l.upvals[n-1]->v; 1201 Proto *p = f->p;
1052 return getstr(p->upvalues[n-1]); 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 */
1053 } 1209 }
1054} 1210}
1055 1211
1056 1212
1057LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { 1213LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
1058 const char *name; 1214 const char *name;
1059 TValue *val; 1215 TValue *val = NULL; /* to avoid warnings */
1060 lua_lock(L); 1216 lua_lock(L);
1061 name = aux_upvalue(index2adr(L, funcindex), n, &val); 1217 name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL);
1062 if (name) { 1218 if (name) {
1063 setobj2s(L, L->top, val); 1219 setobj2s(L, L->top, val);
1064 api_incr_top(L); 1220 api_incr_top(L);
@@ -1070,18 +1226,59 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
1070 1226
1071LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { 1227LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
1072 const char *name; 1228 const char *name;
1073 TValue *val; 1229 TValue *val = NULL; /* to avoid warnings */
1230 GCObject *owner = NULL; /* to avoid warnings */
1074 StkId fi; 1231 StkId fi;
1075 lua_lock(L); 1232 lua_lock(L);
1076 fi = index2adr(L, funcindex); 1233 fi = index2addr(L, funcindex);
1077 api_checknelems(L, 1); 1234 api_checknelems(L, 1);
1078 name = aux_upvalue(fi, n, &val); 1235 name = aux_upvalue(fi, n, &val, &owner);
1079 if (name) { 1236 if (name) {
1080 L->top--; 1237 L->top--;
1081 setobj(L, val, L->top); 1238 setobj(L, val, L->top);
1082 luaC_barrier(L, clvalue(fi), L->top); 1239 luaC_barrier(L, owner, L->top);
1083 } 1240 }
1084 lua_unlock(L); 1241 lua_unlock(L);
1085 return name; 1242 return name;
1086} 1243}
1087 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
diff --git a/apps/plugins/lua/lapi.h b/apps/plugins/lua/lapi.h
index f968ffc992..c7d34ad848 100644
--- a/apps/plugins/lua/lapi.h
+++ b/apps/plugins/lua/lapi.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: lapi.h,v 2.7.1.1 2013/04/12 18:48:47 roberto Exp $
3** Auxiliary functions from Lua API 3** Auxiliary functions from Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -8,9 +8,17 @@
8#define lapi_h 8#define lapi_h
9 9
10 10
11#include "lobject.h" 11#include "llimits.h"
12#include "lstate.h"
12 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")
13 22
14LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o);
15 23
16#endif 24#endif
diff --git a/apps/plugins/lua/lauxlib.c b/apps/plugins/lua/lauxlib.c
index b8020b7475..f451fb7c9e 100644
--- a/apps/plugins/lua/lauxlib.c
+++ b/apps/plugins/lua/lauxlib.c
@@ -1,11 +1,10 @@
1/* 1/*
2** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $ 2** $Id: lauxlib.c,v 1.248.1.1 2013/04/12 18:48:47 roberto Exp $
3** Auxiliary functions for building Lua libraries 3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
6 6
7 7
8#include <ctype.h>
9#include <errno.h> 8#include <errno.h>
10#include <stdarg.h> 9#include <stdarg.h>
11#include <stdio.h> 10#include <stdio.h>
@@ -23,14 +22,127 @@
23#include "lua.h" 22#include "lua.h"
24 23
25#include "lauxlib.h" 24#include "lauxlib.h"
25#include "rocklibc.h"
26 26
27 27
28#define FREELIST_REF 0 /* free list of references */ 28/*
29** {======================================================
30** Traceback
31** =======================================================
32*/
33
34
35#define LEVELS1 12 /* size of the first part of the stack */
36#define LEVELS2 10 /* size of the second part of the stack */
37
38
39
40/*
41** search for 'objidx' in table at index -1.
42** return 1 + string at top if find a good name.
43*/
44static int findfield (lua_State *L, int objidx, int level) {
45 if (level == 0 || !lua_istable(L, -1))
46 return 0; /* not found */
47 lua_pushnil(L); /* start 'next' loop */
48 while (lua_next(L, -2)) { /* for each pair in table */
49 if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */
50 if (lua_rawequal(L, objidx, -1)) { /* found object? */
51 lua_pop(L, 1); /* remove value (but keep name) */
52 return 1;
53 }
54 else if (findfield(L, objidx, level - 1)) { /* try recursively */
55 lua_remove(L, -2); /* remove table (but keep name) */
56 lua_pushliteral(L, ".");
57 lua_insert(L, -2); /* place '.' between the two names */
58 lua_concat(L, 3);
59 return 1;
60 }
61 }
62 lua_pop(L, 1); /* remove value */
63 }
64 return 0; /* not found */
65}
66
67
68static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
69 int top = lua_gettop(L);
70 lua_getinfo(L, "f", ar); /* push function */
71 lua_pushglobaltable(L);
72 if (findfield(L, top + 1, 2)) {
73 lua_copy(L, -1, top + 1); /* move name to proper place */
74 lua_pop(L, 2); /* remove pushed values */
75 return 1;
76 }
77 else {
78 lua_settop(L, top); /* remove function and global table */
79 return 0;
80 }
81}
82
83
84static void pushfuncname (lua_State *L, lua_Debug *ar) {
85 if (*ar->namewhat != '\0') /* is there a name? */
86 lua_pushfstring(L, "function " LUA_QS, ar->name);
87 else if (*ar->what == 'm') /* main? */
88 lua_pushliteral(L, "main chunk");
89 else if (*ar->what == 'C') {
90 if (pushglobalfuncname(L, ar)) {
91 lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
92 lua_remove(L, -2); /* remove name */
93 }
94 else
95 lua_pushliteral(L, "?");
96 }
97 else
98 lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
99}
29 100
30 101
31/* convert a stack index to positive */ 102static int countlevels (lua_State *L) {
32#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ 103 lua_Debug ar;
33 lua_gettop(L) + (i) + 1) 104 int li = 1, le = 1;
105 /* find an upper bound */
106 while (lua_getstack(L, le, &ar)) { li = le; le *= 2; }
107 /* do a binary search */
108 while (li < le) {
109 int m = (li + le)/2;
110 if (lua_getstack(L, m, &ar)) li = m + 1;
111 else le = m;
112 }
113 return le - 1;
114}
115
116
117LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1,
118 const char *msg, int level) {
119 lua_Debug ar;
120 int top = lua_gettop(L);
121 int numlevels = countlevels(L1);
122 int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0;
123 if (msg) lua_pushfstring(L, "%s\n", msg);
124 lua_pushliteral(L, "stack traceback:");
125 while (lua_getstack(L1, level++, &ar)) {
126 if (level == mark) { /* too many levels? */
127 lua_pushliteral(L, "\n\t..."); /* add a '...' */
128 level = numlevels - LEVELS2; /* and skip to last ones */
129 }
130 else {
131 lua_getinfo(L1, "Slnt", &ar);
132 lua_pushfstring(L, "\n\t%s:", ar.short_src);
133 if (ar.currentline > 0)
134 lua_pushfstring(L, "%d:", ar.currentline);
135 lua_pushliteral(L, " in ");
136 pushfuncname(L, &ar);
137 if (ar.istailcall)
138 lua_pushliteral(L, "\n\t(...tail calls...)");
139 lua_concat(L, lua_gettop(L) - top);
140 }
141 }
142 lua_concat(L, lua_gettop(L) - top);
143}
144
145/* }====================================================== */
34 146
35 147
36/* 148/*
@@ -39,7 +151,6 @@
39** ======================================================= 151** =======================================================
40*/ 152*/
41 153
42
43LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { 154LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
44 lua_Debug ar; 155 lua_Debug ar;
45 if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ 156 if (!lua_getstack(L, 0, &ar)) /* no stack frame? */
@@ -52,13 +163,13 @@ LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
52 ar.name, extramsg); 163 ar.name, extramsg);
53 } 164 }
54 if (ar.name == NULL) 165 if (ar.name == NULL)
55 ar.name = "?"; 166 ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?";
56 return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", 167 return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
57 narg, ar.name, extramsg); 168 narg, ar.name, extramsg);
58} 169}
59 170
60 171
61LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { 172static int typeerror (lua_State *L, int narg, const char *tname) {
62 const char *msg = lua_pushfstring(L, "%s expected, got %s", 173 const char *msg = lua_pushfstring(L, "%s expected, got %s",
63 tname, luaL_typename(L, narg)); 174 tname, luaL_typename(L, narg));
64 return luaL_argerror(L, narg, msg); 175 return luaL_argerror(L, narg, msg);
@@ -66,7 +177,7 @@ LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {
66 177
67 178
68static void tag_error (lua_State *L, int narg, int tag) { 179static void tag_error (lua_State *L, int narg, int tag) {
69 luaL_typerror(L, narg, lua_typename(L, tag)); 180 typeerror(L, narg, lua_typename(L, tag));
70} 181}
71 182
72 183
@@ -93,24 +204,74 @@ LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
93 return lua_error(L); 204 return lua_error(L);
94} 205}
95 206
96/* }====================================================== */
97 207
208LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
209 int en = errno; /* calls to Lua API may change this value */
210 if (stat) {
211 lua_pushboolean(L, 1);
212 return 1;
213 }
214 else {
215 lua_pushnil(L);
216 if (fname)
217 lua_pushfstring(L, "%s: %s", fname, strerror(en));
218 else
219 lua_pushstring(L, strerror(en));
220 lua_pushinteger(L, en);
221 return 3;
222 }
223}
98 224
99LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, 225
100 const char *const lst[]) { 226#if !defined(inspectstat) /* { */
101 const char *name = (def) ? luaL_optstring(L, narg, def) : 227
102 luaL_checkstring(L, narg); 228#if defined(LUA_USE_POSIX)
103 int i; 229
104 for (i=0; lst[i]; i++) 230#include <sys/wait.h>
105 if (strcmp(lst[i], name) == 0) 231
106 return i; 232/*
107 return luaL_argerror(L, narg, 233** use appropriate macros to interpret 'pclose' return status
108 lua_pushfstring(L, "invalid option " LUA_QS, name)); 234*/
235#define inspectstat(stat,what) \
236 if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \
237 else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; }
238
239#else
240
241#define inspectstat(stat,what) /* no op */
242
243#endif
244
245#endif /* } */
246
247
248LUALIB_API int luaL_execresult (lua_State *L, int stat) {
249 const char *what = "exit"; /* type of termination */
250 if (stat == -1) /* error? */
251 return luaL_fileresult(L, 0, NULL);
252 else {
253 inspectstat(stat, what); /* interpret result */
254 if (*what == 'e' && stat == 0) /* successful termination? */
255 lua_pushboolean(L, 1);
256 else
257 lua_pushnil(L);
258 lua_pushstring(L, what);
259 lua_pushinteger(L, stat);
260 return 3; /* return true/nil,what,code */
261 }
109} 262}
110 263
264/* }====================================================== */
265
266
267/*
268** {======================================================
269** Userdata's metatable manipulation
270** =======================================================
271*/
111 272
112LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { 273LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
113 lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */ 274 luaL_getmetatable(L, tname); /* try to get metatable */
114 if (!lua_isnil(L, -1)) /* name already in use? */ 275 if (!lua_isnil(L, -1)) /* name already in use? */
115 return 0; /* leave previous value on top, but return 0 */ 276 return 0; /* leave previous value on top, but return 0 */
116 lua_pop(L, 1); 277 lua_pop(L, 1);
@@ -121,25 +282,64 @@ LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
121} 282}
122 283
123 284
124LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { 285LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) {
286 luaL_getmetatable(L, tname);
287 lua_setmetatable(L, -2);
288}
289
290
291LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
125 void *p = lua_touserdata(L, ud); 292 void *p = lua_touserdata(L, ud);
126 if (p != NULL) { /* value is a userdata? */ 293 if (p != NULL) { /* value is a userdata? */
127 if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ 294 if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
128 lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ 295 luaL_getmetatable(L, tname); /* get correct metatable */
129 if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */ 296 if (!lua_rawequal(L, -1, -2)) /* not the same? */
130 lua_pop(L, 2); /* remove both metatables */ 297 p = NULL; /* value is a userdata with wrong metatable */
131 return p; 298 lua_pop(L, 2); /* remove both metatables */
132 } 299 return p;
133 } 300 }
134 } 301 }
135 luaL_typerror(L, ud, tname); /* else error */ 302 return NULL; /* value is not a userdata with a metatable */
136 return NULL; /* to avoid warnings */
137} 303}
138 304
139 305
140LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) { 306LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
141 if (!lua_checkstack(L, space)) 307 void *p = luaL_testudata(L, ud, tname);
142 luaL_error(L, "stack overflow (%s)", mes); 308 if (p == NULL) typeerror(L, ud, tname);
309 return p;
310}
311
312/* }====================================================== */
313
314
315/*
316** {======================================================
317** Argument check functions
318** =======================================================
319*/
320
321LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
322 const char *const lst[]) {
323 const char *name = (def) ? luaL_optstring(L, narg, def) :
324 luaL_checkstring(L, narg);
325 int i;
326 for (i=0; lst[i]; i++)
327 if (strcmp(lst[i], name) == 0)
328 return i;
329 return luaL_argerror(L, narg,
330 lua_pushfstring(L, "invalid option " LUA_QS, name));
331}
332
333
334LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
335 /* keep some extra space to run error routines, if needed */
336 const int extra = LUA_MINSTACK;
337 if (!lua_checkstack(L, space + extra)) {
338 if (msg)
339 luaL_error(L, "stack overflow (%s)", msg);
340 else
341 luaL_error(L, "stack overflow");
342 }
143} 343}
144 344
145 345
@@ -174,8 +374,9 @@ LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
174 374
175 375
176LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { 376LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
177 lua_Number d = lua_tonumber(L, narg); 377 int isnum;
178 if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ 378 lua_Number d = lua_tonumberx(L, narg, &isnum);
379 if (!isnum)
179 tag_error(L, narg, LUA_TNUMBER); 380 tag_error(L, narg, LUA_TNUMBER);
180 return d; 381 return d;
181} 382}
@@ -187,268 +388,79 @@ LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
187 388
188 389
189LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { 390LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
190 lua_Integer d = lua_tointeger(L, narg); 391 int isnum;
191 if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ 392 lua_Integer d = lua_tointegerx(L, narg, &isnum);
393 if (!isnum)
192 tag_error(L, narg, LUA_TNUMBER); 394 tag_error(L, narg, LUA_TNUMBER);
193 return d; 395 return d;
194} 396}
195 397
196 398
197LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, 399LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int narg) {
198 lua_Integer def) { 400 int isnum;
199 return luaL_opt(L, luaL_checkinteger, narg, def); 401 lua_Unsigned d = lua_tounsignedx(L, narg, &isnum);
200} 402 if (!isnum)
201 403 tag_error(L, narg, LUA_TNUMBER);
202 404 return d;
203LUALIB_API int luaL_checkboolean (lua_State *L, int narg) {
204 int b = lua_toboolean(L, narg);
205 if( b == 0 && !lua_isboolean(L, narg))
206 tag_error(L, narg, LUA_TBOOLEAN);
207 return b;
208}
209
210
211LUALIB_API int luaL_optboolean (lua_State *L, int narg, int def) {
212 return luaL_opt(L, luaL_checkboolean, narg, def);
213}
214
215
216LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
217 if (!lua_getmetatable(L, obj)) /* no metatable? */
218 return 0;
219 lua_pushstring(L, event);
220 lua_rawget(L, -2);
221 if (lua_isnil(L, -1)) {
222 lua_pop(L, 2); /* remove metatable and metafield */
223 return 0;
224 }
225 else {
226 lua_remove(L, -2); /* remove only metatable */
227 return 1;
228 }
229}
230
231
232LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
233 obj = abs_index(L, obj);
234 if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
235 return 0;
236 lua_pushvalue(L, obj);
237 lua_call(L, 1, 1);
238 return 1;
239}
240
241
242LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
243 const luaL_Reg *l) {
244 luaI_openlib(L, libname, l, 0);
245}
246
247
248static int libsize (const luaL_Reg *l) {
249 int size = 0;
250 for (; l->name; l++) size++;
251 return size;
252}
253
254
255LUALIB_API void luaI_openlib (lua_State *L, const char *libname,
256 const luaL_Reg *l, int nup) {
257 if (libname) {
258 int size = libsize(l);
259 /* check whether lib already exists */
260 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);
261 lua_getfield(L, -1, libname); /* get _LOADED[libname] */
262 if (!lua_istable(L, -1)) { /* not found? */
263 lua_pop(L, 1); /* remove previous result */
264 /* try global variable (and create one if it does not exist) */
265 if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL)
266 luaL_error(L, "name conflict for module " LUA_QS, libname);
267 lua_pushvalue(L, -1);
268 lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
269 }
270 lua_remove(L, -2); /* remove _LOADED table */
271 lua_insert(L, -(nup+1)); /* move library table to below upvalues */
272 }
273 for (; l->name; l++) {
274 int i;
275 for (i=0; i<nup; i++) /* copy upvalues to the top */
276 lua_pushvalue(L, -nup);
277 lua_pushcclosure(L, l->func, nup);
278 lua_setfield(L, -(nup+2), l->name);
279 }
280 lua_pop(L, nup); /* remove upvalues */
281}
282
283
284
285/*
286** {======================================================
287** getn-setn: size for arrays
288** =======================================================
289*/
290
291#if defined(LUA_COMPAT_GETN)
292
293static int checkint (lua_State *L, int topop) {
294 int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1;
295 lua_pop(L, topop);
296 return n;
297}
298
299
300static void getsizes (lua_State *L) {
301 lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES");
302 if (lua_isnil(L, -1)) { /* no `size' table? */
303 lua_pop(L, 1); /* remove nil */
304 lua_newtable(L); /* create it */
305 lua_pushvalue(L, -1); /* `size' will be its own metatable */
306 lua_setmetatable(L, -2);
307 lua_pushliteral(L, "kv");
308 lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */
309 lua_pushvalue(L, -1);
310 lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */
311 }
312} 405}
313 406
314 407
315LUALIB_API void luaL_setn (lua_State *L, int t, int n) { 408LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
316 t = abs_index(L, t); 409 lua_Integer def) {
317 lua_pushliteral(L, "n"); 410 return luaL_opt(L, luaL_checkinteger, narg, def);
318 lua_rawget(L, t);
319 if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */
320 lua_pushliteral(L, "n"); /* use it */
321 lua_pushinteger(L, n);
322 lua_rawset(L, t);
323 }
324 else { /* use `sizes' */
325 getsizes(L);
326 lua_pushvalue(L, t);
327 lua_pushinteger(L, n);
328 lua_rawset(L, -3); /* sizes[t] = n */
329 lua_pop(L, 1); /* remove `sizes' */
330 }
331} 411}
332 412
333 413
334LUALIB_API int luaL_getn (lua_State *L, int t) { 414LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int narg,
335 int n; 415 lua_Unsigned def) {
336 t = abs_index(L, t); 416 return luaL_opt(L, luaL_checkunsigned, narg, def);
337 lua_pushliteral(L, "n"); /* try t.n */
338 lua_rawget(L, t);
339 if ((n = checkint(L, 1)) >= 0) return n;
340 getsizes(L); /* else try sizes[t] */
341 lua_pushvalue(L, t);
342 lua_rawget(L, -2);
343 if ((n = checkint(L, 2)) >= 0) return n;
344 return (int)lua_objlen(L, t);
345} 417}
346 418
347#endif
348
349/* }====================================================== */ 419/* }====================================================== */
350 420
351 421
352
353LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
354 const char *r) {
355 const char *wild;
356 size_t l = strlen(p);
357 luaL_Buffer b;
358 luaL_buffinit(L, &b);
359 while ((wild = strstr(s, p)) != NULL) {
360 luaL_addlstring(&b, s, wild - s); /* push prefix */
361 luaL_addstring(&b, r); /* push replacement in place of pattern */
362 s = wild + l; /* continue after `p' */
363 }
364 luaL_addstring(&b, s); /* push last suffix */
365 luaL_pushresult(&b);
366 return lua_tostring(L, -1);
367}
368
369
370LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
371 const char *fname, int szhint) {
372 const char *e;
373 lua_pushvalue(L, idx);
374 do {
375 e = strchr(fname, '.');
376 if (e == NULL) e = fname + strlen(fname);
377 lua_pushlstring(L, fname, e - fname);
378 lua_rawget(L, -2);
379 if (lua_isnil(L, -1)) { /* no such field? */
380 lua_pop(L, 1); /* remove this nil */
381 lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
382 lua_pushlstring(L, fname, e - fname);
383 lua_pushvalue(L, -2);
384 lua_settable(L, -4); /* set new table into field */
385 }
386 else if (!lua_istable(L, -1)) { /* field has a non-table value? */
387 lua_pop(L, 2); /* remove table and value */
388 return fname; /* return problematic part of the name */
389 }
390 lua_remove(L, -2); /* remove previous table */
391 fname = e + 1;
392 } while (*e == '.');
393 return NULL;
394}
395
396
397
398/* 422/*
399** {====================================================== 423** {======================================================
400** Generic Buffer manipulation 424** Generic Buffer manipulation
401** ======================================================= 425** =======================================================
402*/ 426*/
403 427
404 428/*
405#define bufflen(B) ((B)->p - (B)->buffer) 429** check whether buffer is using a userdata on the stack as a temporary
406#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) 430** buffer
407 431*/
408#define LIMIT (LUA_MINSTACK/2) 432#define buffonstack(B) ((B)->b != (B)->initb)
409
410
411static int emptybuffer (luaL_Buffer *B) {
412 size_t l = bufflen(B);
413 if (l == 0) return 0; /* put nothing on stack */
414 else {
415 lua_pushlstring(B->L, B->buffer, l);
416 B->p = B->buffer;
417 B->lvl++;
418 return 1;
419 }
420}
421 433
422 434
423static void adjuststack (luaL_Buffer *B) { 435/*
424 if (B->lvl > 1) { 436** returns a pointer to a free area with at least 'sz' bytes
425 lua_State *L = B->L; 437*/
426 int toget = 1; /* number of levels to concat */ 438LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
427 size_t toplen = lua_strlen(L, -1); 439 lua_State *L = B->L;
428 do { 440 if (B->size - B->n < sz) { /* not enough space? */
429 size_t l = lua_strlen(L, -(toget+1)); 441 char *newbuff;
430 if (B->lvl - toget + 1 >= LIMIT || toplen > l) { 442 size_t newsize = B->size * 2; /* double buffer size */
431 toplen += l; 443 if (newsize - B->n < sz) /* not big enough? */
432 toget++; 444 newsize = B->n + sz;
433 } 445 if (newsize < B->n || newsize - B->n < sz)
434 else break; 446 luaL_error(L, "buffer too large");
435 } while (toget < B->lvl); 447 /* create larger buffer */
436 lua_concat(L, toget); 448 newbuff = (char *)lua_newuserdata(L, newsize * sizeof(char));
437 B->lvl = B->lvl - toget + 1; 449 /* move content to new buffer */
450 memcpy(newbuff, B->b, B->n * sizeof(char));
451 if (buffonstack(B))
452 lua_remove(L, -2); /* remove old buffer */
453 B->b = newbuff;
454 B->size = newsize;
438 } 455 }
439} 456 return &B->b[B->n];
440
441
442LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
443 if (emptybuffer(B))
444 adjuststack(B);
445 return B->buffer;
446} 457}
447 458
448 459
449LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { 460LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
450 while (l--) 461 char *b = luaL_prepbuffsize(B, l);
451 luaL_addchar(B, *s++); 462 memcpy(b, s, l * sizeof(char));
463 luaL_addsize(B, l);
452} 464}
453 465
454 466
@@ -458,57 +470,72 @@ LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
458 470
459 471
460LUALIB_API void luaL_pushresult (luaL_Buffer *B) { 472LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
461 emptybuffer(B); 473 lua_State *L = B->L;
462 lua_concat(B->L, B->lvl); 474 lua_pushlstring(L, B->b, B->n);
463 B->lvl = 1; 475 if (buffonstack(B))
476 lua_remove(L, -2); /* remove old buffer */
477}
478
479
480LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) {
481 luaL_addsize(B, sz);
482 luaL_pushresult(B);
464} 483}
465 484
466 485
467LUALIB_API void luaL_addvalue (luaL_Buffer *B) { 486LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
468 lua_State *L = B->L; 487 lua_State *L = B->L;
469 size_t vl; 488 size_t l;
470 const char *s = lua_tolstring(L, -1, &vl); 489 const char *s = lua_tolstring(L, -1, &l);
471 if (vl <= bufffree(B)) { /* fit into buffer? */ 490 if (buffonstack(B))
472 memcpy(B->p, s, vl); /* put it there */ 491 lua_insert(L, -2); /* put value below buffer */
473 B->p += vl; 492 luaL_addlstring(B, s, l);
474 lua_pop(L, 1); /* remove from stack */ 493 lua_remove(L, (buffonstack(B)) ? -2 : -1); /* remove value */
475 }
476 else {
477 if (emptybuffer(B))
478 lua_insert(L, -2); /* put buffer before new value */
479 B->lvl++; /* add new value into B stack */
480 adjuststack(B);
481 }
482} 494}
483 495
484 496
485LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { 497LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
486 B->L = L; 498 B->L = L;
487 B->p = B->buffer; 499 B->b = B->initb;
488 B->lvl = 0; 500 B->n = 0;
501 B->size = LUAL_BUFFERSIZE;
502}
503
504
505LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
506 luaL_buffinit(L, B);
507 return luaL_prepbuffsize(B, sz);
489} 508}
490 509
491/* }====================================================== */ 510/* }====================================================== */
492 511
493 512
513/*
514** {======================================================
515** Reference system
516** =======================================================
517*/
518
519/* index of free-list header */
520#define freelist 0
521
522
494LUALIB_API int luaL_ref (lua_State *L, int t) { 523LUALIB_API int luaL_ref (lua_State *L, int t) {
495 int ref; 524 int ref;
496 t = abs_index(L, t);
497 if (lua_isnil(L, -1)) { 525 if (lua_isnil(L, -1)) {
498 lua_pop(L, 1); /* remove from stack */ 526 lua_pop(L, 1); /* remove from stack */
499 return LUA_REFNIL; /* `nil' has a unique fixed reference */ 527 return LUA_REFNIL; /* `nil' has a unique fixed reference */
500 } 528 }
501 lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ 529 t = lua_absindex(L, t);
502 ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ 530 lua_rawgeti(L, t, freelist); /* get first free element */
531 ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */
503 lua_pop(L, 1); /* remove it from stack */ 532 lua_pop(L, 1); /* remove it from stack */
504 if (ref != 0) { /* any free element? */ 533 if (ref != 0) { /* any free element? */
505 lua_rawgeti(L, t, ref); /* remove it from list */ 534 lua_rawgeti(L, t, ref); /* remove it from list */
506 lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ 535 lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */
507 }
508 else { /* no free elements */
509 ref = (int)lua_objlen(L, t);
510 ref++; /* create new reference */
511 } 536 }
537 else /* no free elements */
538 ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */
512 lua_rawseti(L, t, ref); 539 lua_rawseti(L, t, ref);
513 return ref; 540 return ref;
514} 541}
@@ -516,14 +543,15 @@ LUALIB_API int luaL_ref (lua_State *L, int t) {
516 543
517LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { 544LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
518 if (ref >= 0) { 545 if (ref >= 0) {
519 t = abs_index(L, t); 546 t = lua_absindex(L, t);
520 lua_rawgeti(L, t, FREELIST_REF); 547 lua_rawgeti(L, t, freelist);
521 lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ 548 lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */
522 lua_pushinteger(L, ref); 549 lua_pushinteger(L, ref);
523 lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ 550 lua_rawseti(L, t, freelist); /* t[freelist] = ref */
524 } 551 }
525} 552}
526 553
554/* }====================================================== */
527 555
528 556
529/* 557/*
@@ -533,22 +561,28 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
533*/ 561*/
534 562
535typedef struct LoadF { 563typedef struct LoadF {
536 int extraline; 564 int n; /* number of pre-read characters */
537 int f; 565 int f;
538 char buff[LUAL_BUFFERSIZE]; 566 char buff[LUAL_BUFFERSIZE]; /* area for reading file */
539} LoadF; 567} LoadF;
540 568
541static const char *getF(lua_State *L, void *ud, size_t *size) { 569
570static const char *getF (lua_State *L, void *ud, size_t *size) {
542 LoadF *lf = (LoadF *)ud; 571 LoadF *lf = (LoadF *)ud;
543 (void)L; 572 (void)L; /* not used */
544 if (lf->extraline) { 573 if (lf->n > 0) { /* are there pre-read characters to be read? */
545 lf->extraline = 0; 574 *size = lf->n; /* return them (chars already in buffer) */
546 *size = 1; 575 lf->n = 0; /* no more pre-read characters */
547 return "\n"; 576 }
577 else { /* read a block from file */
578 /* 'fread' can return > 0 *and* set the EOF flag. If next call to
579 'getF' called 'fread', it might still wait for user input.
580 The next check avoids this problem. */
581 *size = rb->read(lf->f, lf->buff, LUAL_BUFFERSIZE);
582 if (*size <= 0) return NULL;
583 return (*size > 0) ? lf->buff : NULL;
548 } 584 }
549 *size = rb->read(lf->f, lf->buff, LUAL_BUFFERSIZE); 585 return lf->buff;
550 if (*size <= 0) return NULL;
551 return (*size > 0) ? lf->buff : NULL;
552} 586}
553 587
554 588
@@ -560,16 +594,68 @@ static int errfile (lua_State *L, const char *what, int fnameindex) {
560 return LUA_ERRFILE; 594 return LUA_ERRFILE;
561} 595}
562 596
563LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { 597
598static int skipBOM (LoadF *lf) {
599 const char *p = "\xEF\xBB\xBF"; /* Utf8 BOM mark */
600 int c;
601 lf->n = 0;
602 do {
603 c = PREFIX(getc)(lf->f);
604 if (c == EOF || c != *(const unsigned char *)p++) return c;
605 lf->buff[lf->n++] = c; /* to be read by the parser */
606 } while (*p != '\0');
607 lf->n = 0; /* prefix matched; discard it */
608 return PREFIX(getc)(lf->f); /* return next character */
609}
610
611
612/*
613** reads the first character of file 'f' and skips an optional BOM mark
614** in its beginning plus its first line if it starts with '#'. Returns
615** true if it skipped the first line. In any case, '*cp' has the
616** first "valid" character of the file (after the optional BOM and
617** a first-line comment).
618*/
619static int skipcomment (LoadF *lf, int *cp) {
620 int c = *cp = skipBOM(lf);
621 if (c == '#') { /* first line is a comment (Unix exec. file)? */
622 do { /* skip first line */
623 c = PREFIX(getc)(lf->f);
624 } while (c != EOF && c != '\n') ;
625 *cp = PREFIX(getc)(lf->f); /* skip end-of-line, if present */
626 return 1; /* there was a comment */
627 }
628 else return 0; /* no comment */
629}
630
631
632LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
633 const char *mode) {
564 LoadF lf; 634 LoadF lf;
565 int status; 635 int status, readstatus;
636 int c;
566 int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ 637 int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
567 lf.extraline = 0;
568 lf.f = rb->open(filename, O_RDONLY);
569 lua_pushfstring(L, "@%s", filename); 638 lua_pushfstring(L, "@%s", filename);
639 lf.n = 0;
640 lf.f = rb->open(filename, O_RDONLY);
570 if (lf.f < 0) return errfile(L, "open", fnameindex); 641 if (lf.f < 0) return errfile(L, "open", fnameindex);
571 status = lua_load(L, getF, &lf, lua_tostring(L, -1)); 642 if (skipcomment(&lf, &c)) /* read initial portion */
572 rb->close(lf.f); 643 lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */
644 if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
645 rb->close(lf.f);
646 lf.f = rb->open(filename, O_RDONLY);
647 if (lf.f < 0) return errfile(L, "reopen", fnameindex);
648 skipcomment(&lf, &c); /* re-read initial portion */
649 }
650 if (c != EOF)
651 lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */
652 status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
653 readstatus = 0;/*ferror(lf.f);*/
654 if (filename) rb->close(lf.f); /* close file (even in case of errors) */
655 if (readstatus) {
656 lua_settop(L, fnameindex); /* ignore results from `lua_load' */
657 return errfile(L, "read", fnameindex);
658 }
573 lua_remove(L, fnameindex); 659 lua_remove(L, fnameindex);
574 return status; 660 return status;
575} 661}
@@ -583,7 +669,7 @@ typedef struct LoadS {
583 669
584static const char *getS (lua_State *L, void *ud, size_t *size) { 670static const char *getS (lua_State *L, void *ud, size_t *size) {
585 LoadS *ls = (LoadS *)ud; 671 LoadS *ls = (LoadS *)ud;
586 (void)L; 672 (void)L; /* not used */
587 if (ls->size == 0) return NULL; 673 if (ls->size == 0) return NULL;
588 *size = ls->size; 674 *size = ls->size;
589 ls->size = 0; 675 ls->size = 0;
@@ -591,27 +677,245 @@ static const char *getS (lua_State *L, void *ud, size_t *size) {
591} 677}
592 678
593 679
594LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size, 680LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size,
595 const char *name) { 681 const char *name, const char *mode) {
596 LoadS ls; 682 LoadS ls;
597 ls.s = buff; 683 ls.s = buff;
598 ls.size = size; 684 ls.size = size;
599 return lua_load(L, getS, &ls, name); 685 return lua_load(L, getS, &ls, name, mode);
600} 686}
601 687
602 688
603LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) { 689LUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
604 return luaL_loadbuffer(L, s, strlen(s), s); 690 return luaL_loadbuffer(L, s, strlen(s), s);
605} 691}
606 692
693/* }====================================================== */
694
695
696
697LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
698 if (!lua_getmetatable(L, obj)) /* no metatable? */
699 return 0;
700 lua_pushstring(L, event);
701 lua_rawget(L, -2);
702 if (lua_isnil(L, -1)) {
703 lua_pop(L, 2); /* remove metatable and metafield */
704 return 0;
705 }
706 else {
707 lua_remove(L, -2); /* remove only metatable */
708 return 1;
709 }
710}
711
712
713LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
714 obj = lua_absindex(L, obj);
715 if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
716 return 0;
717 lua_pushvalue(L, obj);
718 lua_call(L, 1, 1);
719 return 1;
720}
721
722
723LUALIB_API int luaL_len (lua_State *L, int idx) {
724 int l;
725 int isnum;
726 lua_len(L, idx);
727 l = (int)lua_tointegerx(L, -1, &isnum);
728 if (!isnum)
729 luaL_error(L, "object length is not a number");
730 lua_pop(L, 1); /* remove object */
731 return l;
732}
733
734
735LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
736 if (!luaL_callmeta(L, idx, "__tostring")) { /* no metafield? */
737 switch (lua_type(L, idx)) {
738 case LUA_TNUMBER:
739 case LUA_TSTRING:
740 lua_pushvalue(L, idx);
741 break;
742 case LUA_TBOOLEAN:
743 lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false"));
744 break;
745 case LUA_TNIL:
746 lua_pushliteral(L, "nil");
747 break;
748 default:
749 lua_pushfstring(L, "%s: %p", luaL_typename(L, idx),
750 lua_topointer(L, idx));
751 break;
752 }
753 }
754 return lua_tolstring(L, -1, len);
755}
756
757
758/*
759** {======================================================
760** Compatibility with 5.1 module functions
761** =======================================================
762*/
763#if defined(LUA_COMPAT_MODULE)
764
765static const char *luaL_findtable (lua_State *L, int idx,
766 const char *fname, int szhint) {
767 const char *e;
768 if (idx) lua_pushvalue(L, idx);
769 do {
770 e = strchr(fname, '.');
771 if (e == NULL) e = fname + strlen(fname);
772 lua_pushlstring(L, fname, e - fname);
773 lua_rawget(L, -2);
774 if (lua_isnil(L, -1)) { /* no such field? */
775 lua_pop(L, 1); /* remove this nil */
776 lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
777 lua_pushlstring(L, fname, e - fname);
778 lua_pushvalue(L, -2);
779 lua_settable(L, -4); /* set new table into field */
780 }
781 else if (!lua_istable(L, -1)) { /* field has a non-table value? */
782 lua_pop(L, 2); /* remove table and value */
783 return fname; /* return problematic part of the name */
784 }
785 lua_remove(L, -2); /* remove previous table */
786 fname = e + 1;
787 } while (*e == '.');
788 return NULL;
789}
790
791
792/*
793** Count number of elements in a luaL_Reg list.
794*/
795static int libsize (const luaL_Reg *l) {
796 int size = 0;
797 for (; l && l->name; l++) size++;
798 return size;
799}
800
801
802/*
803** Find or create a module table with a given name. The function
804** first looks at the _LOADED table and, if that fails, try a
805** global variable with that name. In any case, leaves on the stack
806** the module table.
807*/
808LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
809 int sizehint) {
810 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */
811 lua_getfield(L, -1, modname); /* get _LOADED[modname] */
812 if (!lua_istable(L, -1)) { /* not found? */
813 lua_pop(L, 1); /* remove previous result */
814 /* try global variable (and create one if it does not exist) */
815 lua_pushglobaltable(L);
816 if (luaL_findtable(L, 0, modname, sizehint) != NULL)
817 luaL_error(L, "name conflict for module " LUA_QS, modname);
818 lua_pushvalue(L, -1);
819 lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */
820 }
821 lua_remove(L, -2); /* remove _LOADED table */
822}
607 823
608 824
825LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
826 const luaL_Reg *l, int nup) {
827 luaL_checkversion(L);
828 if (libname) {
829 luaL_pushmodule(L, libname, libsize(l)); /* get/create library table */
830 lua_insert(L, -(nup + 1)); /* move library table to below upvalues */
831 }
832 if (l)
833 luaL_setfuncs(L, l, nup);
834 else
835 lua_pop(L, nup); /* remove upvalues */
836}
837
838#endif
609/* }====================================================== */ 839/* }====================================================== */
610 840
841/*
842** set functions from list 'l' into table at top - 'nup'; each
843** function gets the 'nup' elements at the top as upvalues.
844** Returns with only the table at the stack.
845*/
846LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
847 luaL_checkversion(L);
848 luaL_checkstack(L, nup, "too many upvalues");
849 for (; l->name != NULL; l++) { /* fill the table with given functions */
850 int i;
851 for (i = 0; i < nup; i++) /* copy upvalues to the top */
852 lua_pushvalue(L, -nup);
853 lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
854 lua_setfield(L, -(nup + 2), l->name);
855 }
856 lua_pop(L, nup); /* remove upvalues */
857}
858
859
860/*
861** ensure that stack[idx][fname] has a table and push that table
862** into the stack
863*/
864LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) {
865 lua_getfield(L, idx, fname);
866 if (lua_istable(L, -1)) return 1; /* table already there */
867 else {
868 lua_pop(L, 1); /* remove previous result */
869 idx = lua_absindex(L, idx);
870 lua_newtable(L);
871 lua_pushvalue(L, -1); /* copy to be left at top */
872 lua_setfield(L, idx, fname); /* assign new table to field */
873 return 0; /* false, because did not find table there */
874 }
875}
876
877
878/*
879** stripped-down 'require'. Calls 'openf' to open a module,
880** registers the result in 'package.loaded' table and, if 'glb'
881** is true, also registers the result in the global table.
882** Leaves resulting module on the top.
883*/
884LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
885 lua_CFunction openf, int glb) {
886 lua_pushcfunction(L, openf);
887 lua_pushstring(L, modname); /* argument to open function */
888 lua_call(L, 1, 1); /* open module */
889 luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
890 lua_pushvalue(L, -2); /* make copy of module (call result) */
891 lua_setfield(L, -2, modname); /* _LOADED[modname] = module */
892 lua_pop(L, 1); /* remove _LOADED table */
893 if (glb) {
894 lua_pushvalue(L, -1); /* copy of 'mod' */
895 lua_setglobal(L, modname); /* _G[modname] = module */
896 }
897}
898
899
900LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
901 const char *r) {
902 const char *wild;
903 size_t l = strlen(p);
904 luaL_Buffer b;
905 luaL_buffinit(L, &b);
906 while ((wild = strstr(s, p)) != NULL) {
907 luaL_addlstring(&b, s, wild - s); /* push prefix */
908 luaL_addstring(&b, r); /* push replacement in place of pattern */
909 s = wild + l; /* continue after `p' */
910 }
911 luaL_addstring(&b, s); /* push last suffix */
912 luaL_pushresult(&b);
913 return lua_tostring(L, -1);
914}
915
611 916
612static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { 917static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
613 (void)ud; 918 (void)ud; (void)osize; /* not used */
614 (void)osize;
615 if (nsize == 0) { 919 if (nsize == 0) {
616 free(ptr); 920 free(ptr);
617 return NULL; 921 return NULL;
@@ -622,12 +926,11 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
622 926
623 927
624static int panic (lua_State *L) { 928static int panic (lua_State *L) {
625 DEBUGF("PANIC: unprotected error in call to Lua API (%s)\n", 929 DEBUGF("PANIC: unprotected error in call to Lua API (%s)\n",
626 lua_tostring(L, -1)); 930 lua_tostring(L, -1));
627 rb->splashf(5 * HZ, "PANIC: unprotected error in call to Lua API (%s)", 931 rb->splashf(5 * HZ, "PANIC: unprotected error in call to Lua API (%s)",
628 lua_tostring(L, -1)); 932 lua_tostring(L, -1));
629 933 return 0; /* return to Lua to abort */
630 return 0;
631} 934}
632 935
633 936
@@ -637,3 +940,20 @@ LUALIB_API lua_State *luaL_newstate (void) {
637 return L; 940 return L;
638} 941}
639 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
diff --git a/apps/plugins/lua/lauxlib.h b/apps/plugins/lua/lauxlib.h
index a36de351fe..0fb023b8e7 100644
--- a/apps/plugins/lua/lauxlib.h
+++ b/apps/plugins/lua/lauxlib.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: lauxlib.h,v 1.120.1.1 2013/04/12 18:48:47 roberto Exp $
3** Auxiliary functions for building Lua libraries 3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -15,18 +15,6 @@
15#include "lua.h" 15#include "lua.h"
16 16
17 17
18#if defined(LUA_COMPAT_GETN)
19LUALIB_API int (luaL_getn) (lua_State *L, int t);
20LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
21#else
22#define luaL_getn(L,i) ((int)lua_objlen(L, i))
23#define luaL_setn(L,i,j) ((void)0) /* no op! */
24#endif
25
26#if defined(LUA_COMPAT_OPENLIB)
27#define luaI_openlib luaL_openlib
28#endif
29
30 18
31/* extra error code for `luaL_load' */ 19/* extra error code for `luaL_load' */
32#define LUA_ERRFILE (LUA_ERRERR+1) 20#define LUA_ERRFILE (LUA_ERRERR+1)
@@ -38,14 +26,12 @@ typedef struct luaL_Reg {
38} luaL_Reg; 26} luaL_Reg;
39 27
40 28
29LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver);
30#define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM)
41 31
42LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname,
43 const luaL_Reg *l, int nup);
44LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
45 const luaL_Reg *l);
46LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); 32LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
47LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); 33LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
48LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); 34LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
49LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); 35LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
50LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, 36LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
51 size_t *l); 37 size_t *l);
@@ -57,16 +43,17 @@ LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
57LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); 43LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
58LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, 44LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
59 lua_Integer def); 45 lua_Integer def);
60 46LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg);
61LUALIB_API int (luaL_checkboolean) (lua_State *L, int numArg); 47LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg,
62LUALIB_API int (luaL_optboolean) (lua_State *L, int nArg, 48 lua_Unsigned def);
63 int def);
64 49
65LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); 50LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
66LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); 51LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
67LUALIB_API void (luaL_checkany) (lua_State *L, int narg); 52LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
68 53
69LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); 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);
70LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); 57LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
71 58
72LUALIB_API void (luaL_where) (lua_State *L, int lvl); 59LUALIB_API void (luaL_where) (lua_State *L, int lvl);
@@ -75,25 +62,41 @@ LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
75LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, 62LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
76 const char *const lst[]); 63 const char *const lst[]);
77 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
78LUALIB_API int (luaL_ref) (lua_State *L, int t); 72LUALIB_API int (luaL_ref) (lua_State *L, int t);
79LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); 73LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
80 74
81LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); 75LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
82LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, 76 const char *mode);
83 const char *name); 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);
84LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); 82LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
85 83
86LUALIB_API lua_State *(luaL_newstate) (void); 84LUALIB_API lua_State *(luaL_newstate) (void);
87 85
86LUALIB_API int (luaL_len) (lua_State *L, int idx);
88 87
89LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, 88LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
90 const char *r); 89 const char *r);
91 90
92LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, 91LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
93 const char *fname, int szhint);
94 92
93LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname);
95 94
95LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1,
96 const char *msg, int level);
96 97
98LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
99 lua_CFunction openf, int glb);
97 100
98/* 101/*
99** =============================================================== 102** ===============================================================
@@ -101,6 +104,12 @@ LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
101** =============================================================== 104** ===============================================================
102*/ 105*/
103 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
104#define luaL_argcheck(L, cond,numarg,extramsg) \ 113#define luaL_argcheck(L, cond,numarg,extramsg) \
105 ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) 114 ((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
106#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) 115#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
@@ -122,56 +131,81 @@ LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
122 131
123#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) 132#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
124 133
134#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL)
135
136
125/* 137/*
126** {====================================================== 138** {======================================================
127** Generic Buffer manipulation 139** Generic Buffer manipulation
128** ======================================================= 140** =======================================================
129*/ 141*/
130 142
131
132
133typedef struct luaL_Buffer { 143typedef struct luaL_Buffer {
134 char *p; /* current position in buffer */ 144 char *b; /* buffer address */
135 int lvl; /* number of strings in the stack (level) */ 145 size_t size; /* buffer size */
146 size_t n; /* number of characters in buffer */
136 lua_State *L; 147 lua_State *L;
137 char buffer[LUAL_BUFFERSIZE]; 148 char initb[LUAL_BUFFERSIZE]; /* initial buffer */
138} luaL_Buffer; 149} luaL_Buffer;
139 150
140#define luaL_addchar(B,c) \
141 ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
142 (*(B)->p++ = (char)(c)))
143 151
144/* compatibility only */ 152#define luaL_addchar(B,c) \
145#define luaL_putchar(B,c) luaL_addchar(B,c) 153 ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \
154 ((B)->b[(B)->n++] = (c)))
146 155
147#define luaL_addsize(B,n) ((B)->p += (n)) 156#define luaL_addsize(B,s) ((B)->n += (s))
148 157
149LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); 158LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
150LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); 159LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
151LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); 160LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
152LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); 161LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
153LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); 162LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
154LUALIB_API void (luaL_pushresult) (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);
155 166
167#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
156 168
157/* }====================================================== */ 169/* }====================================================== */
158 170
159 171
160/* compatibility with ref system */
161 172
162/* pre-defined references */ 173/*
163#define LUA_NOREF (-2) 174** {======================================================
164#define LUA_REFNIL (-1) 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
165 195
166#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
167 (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
168 196
169#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) 197/* compatibility with old module system */
198#if defined(LUA_COMPAT_MODULE)
170 199
171#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) 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);
172 204
205#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0))
206
207#endif
173 208
174#define luaL_reg luaL_Reg
175 209
176#endif 210#endif
177 211
diff --git a/apps/plugins/lua/lbaselib.c b/apps/plugins/lua/lbaselib.c
index 008e3629fe..5255b3cd9b 100644
--- a/apps/plugins/lua/lbaselib.c
+++ b/apps/plugins/lua/lbaselib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $ 2** $Id: lbaselib.c,v 1.276.1.1 2013/04/12 18:48:47 roberto Exp $
3** Basic library 3** Basic library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -20,62 +20,68 @@
20#include "lualib.h" 20#include "lualib.h"
21 21
22 22
23
24
25/*
26** If your system does not support `stdout', you can just remove this function.
27** If you need, you can define your own `print' function, following this
28** model but changing `fputs' to put the strings at a proper place
29** (a console window or a log file, for instance).
30*/
31#if 0
32static int luaB_print (lua_State *L) { 23static int luaB_print (lua_State *L) {
33 int n = lua_gettop(L); /* number of arguments */ 24 int n = lua_gettop(L); /* number of arguments */
34 int i; 25 int i;
35 lua_getglobal(L, "tostring"); 26 lua_getglobal(L, "tostring");
36 for (i=1; i<=n; i++) { 27 for (i=1; i<=n; i++) {
37 const char *s; 28 const char *s;
29 size_t l;
38 lua_pushvalue(L, -1); /* function to be called */ 30 lua_pushvalue(L, -1); /* function to be called */
39 lua_pushvalue(L, i); /* value to print */ 31 lua_pushvalue(L, i); /* value to print */
40 lua_call(L, 1, 1); 32 lua_call(L, 1, 1);
41 s = lua_tostring(L, -1); /* get result */ 33 s = lua_tolstring(L, -1, &l); /* get result */
42 if (s == NULL) 34 if (s == NULL)
43 return luaL_error(L, LUA_QL("tostring") " must return a string to " 35 return luaL_error(L,
44 LUA_QL("print")); 36 LUA_QL("tostring") " must return a string to " LUA_QL("print"));
45 if (i>1) fputs("\t", stdout); 37 if (i>1) luai_writestring("\t", 1);
46 fputs(s, stdout); 38 luai_writestring(s, l);
47 lua_pop(L, 1); /* pop result */ 39 lua_pop(L, 1); /* pop result */
48 } 40 }
49 fputs("\n", stdout); 41 luai_writeline();
50 return 0; 42 return 0;
51} 43}
52#endif
53 44
54 45
46#define SPACECHARS " \f\n\r\t\v"
47
55static int luaB_tonumber (lua_State *L) { 48static int luaB_tonumber (lua_State *L) {
56 int base = luaL_optint(L, 2, 10); 49 if (lua_isnoneornil(L, 2)) { /* standard conversion */
57 if (base == 10) { /* standard conversion */ 50 int isnum;
58 luaL_checkany(L, 1); 51 lua_Number n = lua_tonumberx(L, 1, &isnum);
59 if (lua_isnumber(L, 1)) { 52 if (isnum) {
60 lua_pushnumber(L, lua_tonumber(L, 1)); 53 lua_pushnumber(L, n);
61 return 1; 54 return 1;
62 } 55 } /* else not a number; must be something */
56 luaL_checkany(L, 1);
63 } 57 }
64 else { 58 else {
65 const char *s1 = luaL_checkstring(L, 1); 59 size_t l;
66 char *s2; 60 const char *s = luaL_checklstring(L, 1, &l);
67 unsigned long n; 61 const char *e = s + l; /* end point for 's' */
62 int base = luaL_checkint(L, 2);
63 int neg = 0;
68 luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); 64 luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
69 n = strtoul(s1, &s2, base); 65 s += strspn(s, SPACECHARS); /* skip initial spaces */
70 if (s1 != s2) { /* at least one valid digit? */ 66 if (*s == '-') { s++; neg = 1; } /* handle signal */
71 while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */ 67 else if (*s == '+') s++;
72 if (*s2 == '\0') { /* no invalid trailing characters? */ 68 if (isalnum((unsigned char)*s)) {
73 lua_pushnumber(L, (lua_Number)n); 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);
74 return 1; 80 return 1;
75 } 81 } /* else not a number */
76 } 82 } /* else not a number */
77 } 83 }
78 lua_pushnil(L); /* else not a number */ 84 lua_pushnil(L); /* not a number */
79 return 1; 85 return 1;
80} 86}
81 87
@@ -109,57 +115,13 @@ static int luaB_setmetatable (lua_State *L) {
109 luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, 115 luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
110 "nil or table expected"); 116 "nil or table expected");
111 if (luaL_getmetafield(L, 1, "__metatable")) 117 if (luaL_getmetafield(L, 1, "__metatable"))
112 luaL_error(L, "cannot change a protected metatable"); 118 return luaL_error(L, "cannot change a protected metatable");
113 lua_settop(L, 2); 119 lua_settop(L, 2);
114 lua_setmetatable(L, 1); 120 lua_setmetatable(L, 1);
115 return 1; 121 return 1;
116} 122}
117 123
118 124
119static void getfunc (lua_State *L, int opt) {
120 if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
121 else {
122 lua_Debug ar;
123 int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1);
124 luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
125 if (lua_getstack(L, level, &ar) == 0)
126 luaL_argerror(L, 1, "invalid level");
127 lua_getinfo(L, "f", &ar);
128 if (lua_isnil(L, -1))
129 luaL_error(L, "no function environment for tail call at level %d",
130 level);
131 }
132}
133
134
135static int luaB_getfenv (lua_State *L) {
136 getfunc(L, 1);
137 if (lua_iscfunction(L, -1)) /* is a C function? */
138 lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */
139 else
140 lua_getfenv(L, -1);
141 return 1;
142}
143
144
145static int luaB_setfenv (lua_State *L) {
146 luaL_checktype(L, 2, LUA_TTABLE);
147 getfunc(L, 0);
148 lua_pushvalue(L, 2);
149 if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
150 /* change environment of current thread */
151 lua_pushthread(L);
152 lua_insert(L, -2);
153 lua_setfenv(L, -2);
154 return 0;
155 }
156 else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
157 luaL_error(L,
158 LUA_QL("setfenv") " cannot change environment of given object");
159 return 1;
160}
161
162
163static int luaB_rawequal (lua_State *L) { 125static int luaB_rawequal (lua_State *L) {
164 luaL_checkany(L, 1); 126 luaL_checkany(L, 1);
165 luaL_checkany(L, 2); 127 luaL_checkany(L, 2);
@@ -168,6 +130,15 @@ static int luaB_rawequal (lua_State *L) {
168} 130}
169 131
170 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
171static int luaB_rawget (lua_State *L) { 142static int luaB_rawget (lua_State *L) {
172 luaL_checktype(L, 1, LUA_TTABLE); 143 luaL_checktype(L, 1, LUA_TTABLE);
173 luaL_checkany(L, 2); 144 luaL_checkany(L, 2);
@@ -186,32 +157,29 @@ static int luaB_rawset (lua_State *L) {
186} 157}
187 158
188 159
189static int luaB_gcinfo (lua_State *L) {
190 lua_pushinteger(L, lua_getgccount(L));
191 return 1;
192}
193
194
195static int luaB_collectgarbage (lua_State *L) { 160static int luaB_collectgarbage (lua_State *L) {
196 static const char *const opts[] = {"stop", "restart", "collect", 161 static const char *const opts[] = {"stop", "restart", "collect",
197 "count", "step", "setpause", "setstepmul", NULL}; 162 "count", "step", "setpause", "setstepmul",
163 "setmajorinc", "isrunning", "generational", "incremental", NULL};
198 static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, 164 static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
199 LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL}; 165 LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
200 int o = luaL_checkoption(L, 1, "collect", opts); 166 LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC};
167 int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];
201 int ex = luaL_optint(L, 2, 0); 168 int ex = luaL_optint(L, 2, 0);
202 int res = lua_gc(L, optsnum[o], ex); 169 int res = lua_gc(L, o, ex);
203 switch (optsnum[o]) { 170 switch (o) {
204 case LUA_GCCOUNT: { 171 case LUA_GCCOUNT: {
205 int b = lua_gc(L, LUA_GCCOUNTB, 0); 172 int b = lua_gc(L, LUA_GCCOUNTB, 0);
206 lua_pushnumber(L, res + ((lua_Number)b/1024)); 173 lua_pushnumber(L, res + ((lua_Number)b/1024));
207 return 1; 174 lua_pushinteger(L, b);
175 return 2;
208 } 176 }
209 case LUA_GCSTEP: { 177 case LUA_GCSTEP: case LUA_GCISRUNNING: {
210 lua_pushboolean(L, res); 178 lua_pushboolean(L, res);
211 return 1; 179 return 1;
212 } 180 }
213 default: { 181 default: {
214 lua_pushnumber(L, res); 182 lua_pushinteger(L, res);
215 return 1; 183 return 1;
216 } 184 }
217 } 185 }
@@ -225,6 +193,23 @@ static int luaB_type (lua_State *L) {
225} 193}
226 194
227 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
228static int luaB_next (lua_State *L) { 213static int luaB_next (lua_State *L) {
229 luaL_checktype(L, 1, LUA_TTABLE); 214 luaL_checktype(L, 1, LUA_TTABLE);
230 lua_settop(L, 2); /* create a 2nd argument if there isn't one */ 215 lua_settop(L, 2); /* create a 2nd argument if there isn't one */
@@ -238,11 +223,7 @@ static int luaB_next (lua_State *L) {
238 223
239 224
240static int luaB_pairs (lua_State *L) { 225static int luaB_pairs (lua_State *L) {
241 luaL_checktype(L, 1, LUA_TTABLE); 226 return pairsmeta(L, "__pairs", 0, luaB_next);
242 lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
243 lua_pushvalue(L, 1); /* state, */
244 lua_pushnil(L); /* and initial value */
245 return 3;
246} 227}
247 228
248 229
@@ -252,23 +233,25 @@ static int ipairsaux (lua_State *L) {
252 i++; /* next value */ 233 i++; /* next value */
253 lua_pushinteger(L, i); 234 lua_pushinteger(L, i);
254 lua_rawgeti(L, 1, i); 235 lua_rawgeti(L, 1, i);
255 return (lua_isnil(L, -1)) ? 0 : 2; 236 return (lua_isnil(L, -1)) ? 1 : 2;
256} 237}
257 238
258 239
259static int luaB_ipairs (lua_State *L) { 240static int luaB_ipairs (lua_State *L) {
260 luaL_checktype(L, 1, LUA_TTABLE); 241 return pairsmeta(L, "__ipairs", 1, ipairsaux);
261 lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
262 lua_pushvalue(L, 1); /* state, */
263 lua_pushinteger(L, 0); /* and initial value */
264 return 3;
265} 242}
266 243
267 244
268static int load_aux (lua_State *L, int status) { 245static int load_aux (lua_State *L, int status, int envidx) {
269 if (status == 0) /* OK? */ 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 }
270 return 1; 252 return 1;
271 else { 253 }
254 else { /* error (message is on top of the stack) */
272 lua_pushnil(L); 255 lua_pushnil(L);
273 lua_insert(L, -2); /* put before error message */ 256 lua_insert(L, -2); /* put before error message */
274 return 2; /* return nil plus error message */ 257 return 2; /* return nil plus error message */
@@ -276,87 +259,97 @@ static int load_aux (lua_State *L, int status) {
276} 259}
277 260
278 261
279static int luaB_loadstring (lua_State *L) {
280 size_t l;
281 const char *s = luaL_checklstring(L, 1, &l);
282 const char *chunkname = luaL_optstring(L, 2, s);
283 return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
284}
285
286
287static int luaB_loadfile (lua_State *L) { 262static int luaB_loadfile (lua_State *L) {
288 const char *fname = luaL_optstring(L, 1, NULL); 263 const char *fname = luaL_optstring(L, 1, NULL);
289 return load_aux(L, luaL_loadfile(L, fname)); 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);
290} 268}
291 269
292 270
293/* 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/*
294** Reader for generic `load' function: `lua_load' uses the 287** Reader for generic `load' function: `lua_load' uses the
295** stack for internal stuff, so the reader cannot change the 288** stack for internal stuff, so the reader cannot change the
296** stack top. Instead, it keeps its resulting string in a 289** stack top. Instead, it keeps its resulting string in a
297** reserved slot inside the stack. 290** reserved slot inside the stack.
298*/ 291*/
299static const char *generic_reader (lua_State *L, void *ud, size_t *size) { 292static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
300 (void)ud; /* to avoid warnings */ 293 (void)(ud); /* not used */
301 luaL_checkstack(L, 2, "too many nested functions"); 294 luaL_checkstack(L, 2, "too many nested functions");
302 lua_pushvalue(L, 1); /* get function */ 295 lua_pushvalue(L, 1); /* get function */
303 lua_call(L, 0, 1); /* call it */ 296 lua_call(L, 0, 1); /* call it */
304 if (lua_isnil(L, -1)) { 297 if (lua_isnil(L, -1)) {
298 lua_pop(L, 1); /* pop result */
305 *size = 0; 299 *size = 0;
306 return NULL; 300 return NULL;
307 } 301 }
308 else if (lua_isstring(L, -1)) { 302 else if (!lua_isstring(L, -1))
309 lua_replace(L, 3); /* save string in a reserved stack slot */ 303 luaL_error(L, "reader function must return a string");
310 return lua_tolstring(L, 3, size); 304 lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */
311 } 305 return lua_tolstring(L, RESERVEDSLOT, size);
312 else luaL_error(L, "reader function must return a string");
313 return NULL; /* to avoid warnings */
314} 306}
315 307
316 308
317static int luaB_load (lua_State *L) { 309static int luaB_load (lua_State *L) {
318 int status; 310 int status;
319 const char *cname = luaL_optstring(L, 2, "=(load)"); 311 size_t l;
320 luaL_checktype(L, 1, LUA_TFUNCTION); 312 const char *s = lua_tolstring(L, 1, &l);
321 lua_settop(L, 3); /* function, eventual name, plus one reserved slot */ 313 const char *mode = luaL_optstring(L, 3, "bt");
322 status = lua_load(L, generic_reader, NULL, cname); 314 int env = (!lua_isnone(L, 4) ? 4 : 0); /* 'env' index or 0 if no 'env' */
323 return load_aux(L, status); 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;
324} 333}
325 334
326 335
327static int luaB_dofile (lua_State *L) { 336static int luaB_dofile (lua_State *L) {
328 const char *fname = luaL_optstring(L, 1, NULL); 337 const char *fname = luaL_optstring(L, 1, NULL);
329 int n = lua_gettop(L); 338 lua_settop(L, 1);
330 if (luaL_loadfile(L, fname) != 0) lua_error(L); 339 if (luaL_loadfile(L, fname) != LUA_OK)
331 lua_call(L, 0, LUA_MULTRET); 340 return lua_error(L);
332 return lua_gettop(L) - n; 341 lua_callk(L, 0, LUA_MULTRET, 0, dofilecont);
342 return dofilecont(L);
333} 343}
334 344
335 345
336static int luaB_assert (lua_State *L) { 346static int luaB_assert (lua_State *L) {
337 luaL_checkany(L, 1);
338 if (!lua_toboolean(L, 1)) 347 if (!lua_toboolean(L, 1))
339 return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); 348 return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
340 return lua_gettop(L); 349 return lua_gettop(L);
341} 350}
342 351
343 352
344static int luaB_unpack (lua_State *L) {
345 int i, e, n;
346 luaL_checktype(L, 1, LUA_TTABLE);
347 i = luaL_optint(L, 2, 1);
348 e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1));
349 if (i > e) return 0; /* empty range */
350 n = e - i + 1; /* number of elements */
351 if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */
352 return luaL_error(L, "too many results to unpack");
353 lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */
354 while (i++ < e) /* push arg[i + 1...e] */
355 lua_rawgeti(L, 1, i);
356 return n;
357}
358
359
360static int luaB_select (lua_State *L) { 353static int luaB_select (lua_State *L) {
361 int n = lua_gettop(L); 354 int n = lua_gettop(L);
362 if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { 355 if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
@@ -373,75 +366,50 @@ static int luaB_select (lua_State *L) {
373} 366}
374 367
375 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
376static int luaB_pcall (lua_State *L) { 388static int luaB_pcall (lua_State *L) {
377 int status; 389 int status;
378 luaL_checkany(L, 1); 390 luaL_checkany(L, 1);
379 status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); 391 lua_pushnil(L);
380 lua_pushboolean(L, (status == 0)); 392 lua_insert(L, 1); /* create space for status result */
381 lua_insert(L, 1); 393 status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont);
382 return lua_gettop(L); /* return status + all results */ 394 return finishpcall(L, (status == LUA_OK));
383} 395}
384 396
385 397
386static int luaB_xpcall (lua_State *L) { 398static int luaB_xpcall (lua_State *L) {
387 int status; 399 int status;
388 luaL_checkany(L, 2); 400 int n = lua_gettop(L);
389 lua_settop(L, 2); 401 luaL_argcheck(L, n >= 2, 2, "value expected");
390 lua_insert(L, 1); /* put error function under function to be called */ 402 lua_pushvalue(L, 1); /* exchange function... */
391 status = lua_pcall(L, 0, LUA_MULTRET, 1); 403 lua_copy(L, 2, 1); /* ...and error handler */
392 lua_pushboolean(L, (status == 0)); 404 lua_replace(L, 2);
393 lua_replace(L, 1); 405 status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 0, pcallcont);
394 return lua_gettop(L); /* return status + all results */ 406 return finishpcall(L, (status == LUA_OK));
395} 407}
396 408
397 409
398static int luaB_tostring (lua_State *L) { 410static int luaB_tostring (lua_State *L) {
399 luaL_checkany(L, 1); 411 luaL_checkany(L, 1);
400 if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */ 412 luaL_tolstring(L, 1, NULL);
401 return 1; /* use its value */
402 switch (lua_type(L, 1)) {
403 case LUA_TNUMBER:
404 lua_pushstring(L, lua_tostring(L, 1));
405 break;
406 case LUA_TSTRING:
407 lua_pushvalue(L, 1);
408 break;
409 case LUA_TBOOLEAN:
410 lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
411 break;
412 case LUA_TNIL:
413 lua_pushliteral(L, "nil");
414 break;
415 default:
416 lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1));
417 break;
418 }
419 return 1;
420}
421
422
423static int luaB_newproxy (lua_State *L) {
424 lua_settop(L, 1);
425 lua_newuserdata(L, 0); /* create proxy */
426 if (lua_toboolean(L, 1) == 0)
427 return 1; /* no metatable */
428 else if (lua_isboolean(L, 1)) {
429 lua_newtable(L); /* create a new metatable `m' ... */
430 lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */
431 lua_pushboolean(L, 1);
432 lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */
433 }
434 else {
435 int validproxy = 0; /* to check if weaktable[metatable(u)] == true */
436 if (lua_getmetatable(L, 1)) {
437 lua_rawget(L, lua_upvalueindex(1));
438 validproxy = lua_toboolean(L, -1);
439 lua_pop(L, 1); /* remove value */
440 }
441 luaL_argcheck(L, validproxy, 1, "boolean or proxy expected");
442 lua_getmetatable(L, 1); /* metatable is valid; get it */
443 }
444 lua_setmetatable(L, 2);
445 return 1; 413 return 1;
446} 414}
447 415
@@ -451,207 +419,40 @@ static const luaL_Reg base_funcs[] = {
451 {"collectgarbage", luaB_collectgarbage}, 419 {"collectgarbage", luaB_collectgarbage},
452 {"dofile", luaB_dofile}, 420 {"dofile", luaB_dofile},
453 {"error", luaB_error}, 421 {"error", luaB_error},
454 {"gcinfo", luaB_gcinfo},
455 {"getfenv", luaB_getfenv},
456 {"getmetatable", luaB_getmetatable}, 422 {"getmetatable", luaB_getmetatable},
423 {"ipairs", luaB_ipairs},
457 {"loadfile", luaB_loadfile}, 424 {"loadfile", luaB_loadfile},
458 {"load", luaB_load}, 425 {"load", luaB_load},
459 {"loadstring", luaB_loadstring}, 426#if defined(LUA_COMPAT_LOADSTRING)
427 {"loadstring", luaB_load},
428#endif
460 {"next", luaB_next}, 429 {"next", luaB_next},
430 {"pairs", luaB_pairs},
461 {"pcall", luaB_pcall}, 431 {"pcall", luaB_pcall},
462#if 0
463 {"print", luaB_print}, 432 {"print", luaB_print},
464#endif
465 {"rawequal", luaB_rawequal}, 433 {"rawequal", luaB_rawequal},
434 {"rawlen", luaB_rawlen},
466 {"rawget", luaB_rawget}, 435 {"rawget", luaB_rawget},
467 {"rawset", luaB_rawset}, 436 {"rawset", luaB_rawset},
468 {"select", luaB_select}, 437 {"select", luaB_select},
469 {"setfenv", luaB_setfenv},
470 {"setmetatable", luaB_setmetatable}, 438 {"setmetatable", luaB_setmetatable},
471 {"tonumber", luaB_tonumber}, 439 {"tonumber", luaB_tonumber},
472 {"tostring", luaB_tostring}, 440 {"tostring", luaB_tostring},
473 {"type", luaB_type}, 441 {"type", luaB_type},
474 {"unpack", luaB_unpack},
475 {"xpcall", luaB_xpcall}, 442 {"xpcall", luaB_xpcall},
476 {NULL, NULL} 443 {NULL, NULL}
477}; 444};
478 445
479 446
480/* 447LUAMOD_API int luaopen_base (lua_State *L) {
481** {======================================================
482** Coroutine library
483** =======================================================
484*/
485
486#define CO_RUN 0 /* running */
487#define CO_SUS 1 /* suspended */
488#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */
489#define CO_DEAD 3
490
491static const char *const statnames[] =
492 {"running", "suspended", "normal", "dead"};
493
494static int costatus (lua_State *L, lua_State *co) {
495 if (L == co) return CO_RUN;
496 switch (lua_status(co)) {
497 case LUA_YIELD:
498 return CO_SUS;
499 case 0: {
500 lua_Debug ar;
501 if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
502 return CO_NOR; /* it is running */
503 else if (lua_gettop(co) == 0)
504 return CO_DEAD;
505 else
506 return CO_SUS; /* initial state */
507 }
508 default: /* some error occured */
509 return CO_DEAD;
510 }
511}
512
513
514static int luaB_costatus (lua_State *L) {
515 lua_State *co = lua_tothread(L, 1);
516 luaL_argcheck(L, co, 1, "coroutine expected");
517 lua_pushstring(L, statnames[costatus(L, co)]);
518 return 1;
519}
520
521
522static int auxresume (lua_State *L, lua_State *co, int narg) {
523 int status = costatus(L, co);
524 if (!lua_checkstack(co, narg))
525 luaL_error(L, "too many arguments to resume");
526 if (status != CO_SUS) {
527 lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]);
528 return -1; /* error flag */
529 }
530 lua_xmove(L, co, narg);
531 lua_setlevel(L, co);
532 status = lua_resume(co, narg);
533 if (status == 0 || status == LUA_YIELD) {
534 int nres = lua_gettop(co);
535 if (!lua_checkstack(L, nres + 1))
536 luaL_error(L, "too many results to resume");
537 lua_xmove(co, L, nres); /* move yielded values */
538 return nres;
539 }
540 else {
541 lua_xmove(co, L, 1); /* move error message */
542 return -1; /* error flag */
543 }
544}
545
546
547static int luaB_coresume (lua_State *L) {
548 lua_State *co = lua_tothread(L, 1);
549 int r;
550 luaL_argcheck(L, co, 1, "coroutine expected");
551 r = auxresume(L, co, lua_gettop(L) - 1);
552 if (r < 0) {
553 lua_pushboolean(L, 0);
554 lua_insert(L, -2);
555 return 2; /* return false + error message */
556 }
557 else {
558 lua_pushboolean(L, 1);
559 lua_insert(L, -(r + 1));
560 return r + 1; /* return true + `resume' returns */
561 }
562}
563
564
565static int luaB_auxwrap (lua_State *L) {
566 lua_State *co = lua_tothread(L, lua_upvalueindex(1));
567 int r = auxresume(L, co, lua_gettop(L));
568 if (r < 0) {
569 if (lua_isstring(L, -1)) { /* error object is a string? */
570 luaL_where(L, 1); /* add extra info */
571 lua_insert(L, -2);
572 lua_concat(L, 2);
573 }
574 lua_error(L); /* propagate error */
575 }
576 return r;
577}
578
579
580static int luaB_cocreate (lua_State *L) {
581 lua_State *NL = lua_newthread(L);
582 luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
583 "Lua function expected");
584 lua_pushvalue(L, 1); /* move function to top */
585 lua_xmove(L, NL, 1); /* move function from L to NL */
586 return 1;
587}
588
589
590static int luaB_cowrap (lua_State *L) {
591 luaB_cocreate(L);
592 lua_pushcclosure(L, luaB_auxwrap, 1);
593 return 1;
594}
595
596
597static int luaB_yield (lua_State *L) {
598 return lua_yield(L, lua_gettop(L));
599}
600
601
602static int luaB_corunning (lua_State *L) {
603 if (lua_pushthread(L))
604 lua_pushnil(L); /* main thread is not a coroutine */
605 return 1;
606}
607
608
609static const luaL_Reg co_funcs[] = {
610 {"create", luaB_cocreate},
611 {"resume", luaB_coresume},
612 {"running", luaB_corunning},
613 {"status", luaB_costatus},
614 {"wrap", luaB_cowrap},
615 {"yield", luaB_yield},
616 {NULL, NULL}
617};
618
619/* }====================================================== */
620
621
622static void auxopen (lua_State *L, const char *name,
623 lua_CFunction f, lua_CFunction u) {
624 lua_pushcfunction(L, u);
625 lua_pushcclosure(L, f, 1);
626 lua_setfield(L, -2, name);
627}
628
629
630static void base_open (lua_State *L) {
631 /* set global _G */ 448 /* set global _G */
632 lua_pushvalue(L, LUA_GLOBALSINDEX); 449 lua_pushglobaltable(L);
633 lua_setglobal(L, "_G"); 450 lua_pushglobaltable(L);
451 lua_setfield(L, -2, "_G");
634 /* open lib into global table */ 452 /* open lib into global table */
635 luaL_register(L, "_G", base_funcs); 453 luaL_setfuncs(L, base_funcs, 0);
636 lua_pushliteral(L, LUA_VERSION); 454 lua_pushliteral(L, LUA_VERSION);
637 lua_setglobal(L, "_VERSION"); /* set global _VERSION */ 455 lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */
638 /* `ipairs' and `pairs' need auxliliary functions as upvalues */ 456 return 1;
639 auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
640 auxopen(L, "pairs", luaB_pairs, luaB_next);
641 /* `newproxy' needs a weaktable as upvalue */
642 lua_createtable(L, 0, 1); /* new table `w' */
643 lua_pushvalue(L, -1); /* `w' will be its own metatable */
644 lua_setmetatable(L, -2);
645 lua_pushliteral(L, "kv");
646 lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */
647 lua_pushcclosure(L, luaB_newproxy, 1);
648 lua_setglobal(L, "newproxy"); /* set global `newproxy' */
649}
650
651
652LUALIB_API int luaopen_base (lua_State *L) {
653 base_open(L);
654 luaL_register(L, LUA_COLIBNAME, co_funcs);
655 return 2;
656} 457}
657 458
diff --git a/apps/plugins/lua/lbitlib.c b/apps/plugins/lua/lbitlib.c
index 76c8d1d39b..31c7b66f12 100644
--- a/apps/plugins/lua/lbitlib.c
+++ b/apps/plugins/lua/lbitlib.c
@@ -1,126 +1,212 @@
1/* Bitwise operations library */ 1/*
2/* (c) Reuben Thomas 2000-2008 */ 2** $Id: lbitlib.c,v 1.18.1.2 2013/07/09 18:01:41 roberto Exp $
3/* bitlib is copyright Reuben Thomas 2000-2008, and is released under the MIT 3** Standard library for bitwise operations
4 license, like Lua (see http://www.lua.org/copyright.html; it's 4** See Copyright Notice in lua.h
5 basically the same as the BSD license). There is no warranty. */ 5*/
6 6
7#include "config.h" 7#define lbitlib_c
8#define LUA_LIB
8 9
9#include "lua.h" 10#include "lua.h"
11
10#include "lauxlib.h" 12#include "lauxlib.h"
11#include "lualib.h" 13#include "lualib.h"
12#include <limits.h>
13 14
14 15
15/* FIXME: Assume lua_Integer is ptrdiff_t */ 16/* number of bits to consider in a number */
16#define LUA_INTEGER_MAX INTPTR_MAX 17#if !defined(LUA_NBITS)
17#define LUA_INTEGER_MIN INTPTR_MIN 18#define LUA_NBITS 32
19#endif
18 20
19/* FIXME: Assume size_t is an unsigned lua_Integer */
20typedef size_t lua_UInteger;
21#define LUA_UINTEGER_MAX UINT_MAX
22 21
22#define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
23 23
24/* Bit type size and limits */ 24/* macro to trim extra bits */
25#define trim(x) ((x) & ALLONES)
25 26
26#define BIT_BITS (CHAR_BIT * sizeof(lua_Integer))
27 27
28/* This code may give warnings if BITLIB_FLOAT_* are too big to fit in 28/* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */
29 long, but that doesn't matter since in that case they won't be 29#define mask(n) (~((ALLONES << 1) << ((n) - 1)))
30 used. */
31#define BIT_MAX (LUA_INTEGER_MAX)
32 30
33#define BIT_MIN (LUA_INTEGER_MIN)
34 31
35#define BIT_UMAX (LUA_UINTEGER_MAX) 32typedef lua_Unsigned b_uint;
36 33
37 34
38/* Define TOBIT to get a bit value */
39#ifdef BUILTIN_CAST
40#define
41#define TOBIT(L, n, res) \
42 ((void)(res), luaL_checkinteger((L), (n)))
43#else
44 35
45#define TOBIT(L, n, res) \ 36static b_uint andaux (lua_State *L) {
46 ((lua_Integer)(((res) = luaL_checknumber(L, (n)) % BIT_UMAX), \ 37 int i, n = lua_gettop(L);
47 (res) > BIT_MAX ? ((res) -= BIT_UMAX, (res) -= 1) : \ 38 b_uint r = ~(b_uint)0;
48 ((res) < BIT_MIN ? ((res) += BIT_UMAX, (res) += 1) : (res)))) 39 for (i = 1; i <= n; i++)
49#endif 40 r &= luaL_checkunsigned(L, i);
41 return trim(r);
42}
50 43
51 44
52#define BIT_TRUNCATE(i) \ 45static int b_and (lua_State *L) {
53 ((i) & BIT_UMAX) 46 b_uint r = andaux(L);
47 lua_pushunsigned(L, r);
48 return 1;
49}
54 50
55 51
56/* Operations 52static int b_test (lua_State *L) {
53 b_uint r = andaux(L);
54 lua_pushboolean(L, r != 0);
55 return 1;
56}
57 57
58 The macros MONADIC and VARIADIC only deal with bitwise operations.
59 58
60 LOGICAL_SHIFT truncates its left-hand operand before shifting so 59static int b_or (lua_State *L) {
61 that any extra bits at the most-significant end are not shifted 60 int i, n = lua_gettop(L);
62 into the result. 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}
63 67
64 ARITHMETIC_SHIFT does not truncate its left-hand operand, so that
65 the sign bits are not removed and right shift work properly.
66 */
67
68#define MONADIC(name, op) \
69 static int bit_ ## name(lua_State *L) { \
70 lua_Number f; \
71 lua_pushinteger(L, BIT_TRUNCATE(op TOBIT(L, 1, f))); \
72 return 1; \
73 }
74 68
75#define VARIADIC(name, op) \ 69static int b_xor (lua_State *L) {
76 static int bit_ ## name(lua_State *L) { \ 70 int i, n = lua_gettop(L);
77 lua_Number f; \ 71 b_uint r = 0;
78 int n = lua_gettop(L), i; \ 72 for (i = 1; i <= n; i++)
79 lua_Integer w = TOBIT(L, 1, f); \ 73 r ^= luaL_checkunsigned(L, i);
80 for (i = 2; i <= n; i++) \ 74 lua_pushunsigned(L, trim(r));
81 w op TOBIT(L, i, f); \ 75 return 1;
82 lua_pushinteger(L, BIT_TRUNCATE(w)); \ 76}
83 return 1; \
84 }
85 77
86#define LOGICAL_SHIFT(name, op) \ 78
87 static int bit_ ## name(lua_State *L) { \ 79static int b_not (lua_State *L) {
88 lua_Number f; \ 80 b_uint r = ~luaL_checkunsigned(L, 1);
89 lua_pushinteger(L, BIT_TRUNCATE(BIT_TRUNCATE((lua_UInteger)TOBIT(L, 1, f)) op \ 81 lua_pushunsigned(L, trim(r));
90 (unsigned)luaL_checknumber(L, 2))); \ 82 return 1;
91 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);
92 } 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}
93 111
94#define ARITHMETIC_SHIFT(name, op) \ 112
95 static int bit_ ## name(lua_State *L) { \ 113static int b_arshift (lua_State *L) {
96 lua_Number f; \ 114 b_uint r = luaL_checkunsigned(L, 1);
97 lua_pushinteger(L, BIT_TRUNCATE((lua_Integer)TOBIT(L, 1, f) op \ 115 int i = luaL_checkint(L, 2);
98 (unsigned)luaL_checknumber(L, 2))); \ 116 if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1))))
99 return 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;
100 } 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 if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */
133 r = (r << i) | (r >> (LUA_NBITS - i));
134 lua_pushunsigned(L, trim(r));
135 return 1;
136}
137
101 138
102MONADIC(bnot, ~) 139static int b_lrot (lua_State *L) {
103VARIADIC(band, &=) 140 return b_rot(L, luaL_checkint(L, 2));
104VARIADIC(bor, |=) 141}
105VARIADIC(bxor, ^=) 142
106ARITHMETIC_SHIFT(lshift, <<) 143
107LOGICAL_SHIFT(rshift, >>) 144static int b_rrot (lua_State *L) {
108ARITHMETIC_SHIFT(arshift, >>) 145 return b_rot(L, -luaL_checkint(L, 2));
109 146}
110static const struct luaL_reg bitlib[] = { 147
111 {"bnot", bit_bnot}, 148
112 {"band", bit_band}, 149/*
113 {"bor", bit_bor}, 150** get field and width arguments for field-manipulation functions,
114 {"bxor", bit_bxor}, 151** checking whether they are valid.
115 {"lshift", bit_lshift}, 152** ('luaL_error' called without 'return' to avoid later warnings about
116 {"rshift", bit_rshift}, 153** 'width' being used uninitialized.)
117 {"arshift", bit_arshift}, 154*/
155static int fieldargs (lua_State *L, int farg, int *width) {
156 int f = luaL_checkint(L, farg);
157 int w = luaL_optint(L, farg + 1, 1);
158 luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
159 luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
160 if (f + w > LUA_NBITS)
161 luaL_error(L, "trying to access non-existent bits");
162 *width = w;
163 return f;
164}
165
166
167static int b_extract (lua_State *L) {
168 int w;
169 b_uint r = luaL_checkunsigned(L, 1);
170 int f = fieldargs(L, 2, &w);
171 r = (r >> f) & mask(w);
172 lua_pushunsigned(L, r);
173 return 1;
174}
175
176
177static int b_replace (lua_State *L) {
178 int w;
179 b_uint r = luaL_checkunsigned(L, 1);
180 b_uint v = luaL_checkunsigned(L, 2);
181 int f = fieldargs(L, 3, &w);
182 int m = mask(w);
183 v &= m; /* erase bits outside given width */
184 r = (r & ~(m << f)) | (v << f);
185 lua_pushunsigned(L, r);
186 return 1;
187}
188
189
190static const luaL_Reg bitlib[] = {
191 {"arshift", b_arshift},
192 {"band", b_and},
193 {"bnot", b_not},
194 {"bor", b_or},
195 {"bxor", b_xor},
196 {"btest", b_test},
197 {"extract", b_extract},
198 {"lrotate", b_lrot},
199 {"lshift", b_lshift},
200 {"replace", b_replace},
201 {"rrotate", b_rrot},
202 {"rshift", b_rshift},
118 {NULL, NULL} 203 {NULL, NULL}
119}; 204};
120 205
121LUALIB_API int luaopen_bit (lua_State *L) { 206
122 luaL_register(L, "bit", bitlib); 207
123 lua_pushnumber(L, BIT_BITS); 208LUAMOD_API int luaopen_bit32 (lua_State *L) {
124 lua_setfield(L, -2, "bits"); 209 luaL_newlib(L, bitlib);
125 return 1; 210 return 1;
126} 211}
212
diff --git a/apps/plugins/lua/lcode.c b/apps/plugins/lua/lcode.c
index cff626b7fa..820b95c0e1 100644
--- a/apps/plugins/lua/lcode.c
+++ b/apps/plugins/lua/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $ 2** $Id: lcode.c,v 2.62.1.1 2013/04/12 18:48:47 roberto Exp $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -21,7 +21,9 @@
21#include "lobject.h" 21#include "lobject.h"
22#include "lopcodes.h" 22#include "lopcodes.h"
23#include "lparser.h" 23#include "lparser.h"
24#include "lstring.h"
24#include "ltable.h" 25#include "ltable.h"
26#include "lvm.h"
25 27
26 28
27#define hasjumps(e) ((e)->t != (e)->f) 29#define hasjumps(e) ((e)->t != (e)->f)
@@ -34,25 +36,23 @@ static int isnumeral(expdesc *e) {
34 36
35void luaK_nil (FuncState *fs, int from, int n) { 37void luaK_nil (FuncState *fs, int from, int n) {
36 Instruction *previous; 38 Instruction *previous;
39 int l = from + n - 1; /* last register to set nil */
37 if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ 40 if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
38 if (fs->pc == 0) { /* function start? */ 41 previous = &fs->f->code[fs->pc-1];
39 if (from >= fs->nactvar) 42 if (GET_OPCODE(*previous) == OP_LOADNIL) {
40 return; /* positions are already clean */ 43 int pfrom = GETARG_A(*previous);
41 } 44 int pl = pfrom + GETARG_B(*previous);
42 else { 45 if ((pfrom <= from && from <= pl + 1) ||
43 previous = &fs->f->code[fs->pc-1]; 46 (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */
44 if (GET_OPCODE(*previous) == OP_LOADNIL) { 47 if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */
45 int pfrom = GETARG_A(*previous); 48 if (pl > l) l = pl; /* l = max(l, pl) */
46 int pto = GETARG_B(*previous); 49 SETARG_A(*previous, from);
47 if (pfrom <= from && from <= pto+1) { /* can connect both? */ 50 SETARG_B(*previous, l - from);
48 if (from+n-1 > pto) 51 return;
49 SETARG_B(*previous, from+n-1);
50 return;
51 }
52 } 52 }
53 } 53 } /* else go through */
54 } 54 }
55 luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */ 55 luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */
56} 56}
57 57
58 58
@@ -176,6 +176,19 @@ void luaK_patchlist (FuncState *fs, int list, int target) {
176} 176}
177 177
178 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
179void luaK_patchtohere (FuncState *fs, int list) { 192void luaK_patchtohere (FuncState *fs, int list) {
180 luaK_getlabel(fs); 193 luaK_getlabel(fs);
181 luaK_concat(fs, &fs->jpc, list); 194 luaK_concat(fs, &fs->jpc, list);
@@ -196,6 +209,55 @@ void luaK_concat (FuncState *fs, int *l1, int l2) {
196} 209}
197 210
198 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
199void luaK_checkstack (FuncState *fs, int n) { 261void luaK_checkstack (FuncState *fs, int n) {
200 int newstack = fs->freereg + n; 262 int newstack = fs->freereg + n;
201 if (newstack > fs->f->maxstacksize) { 263 if (newstack > fs->f->maxstacksize) {
@@ -222,42 +284,59 @@ static void freereg (FuncState *fs, int reg) {
222 284
223static void freeexp (FuncState *fs, expdesc *e) { 285static void freeexp (FuncState *fs, expdesc *e) {
224 if (e->k == VNONRELOC) 286 if (e->k == VNONRELOC)
225 freereg(fs, e->u.s.info); 287 freereg(fs, e->u.info);
226} 288}
227 289
228 290
229static int addk (FuncState *fs, TValue *k, TValue *v) { 291static int addk (FuncState *fs, TValue *key, TValue *v) {
230 lua_State *L = fs->L; 292 lua_State *L = fs->ls->L;
231 TValue *idx = luaH_set(L, fs->h, k); 293 TValue *idx = luaH_set(L, fs->h, key);
232 Proto *f = fs->f; 294 Proto *f = fs->f;
233 int oldsize = f->sizek; 295 int k, oldsize;
234 if (ttisnumber(idx)) { 296 if (ttisnumber(idx)) {
235 lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); 297 lua_Number n = nvalue(idx);
236 return cast_int(nvalue(idx)); 298 lua_number2int(k, n);
237 } 299 if (luaV_rawequalobj(&f->k[k], v))
238 else { /* constant not found; create a new entry */ 300 return k;
239 setnvalue(idx, cast_num(fs->nk)); 301 /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0");
240 luaM_growvector(L, f->k, fs->nk, f->sizek, TValue, 302 go through and create a new entry for this value */
241 MAXARG_Bx, "constant table overflow");
242 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
243 setobj(L, &f->k[fs->nk], v);
244 luaC_barrier(L, f, v);
245 return fs->nk++;
246 } 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;
247} 316}
248 317
249 318
250int luaK_stringK (FuncState *fs, TString *s) { 319int luaK_stringK (FuncState *fs, TString *s) {
251 TValue o; 320 TValue o;
252 setsvalue(fs->L, &o, s); 321 setsvalue(fs->ls->L, &o, s);
253 return addk(fs, &o, &o); 322 return addk(fs, &o, &o);
254} 323}
255 324
256 325
257int luaK_numberK (FuncState *fs, lua_Number r) { 326int luaK_numberK (FuncState *fs, lua_Number r) {
327 int n;
328 lua_State *L = fs->ls->L;
258 TValue o; 329 TValue o;
259 setnvalue(&o, r); 330 setnvalue(&o, r);
260 return addk(fs, &o, &o); 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;
261} 340}
262 341
263 342
@@ -272,7 +351,7 @@ static int nilK (FuncState *fs) {
272 TValue k, v; 351 TValue k, v;
273 setnilvalue(&v); 352 setnilvalue(&v);
274 /* cannot use nil as key; instead use table itself to represent nil */ 353 /* cannot use nil as key; instead use table itself to represent nil */
275 sethvalue(fs->L, &k, fs->h); 354 sethvalue(fs->ls->L, &k, fs->h);
276 return addk(fs, &k, &v); 355 return addk(fs, &k, &v);
277} 356}
278 357
@@ -292,7 +371,7 @@ void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
292void luaK_setoneret (FuncState *fs, expdesc *e) { 371void luaK_setoneret (FuncState *fs, expdesc *e) {
293 if (e->k == VCALL) { /* expression is an open function call? */ 372 if (e->k == VCALL) { /* expression is an open function call? */
294 e->k = VNONRELOC; 373 e->k = VNONRELOC;
295 e->u.s.info = GETARG_A(getcode(fs, e)); 374 e->u.info = GETARG_A(getcode(fs, e));
296 } 375 }
297 else if (e->k == VVARARG) { 376 else if (e->k == VVARARG) {
298 SETARG_B(getcode(fs, e), 2); 377 SETARG_B(getcode(fs, e), 2);
@@ -308,19 +387,18 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
308 break; 387 break;
309 } 388 }
310 case VUPVAL: { 389 case VUPVAL: {
311 e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0); 390 e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
312 e->k = VRELOCABLE;
313 break;
314 }
315 case VGLOBAL: {
316 e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info);
317 e->k = VRELOCABLE; 391 e->k = VRELOCABLE;
318 break; 392 break;
319 } 393 }
320 case VINDEXED: { 394 case VINDEXED: {
321 freereg(fs, e->u.s.aux); 395 OpCode op = OP_GETTABUP; /* assume 't' is in an upvalue */
322 freereg(fs, e->u.s.info); 396 freereg(fs, e->u.ind.idx);
323 e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux); 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);
324 e->k = VRELOCABLE; 402 e->k = VRELOCABLE;
325 break; 403 break;
326 } 404 }
@@ -347,16 +425,16 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
347 luaK_nil(fs, reg, 1); 425 luaK_nil(fs, reg, 1);
348 break; 426 break;
349 } 427 }
350 case VFALSE: case VTRUE: { 428 case VFALSE: case VTRUE: {
351 luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); 429 luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
352 break; 430 break;
353 } 431 }
354 case VK: { 432 case VK: {
355 luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info); 433 luaK_codek(fs, reg, e->u.info);
356 break; 434 break;
357 } 435 }
358 case VKNUM: { 436 case VKNUM: {
359 luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval)); 437 luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval));
360 break; 438 break;
361 } 439 }
362 case VRELOCABLE: { 440 case VRELOCABLE: {
@@ -365,8 +443,8 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
365 break; 443 break;
366 } 444 }
367 case VNONRELOC: { 445 case VNONRELOC: {
368 if (reg != e->u.s.info) 446 if (reg != e->u.info)
369 luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0); 447 luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
370 break; 448 break;
371 } 449 }
372 default: { 450 default: {
@@ -374,7 +452,7 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
374 return; /* nothing to do... */ 452 return; /* nothing to do... */
375 } 453 }
376 } 454 }
377 e->u.s.info = reg; 455 e->u.info = reg;
378 e->k = VNONRELOC; 456 e->k = VNONRELOC;
379} 457}
380 458
@@ -390,7 +468,7 @@ static void discharge2anyreg (FuncState *fs, expdesc *e) {
390static void exp2reg (FuncState *fs, expdesc *e, int reg) { 468static void exp2reg (FuncState *fs, expdesc *e, int reg) {
391 discharge2reg(fs, e, reg); 469 discharge2reg(fs, e, reg);
392 if (e->k == VJMP) 470 if (e->k == VJMP)
393 luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */ 471 luaK_concat(fs, &e->t, e->u.info); /* put this jump in `t' list */
394 if (hasjumps(e)) { 472 if (hasjumps(e)) {
395 int final; /* position after whole expression */ 473 int final; /* position after whole expression */
396 int p_f = NO_JUMP; /* position of an eventual LOAD false */ 474 int p_f = NO_JUMP; /* position of an eventual LOAD false */
@@ -406,7 +484,7 @@ static void exp2reg (FuncState *fs, expdesc *e, int reg) {
406 patchlistaux(fs, e->t, final, reg, p_t); 484 patchlistaux(fs, e->t, final, reg, p_t);
407 } 485 }
408 e->f = e->t = NO_JUMP; 486 e->f = e->t = NO_JUMP;
409 e->u.s.info = reg; 487 e->u.info = reg;
410 e->k = VNONRELOC; 488 e->k = VNONRELOC;
411} 489}
412 490
@@ -422,14 +500,20 @@ void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
422int luaK_exp2anyreg (FuncState *fs, expdesc *e) { 500int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
423 luaK_dischargevars(fs, e); 501 luaK_dischargevars(fs, e);
424 if (e->k == VNONRELOC) { 502 if (e->k == VNONRELOC) {
425 if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */ 503 if (!hasjumps(e)) return e->u.info; /* exp is already in a register */
426 if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */ 504 if (e->u.info >= fs->nactvar) { /* reg. is not a local? */
427 exp2reg(fs, e, e->u.s.info); /* put value on it */ 505 exp2reg(fs, e, e->u.info); /* put value on it */
428 return e->u.s.info; 506 return e->u.info;
429 } 507 }
430 } 508 }
431 luaK_exp2nextreg(fs, e); /* default */ 509 luaK_exp2nextreg(fs, e); /* default */
432 return e->u.s.info; 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);
433} 517}
434 518
435 519
@@ -444,22 +528,24 @@ void luaK_exp2val (FuncState *fs, expdesc *e) {
444int luaK_exp2RK (FuncState *fs, expdesc *e) { 528int luaK_exp2RK (FuncState *fs, expdesc *e) {
445 luaK_exp2val(fs, e); 529 luaK_exp2val(fs, e);
446 switch (e->k) { 530 switch (e->k) {
447 case VKNUM:
448 case VTRUE: 531 case VTRUE:
449 case VFALSE: 532 case VFALSE:
450 case VNIL: { 533 case VNIL: {
451 if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */ 534 if (fs->nk <= MAXINDEXRK) { /* constant fits in RK operand? */
452 e->u.s.info = (e->k == VNIL) ? nilK(fs) : 535 e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
453 (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :
454 boolK(fs, (e->k == VTRUE));
455 e->k = VK; 536 e->k = VK;
456 return RKASK(e->u.s.info); 537 return RKASK(e->u.info);
457 } 538 }
458 else break; 539 else break;
459 } 540 }
541 case VKNUM: {
542 e->u.info = luaK_numberK(fs, e->u.nval);
543 e->k = VK;
544 /* go through */
545 }
460 case VK: { 546 case VK: {
461 if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */ 547 if (e->u.info <= MAXINDEXRK) /* constant fits in argC? */
462 return RKASK(e->u.s.info); 548 return RKASK(e->u.info);
463 else break; 549 else break;
464 } 550 }
465 default: break; 551 default: break;
@@ -473,22 +559,18 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
473 switch (var->k) { 559 switch (var->k) {
474 case VLOCAL: { 560 case VLOCAL: {
475 freeexp(fs, ex); 561 freeexp(fs, ex);
476 exp2reg(fs, ex, var->u.s.info); 562 exp2reg(fs, ex, var->u.info);
477 return; 563 return;
478 } 564 }
479 case VUPVAL: { 565 case VUPVAL: {
480 int e = luaK_exp2anyreg(fs, ex); 566 int e = luaK_exp2anyreg(fs, ex);
481 luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0); 567 luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
482 break;
483 }
484 case VGLOBAL: {
485 int e = luaK_exp2anyreg(fs, ex);
486 luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);
487 break; 568 break;
488 } 569 }
489 case VINDEXED: { 570 case VINDEXED: {
571 OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP;
490 int e = luaK_exp2RK(fs, ex); 572 int e = luaK_exp2RK(fs, ex);
491 luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); 573 luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
492 break; 574 break;
493 } 575 }
494 default: { 576 default: {
@@ -501,20 +583,20 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
501 583
502 584
503void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { 585void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
504 int func; 586 int ereg;
505 luaK_exp2anyreg(fs, e); 587 luaK_exp2anyreg(fs, e);
588 ereg = e->u.info; /* register where 'e' was placed */
506 freeexp(fs, e); 589 freeexp(fs, e);
507 func = fs->freereg; 590 e->u.info = fs->freereg; /* base register for op_self */
508 luaK_reserveregs(fs, 2);
509 luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key));
510 freeexp(fs, key);
511 e->u.s.info = func;
512 e->k = VNONRELOC; 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);
513} 595}
514 596
515 597
516static void invertjump (FuncState *fs, expdesc *e) { 598static void invertjump (FuncState *fs, expdesc *e) {
517 Instruction *pc = getjumpcontrol(fs, e->u.s.info); 599 Instruction *pc = getjumpcontrol(fs, e->u.info);
518 lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && 600 lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
519 GET_OPCODE(*pc) != OP_TEST); 601 GET_OPCODE(*pc) != OP_TEST);
520 SETARG_A(*pc, !(GETARG_A(*pc))); 602 SETARG_A(*pc, !(GETARG_A(*pc)));
@@ -532,7 +614,7 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) {
532 } 614 }
533 discharge2anyreg(fs, e); 615 discharge2anyreg(fs, e);
534 freeexp(fs, e); 616 freeexp(fs, e);
535 return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond); 617 return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond);
536} 618}
537 619
538 620
@@ -540,17 +622,13 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
540 int pc; /* pc of last jump */ 622 int pc; /* pc of last jump */
541 luaK_dischargevars(fs, e); 623 luaK_dischargevars(fs, e);
542 switch (e->k) { 624 switch (e->k) {
543 case VK: case VKNUM: case VTRUE: {
544 pc = NO_JUMP; /* always true; do nothing */
545 break;
546 }
547 case VFALSE: {
548 pc = luaK_jump(fs); /* always jump */
549 break;
550 }
551 case VJMP: { 625 case VJMP: {
552 invertjump(fs, e); 626 invertjump(fs, e);
553 pc = e->u.s.info; 627 pc = e->u.info;
628 break;
629 }
630 case VK: case VKNUM: case VTRUE: {
631 pc = NO_JUMP; /* always true; do nothing */
554 break; 632 break;
555 } 633 }
556 default: { 634 default: {
@@ -564,20 +642,16 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
564} 642}
565 643
566 644
567static void luaK_goiffalse (FuncState *fs, expdesc *e) { 645void luaK_goiffalse (FuncState *fs, expdesc *e) {
568 int pc; /* pc of last jump */ 646 int pc; /* pc of last jump */
569 luaK_dischargevars(fs, e); 647 luaK_dischargevars(fs, e);
570 switch (e->k) { 648 switch (e->k) {
571 case VNIL: case VFALSE: { 649 case VJMP: {
572 pc = NO_JUMP; /* always false; do nothing */ 650 pc = e->u.info;
573 break;
574 }
575 case VTRUE: {
576 pc = luaK_jump(fs); /* always jump */
577 break; 651 break;
578 } 652 }
579 case VJMP: { 653 case VNIL: case VFALSE: {
580 pc = e->u.s.info; 654 pc = NO_JUMP; /* always false; do nothing */
581 break; 655 break;
582 } 656 }
583 default: { 657 default: {
@@ -610,7 +684,7 @@ static void codenot (FuncState *fs, expdesc *e) {
610 case VNONRELOC: { 684 case VNONRELOC: {
611 discharge2anyreg(fs, e); 685 discharge2anyreg(fs, e);
612 freeexp(fs, e); 686 freeexp(fs, e);
613 e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0); 687 e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0);
614 e->k = VRELOCABLE; 688 e->k = VRELOCABLE;
615 break; 689 break;
616 } 690 }
@@ -627,38 +701,28 @@ static void codenot (FuncState *fs, expdesc *e) {
627 701
628 702
629void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { 703void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
630 t->u.s.aux = luaK_exp2RK(fs, 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);
631 t->k = VINDEXED; 709 t->k = VINDEXED;
632} 710}
633 711
634 712
635static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { 713static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
636 lua_Number v1, v2, r; 714 lua_Number r;
637 if (!isnumeral(e1) || !isnumeral(e2)) return 0; 715 if (!isnumeral(e1) || !isnumeral(e2)) return 0;
638 v1 = e1->u.nval; 716 if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0)
639 v2 = e2->u.nval; 717 return 0; /* do not attempt to divide by 0 */
640 switch (op) { 718 r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval);
641 case OP_ADD: r = luai_numadd(v1, v2); break;
642 case OP_SUB: r = luai_numsub(v1, v2); break;
643 case OP_MUL: r = luai_nummul(v1, v2); break;
644 case OP_DIV:
645 if (v2 == 0) return 0; /* do not attempt to divide by 0 */
646 r = luai_numdiv(v1, v2); break;
647 case OP_MOD:
648 if (v2 == 0) return 0; /* do not attempt to divide by 0 */
649 r = luai_nummod(v1, v2); break;
650 case OP_POW: r = luai_numpow(v1, v2); break;
651 case OP_UNM: r = luai_numunm(v1); break;
652 case OP_LEN: return 0; /* no constant folding for 'len' */
653 default: lua_assert(0); r = 0; break;
654 }
655 if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */
656 e1->u.nval = r; 719 e1->u.nval = r;
657 return 1; 720 return 1;
658} 721}
659 722
660 723
661static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { 724static void codearith (FuncState *fs, OpCode op,
725 expdesc *e1, expdesc *e2, int line) {
662 if (constfolding(op, e1, e2)) 726 if (constfolding(op, e1, e2))
663 return; 727 return;
664 else { 728 else {
@@ -672,8 +736,9 @@ static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
672 freeexp(fs, e2); 736 freeexp(fs, e2);
673 freeexp(fs, e1); 737 freeexp(fs, e1);
674 } 738 }
675 e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2); 739 e1->u.info = luaK_codeABC(fs, op, 0, o1, o2);
676 e1->k = VRELOCABLE; 740 e1->k = VRELOCABLE;
741 luaK_fixline(fs, line);
677 } 742 }
678} 743}
679 744
@@ -689,25 +754,28 @@ static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
689 temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ 754 temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
690 cond = 1; 755 cond = 1;
691 } 756 }
692 e1->u.s.info = condjump(fs, op, cond, o1, o2); 757 e1->u.info = condjump(fs, op, cond, o1, o2);
693 e1->k = VJMP; 758 e1->k = VJMP;
694} 759}
695 760
696 761
697void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { 762void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
698 expdesc e2; 763 expdesc e2;
699 e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; 764 e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
700 switch (op) { 765 switch (op) {
701 case OPR_MINUS: { 766 case OPR_MINUS: {
702 if (!isnumeral(e)) 767 if (isnumeral(e)) /* minus constant? */
703 luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ 768 e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */
704 codearith(fs, OP_UNM, e, &e2); 769 else {
770 luaK_exp2anyreg(fs, e);
771 codearith(fs, OP_UNM, e, &e2, line);
772 }
705 break; 773 break;
706 } 774 }
707 case OPR_NOT: codenot(fs, e); break; 775 case OPR_NOT: codenot(fs, e); break;
708 case OPR_LEN: { 776 case OPR_LEN: {
709 luaK_exp2anyreg(fs, e); /* cannot operate on constants */ 777 luaK_exp2anyreg(fs, e); /* cannot operate on constants */
710 codearith(fs, OP_LEN, e, &e2); 778 codearith(fs, OP_LEN, e, &e2, line);
711 break; 779 break;
712 } 780 }
713 default: lua_assert(0); 781 default: lua_assert(0);
@@ -742,7 +810,8 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
742} 810}
743 811
744 812
745void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { 813void luaK_posfix (FuncState *fs, BinOpr op,
814 expdesc *e1, expdesc *e2, int line) {
746 switch (op) { 815 switch (op) {
747 case OPR_AND: { 816 case OPR_AND: {
748 lua_assert(e1->t == NO_JUMP); /* list must be closed */ 817 lua_assert(e1->t == NO_JUMP); /* list must be closed */
@@ -761,29 +830,30 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
761 case OPR_CONCAT: { 830 case OPR_CONCAT: {
762 luaK_exp2val(fs, e2); 831 luaK_exp2val(fs, e2);
763 if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { 832 if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
764 lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1); 833 lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1);
765 freeexp(fs, e1); 834 freeexp(fs, e1);
766 SETARG_B(getcode(fs, e2), e1->u.s.info); 835 SETARG_B(getcode(fs, e2), e1->u.info);
767 e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info; 836 e1->k = VRELOCABLE; e1->u.info = e2->u.info;
768 } 837 }
769 else { 838 else {
770 luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ 839 luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
771 codearith(fs, OP_CONCAT, e1, e2); 840 codearith(fs, OP_CONCAT, e1, e2, line);
772 } 841 }
773 break; 842 break;
774 } 843 }
775 case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break; 844 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
776 case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break; 845 case OPR_MOD: case OPR_POW: {
777 case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break; 846 codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line);
778 case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break; 847 break;
779 case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break; 848 }
780 case OPR_POW: codearith(fs, OP_POW, e1, e2); break; 849 case OPR_EQ: case OPR_LT: case OPR_LE: {
781 case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break; 850 codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2);
782 case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break; 851 break;
783 case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break; 852 }
784 case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break; 853 case OPR_NE: case OPR_GT: case OPR_GE: {
785 case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break; 854 codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2);
786 case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break; 855 break;
856 }
787 default: lua_assert(0); 857 default: lua_assert(0);
788 } 858 }
789} 859}
@@ -794,46 +864,18 @@ void luaK_fixline (FuncState *fs, int line) {
794} 864}
795 865
796 866
797static int luaK_code (FuncState *fs, Instruction i, int line) {
798 Proto *f = fs->f;
799 dischargejpc(fs); /* `pc' will change */
800 /* put new instruction in code array */
801 luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
802 MAX_INT, "code size overflow");
803 f->code[fs->pc] = i;
804 /* save corresponding line information */
805 luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
806 MAX_INT, "code size overflow");
807 f->lineinfo[fs->pc] = line;
808 return fs->pc++;
809}
810
811
812int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
813 lua_assert(getOpMode(o) == iABC);
814 lua_assert(getBMode(o) != OpArgN || b == 0);
815 lua_assert(getCMode(o) != OpArgN || c == 0);
816 return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
817}
818
819
820int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
821 lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
822 lua_assert(getCMode(o) == OpArgN);
823 return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
824}
825
826
827void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { 867void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
828 int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; 868 int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
829 int b = (tostore == LUA_MULTRET) ? 0 : tostore; 869 int b = (tostore == LUA_MULTRET) ? 0 : tostore;
830 lua_assert(tostore != 0); 870 lua_assert(tostore != 0);
831 if (c <= MAXARG_C) 871 if (c <= MAXARG_C)
832 luaK_codeABC(fs, OP_SETLIST, base, b, c); 872 luaK_codeABC(fs, OP_SETLIST, base, b, c);
833 else { 873 else if (c <= MAXARG_Ax) {
834 luaK_codeABC(fs, OP_SETLIST, base, b, 0); 874 luaK_codeABC(fs, OP_SETLIST, base, b, 0);
835 luaK_code(fs, cast(Instruction, c), fs->ls->lastline); 875 codeextraarg(fs, c);
836 } 876 }
877 else
878 luaX_syntaxerror(fs->ls, "constructor too long");
837 fs->freereg = base + 1; /* free registers with list values */ 879 fs->freereg = base + 1; /* free registers with list values */
838} 880}
839 881
diff --git a/apps/plugins/lua/lcode.h b/apps/plugins/lua/lcode.h
index 751b2b5695..6a1424cf5a 100644
--- a/apps/plugins/lua/lcode.h
+++ b/apps/plugins/lua/lcode.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: lcode.h,v 1.58.1.1 2013/04/12 18:48:47 roberto Exp $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -21,13 +21,13 @@
21 21
22 22
23/* 23/*
24** grep "ORDER OPR" if you change these enums 24** grep "ORDER OPR" if you change these enums (ORDER OP)
25*/ 25*/
26typedef enum BinOpr { 26typedef enum BinOpr {
27 OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, 27 OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
28 OPR_CONCAT, 28 OPR_CONCAT,
29 OPR_NE, OPR_EQ, 29 OPR_EQ, OPR_LT, OPR_LE,
30 OPR_LT, OPR_LE, OPR_GT, OPR_GE, 30 OPR_NE, OPR_GT, OPR_GE,
31 OPR_AND, OPR_OR, 31 OPR_AND, OPR_OR,
32 OPR_NOBINOPR 32 OPR_NOBINOPR
33} BinOpr; 33} BinOpr;
@@ -36,14 +36,17 @@ typedef enum BinOpr {
36typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; 36typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
37 37
38 38
39#define getcode(fs,e) ((fs)->f->code[(e)->u.s.info]) 39#define getcode(fs,e) ((fs)->f->code[(e)->u.info])
40 40
41#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) 41#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
42 42
43#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) 43#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)
44 44
45#define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t)
46
45LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); 47LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
46LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); 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);
47LUAI_FUNC void luaK_fixline (FuncState *fs, int line); 50LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
48LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); 51LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
49LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); 52LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
@@ -52,12 +55,14 @@ LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
52LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); 55LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
53LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); 56LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
54LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); 57LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
58LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);
55LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); 59LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
56LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); 60LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
57LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); 61LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
58LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); 62LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
59LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); 63LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
60LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); 64LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
65LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e);
61LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); 66LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
62LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); 67LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
63LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); 68LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
@@ -65,11 +70,13 @@ LUAI_FUNC int luaK_jump (FuncState *fs);
65LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); 70LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
66LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); 71LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
67LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); 72LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
73LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level);
68LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); 74LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
69LUAI_FUNC int luaK_getlabel (FuncState *fs); 75LUAI_FUNC int luaK_getlabel (FuncState *fs);
70LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); 76LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line);
71LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); 77LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
72LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); 78LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1,
79 expdesc *v2, int line);
73LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); 80LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
74 81
75 82
diff --git a/apps/plugins/lua/lctype.h b/apps/plugins/lua/lctype.h
new file mode 100644
index 0000000000..b09b21a337
--- /dev/null
+++ b/apps/plugins/lua/lctype.h
@@ -0,0 +1,95 @@
1/*
2** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 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
diff --git a/apps/plugins/lua/ldebug.c b/apps/plugins/lua/ldebug.c
index 50ad3d3803..20d663efff 100644
--- a/apps/plugins/lua/ldebug.c
+++ b/apps/plugins/lua/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $ 2** $Id: ldebug.c,v 2.90.1.3 2013/05/16 16:04:15 roberto Exp $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -30,23 +30,20 @@
30 30
31 31
32 32
33#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL)
34
35
33static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); 36static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
34 37
35 38
36static int currentpc (lua_State *L, CallInfo *ci) { 39static int currentpc (CallInfo *ci) {
37 if (!isLua(ci)) return -1; /* function is not a Lua function? */ 40 lua_assert(isLua(ci));
38 if (ci == L->ci) 41 return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
39 ci->savedpc = L->savedpc;
40 return pcRel(ci->savedpc, ci_func(ci)->l.p);
41} 42}
42 43
43 44
44static int currentline (lua_State *L, CallInfo *ci) { 45static int currentline (CallInfo *ci) {
45 int pc = currentpc(L, ci); 46 return getfuncline(ci_func(ci)->p, currentpc(ci));
46 if (pc < 0)
47 return -1; /* only active lua functions have current-line information */
48 else
49 return getline(ci_func(ci)->l.p, pc);
50} 47}
51 48
52 49
@@ -58,6 +55,8 @@ LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
58 mask = 0; 55 mask = 0;
59 func = NULL; 56 func = NULL;
60 } 57 }
58 if (isLua(L->ci))
59 L->oldpc = L->ci->u.l.savedpc;
61 L->hook = func; 60 L->hook = func;
62 L->basehookcount = count; 61 L->basehookcount = count;
63 resethookcount(L); 62 resethookcount(L);
@@ -84,19 +83,13 @@ LUA_API int lua_gethookcount (lua_State *L) {
84LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { 83LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
85 int status; 84 int status;
86 CallInfo *ci; 85 CallInfo *ci;
86 if (level < 0) return 0; /* invalid (negative) level */
87 lua_lock(L); 87 lua_lock(L);
88 for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { 88 for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous)
89 level--; 89 level--;
90 if (f_isLua(ci)) /* Lua function? */ 90 if (level == 0 && ci != &L->base_ci) { /* level found? */
91 level -= ci->tailcalls; /* skip lost tail calls */
92 }
93 if (level == 0 && ci > L->base_ci) { /* level found? */
94 status = 1; 91 status = 1;
95 ar->i_ci = cast_int(ci - L->base_ci); 92 ar->i_ci = ci;
96 }
97 else if (level < 0) { /* level is of a lost tail call? */
98 status = 1;
99 ar->i_ci = 0;
100 } 93 }
101 else status = 0; /* no such level */ 94 else status = 0; /* no such level */
102 lua_unlock(L); 95 lua_unlock(L);
@@ -104,43 +97,78 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
104} 97}
105 98
106 99
107static Proto *getluaproto (CallInfo *ci) { 100static const char *upvalname (Proto *p, int uv) {
108 return (isLua(ci) ? ci_func(ci)->l.p : NULL); 101 TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
102 if (s == NULL) return "?";
103 else return getstr(s);
109} 104}
110 105
111 106
112static const char *findlocal (lua_State *L, CallInfo *ci, int n) { 107static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
113 const char *name; 108 int nparams = clLvalue(ci->func)->p->numparams;
114 Proto *fp = getluaproto(ci); 109 if (n >= ci->u.l.base - ci->func - nparams)
115 if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL) 110 return NULL; /* no such vararg */
116 return name; /* is a local variable in a Lua function */
117 else { 111 else {
118 StkId limit = (ci == L->ci) ? L->top : (ci+1)->func; 112 *pos = ci->func + nparams + n;
119 if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */ 113 return "(*vararg)"; /* generic name for any vararg */
120 return "(*temporary)"; 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 */
121 else 136 else
122 return NULL; 137 return NULL; /* no name */
123 } 138 }
139 *pos = base + (n - 1);
140 return name;
124} 141}
125 142
126 143
127LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { 144LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
128 CallInfo *ci = L->base_ci + ar->i_ci; 145 const char *name;
129 const char *name = findlocal(L, ci, n);
130 lua_lock(L); 146 lua_lock(L);
131 if (name) 147 if (ar == NULL) { /* information about non-active function? */
132 luaA_pushobject(L, ci->base + (n - 1)); 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 }
133 lua_unlock(L); 161 lua_unlock(L);
134 return name; 162 return name;
135} 163}
136 164
137 165
138LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { 166LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
139 CallInfo *ci = L->base_ci + ar->i_ci; 167 StkId pos = 0; /* to avoid warnings */
140 const char *name = findlocal(L, ci, n); 168 const char *name = findlocal(L, ar->i_ci, n, &pos);
141 lua_lock(L); 169 lua_lock(L);
142 if (name) 170 if (name)
143 setobjs2s(L, ci->base + (n - 1), L->top - 1); 171 setobjs2s(L, pos, L->top - 1);
144 L->top--; /* pop value */ 172 L->top--; /* pop value */
145 lua_unlock(L); 173 lua_unlock(L);
146 return name; 174 return name;
@@ -148,55 +176,45 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
148 176
149 177
150static void funcinfo (lua_Debug *ar, Closure *cl) { 178static void funcinfo (lua_Debug *ar, Closure *cl) {
151 if (cl->c.isC) { 179 if (noLuaClosure(cl)) {
152 ar->source = "=[C]"; 180 ar->source = "=[C]";
153 ar->linedefined = -1; 181 ar->linedefined = -1;
154 ar->lastlinedefined = -1; 182 ar->lastlinedefined = -1;
155 ar->what = "C"; 183 ar->what = "C";
156 } 184 }
157 else { 185 else {
158 ar->source = getstr(cl->l.p->source); 186 Proto *p = cl->l.p;
159 ar->linedefined = cl->l.p->linedefined; 187 ar->source = p->source ? getstr(p->source) : "=?";
160 ar->lastlinedefined = cl->l.p->lastlinedefined; 188 ar->linedefined = p->linedefined;
189 ar->lastlinedefined = p->lastlinedefined;
161 ar->what = (ar->linedefined == 0) ? "main" : "Lua"; 190 ar->what = (ar->linedefined == 0) ? "main" : "Lua";
162 } 191 }
163 luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); 192 luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
164} 193}
165 194
166 195
167static void info_tailcall (lua_Debug *ar) {
168 ar->name = ar->namewhat = "";
169 ar->what = "tail";
170 ar->lastlinedefined = ar->linedefined = ar->currentline = -1;
171 ar->source = "=(tail call)";
172 luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
173 ar->nups = 0;
174}
175
176
177static void collectvalidlines (lua_State *L, Closure *f) { 196static void collectvalidlines (lua_State *L, Closure *f) {
178 if (f == NULL || f->c.isC) { 197 if (noLuaClosure(f)) {
179 setnilvalue(L->top); 198 setnilvalue(L->top);
199 api_incr_top(L);
180 } 200 }
181 else { 201 else {
182 Table *t = luaH_new(L, 0, 0);
183 int *lineinfo = f->l.p->lineinfo;
184 int i; 202 int i;
185 for (i=0; i<f->l.p->sizelineinfo; i++) 203 TValue v;
186 setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); 204 int *lineinfo = f->l.p->lineinfo;
187 sethvalue(L, L->top, t); 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 */
188 } 211 }
189 incr_top(L);
190} 212}
191 213
192 214
193static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, 215static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
194 Closure *f, CallInfo *ci) { 216 Closure *f, CallInfo *ci) {
195 int status = 1; 217 int status = 1;
196 if (f == NULL) {
197 info_tailcall(ar);
198 return status;
199 }
200 for (; *what; what++) { 218 for (; *what; what++) {
201 switch (*what) { 219 switch (*what) {
202 case 'S': { 220 case 'S': {
@@ -204,15 +222,31 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
204 break; 222 break;
205 } 223 }
206 case 'l': { 224 case 'l': {
207 ar->currentline = (ci) ? currentline(L, ci) : -1; 225 ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1;
208 break; 226 break;
209 } 227 }
210 case 'u': { 228 case 'u': {
211 ar->nups = f->c.nupvalues; 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;
212 break; 242 break;
213 } 243 }
214 case 'n': { 244 case 'n': {
215 ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL; 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;
216 if (ar->namewhat == NULL) { 250 if (ar->namewhat == NULL) {
217 ar->namewhat = ""; /* not found */ 251 ar->namewhat = ""; /* not found */
218 ar->name = NULL; 252 ar->name = NULL;
@@ -231,29 +265,30 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
231 265
232LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { 266LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
233 int status; 267 int status;
234 Closure *f = NULL; 268 Closure *cl;
235 CallInfo *ci = NULL; 269 CallInfo *ci;
270 StkId func;
236 lua_lock(L); 271 lua_lock(L);
237 if (*what == '>') { 272 if (*what == '>') {
238 StkId func = L->top - 1; 273 ci = NULL;
239 luai_apicheck(L, ttisfunction(func)); 274 func = L->top - 1;
275 api_check(L, ttisfunction(func), "function expected");
240 what++; /* skip the '>' */ 276 what++; /* skip the '>' */
241 f = clvalue(func);
242 L->top--; /* pop function */ 277 L->top--; /* pop function */
243 } 278 }
244 else if (ar->i_ci != 0) { /* no tail call? */ 279 else {
245 ci = L->base_ci + ar->i_ci; 280 ci = ar->i_ci;
281 func = ci->func;
246 lua_assert(ttisfunction(ci->func)); 282 lua_assert(ttisfunction(ci->func));
247 f = clvalue(ci->func);
248 } 283 }
249 status = auxgetinfo(L, what, ar, f, ci); 284 cl = ttisclosure(func) ? clvalue(func) : NULL;
285 status = auxgetinfo(L, what, ar, cl, ci);
250 if (strchr(what, 'f')) { 286 if (strchr(what, 'f')) {
251 if (f == NULL) setnilvalue(L->top); 287 setobjs2s(L, L->top, func);
252 else setclvalue(L, L->top, f); 288 api_incr_top(L);
253 incr_top(L);
254 } 289 }
255 if (strchr(what, 'L')) 290 if (strchr(what, 'L'))
256 collectvalidlines(L, f); 291 collectvalidlines(L, cl);
257 lua_unlock(L); 292 lua_unlock(L);
258 return status; 293 return status;
259} 294}
@@ -261,315 +296,231 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
261 296
262/* 297/*
263** {====================================================== 298** {======================================================
264** Symbolic Execution and code checker 299** Symbolic Execution
265** ======================================================= 300** =======================================================
266*/ 301*/
267 302
268#define check(x) if (!(x)) return 0; 303static const char *getobjname (Proto *p, int lastpc, int reg,
304 const char **name);
269 305
270#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode)
271 306
272#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize) 307/*
273 308** find a "name" for the RK value 'c'
274 309*/
275 310static void kname (Proto *p, int pc, int c, const char **name) {
276static int precheck (const Proto *pt) { 311 if (ISK(c)) { /* is 'c' a constant? */
277 check(pt->maxstacksize <= MAXSTACK); 312 TValue *kvalue = &p->k[INDEXK(c)];
278 check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize); 313 if (ttisstring(kvalue)) { /* literal constant? */
279 check(!(pt->is_vararg & VARARG_NEEDSARG) || 314 *name = svalue(kvalue); /* it is its own name */
280 (pt->is_vararg & VARARG_HASARG)); 315 return;
281 check(pt->sizeupvalues <= pt->nups); 316 }
282 check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); 317 /* else no reasonable name found */
283 check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); 318 }
284 return 1; 319 else { /* 'c' is a register */
285} 320 const char *what = getobjname(p, pc, c, name); /* search for 'c' */
286 321 if (what && *what == 'c') { /* found a constant name? */
287 322 return; /* 'name' already filled */
288#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1])
289
290int luaG_checkopenop (Instruction i) {
291 switch (GET_OPCODE(i)) {
292 case OP_CALL:
293 case OP_TAILCALL:
294 case OP_RETURN:
295 case OP_SETLIST: {
296 check(GETARG_B(i) == 0);
297 return 1;
298 } 323 }
299 default: return 0; /* invalid instruction after an open call */ 324 /* else no reasonable name found */
300 } 325 }
326 *name = "?"; /* no reasonable name found */
301} 327}
302 328
303 329
304static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) { 330static int filterpc (int pc, int jmptarget) {
305 switch (mode) { 331 if (pc < jmptarget) /* is code conditional (inside a jump)? */
306 case OpArgN: check(r == 0); break; 332 return -1; /* cannot know who sets that register */
307 case OpArgU: break; 333 else return pc; /* current position sets that register */
308 case OpArgR: checkreg(pt, r); break;
309 case OpArgK:
310 check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize);
311 break;
312 }
313 return 1;
314} 334}
315 335
316 336
317static Instruction symbexec (const Proto *pt, int lastpc, int reg) { 337/*
338** try to find last instruction before 'lastpc' that modified register 'reg'
339*/
340static int findsetreg (Proto *p, int lastpc, int reg) {
318 int pc; 341 int pc;
319 int last; /* stores position of last instruction that changed `reg' */ 342 int setreg = -1; /* keep last instruction that changed 'reg' */
320 last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ 343 int jmptarget = 0; /* any code before this address is conditional */
321 check(precheck(pt));
322 for (pc = 0; pc < lastpc; pc++) { 344 for (pc = 0; pc < lastpc; pc++) {
323 Instruction i = pt->code[pc]; 345 Instruction i = p->code[pc];
324 OpCode op = GET_OPCODE(i); 346 OpCode op = GET_OPCODE(i);
325 int a = GETARG_A(i); 347 int a = GETARG_A(i);
326 int b = 0;
327 int c = 0;
328 check(op < NUM_OPCODES);
329 checkreg(pt, a);
330 switch (getOpMode(op)) {
331 case iABC: {
332 b = GETARG_B(i);
333 c = GETARG_C(i);
334 check(checkArgMode(pt, b, getBMode(op)));
335 check(checkArgMode(pt, c, getCMode(op)));
336 break;
337 }
338 case iABx: {
339 b = GETARG_Bx(i);
340 if (getBMode(op) == OpArgK) check(b < pt->sizek);
341 break;
342 }
343 case iAsBx: {
344 b = GETARG_sBx(i);
345 if (getBMode(op) == OpArgR) {
346 int dest = pc+1+b;
347 check(0 <= dest && dest < pt->sizecode);
348 if (dest > 0) {
349 int j;
350 /* check that it does not jump to a setlist count; this
351 is tricky, because the count from a previous setlist may
352 have the same value of an invalid setlist; so, we must
353 go all the way back to the first of them (if any) */
354 for (j = 0; j < dest; j++) {
355 Instruction d = pt->code[dest-1-j];
356 if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break;
357 }
358 /* if 'j' is even, previous value is not a setlist (even if
359 it looks like one) */
360 check((j&1) == 0);
361 }
362 }
363 break;
364 }
365 }
366 if (testAMode(op)) {
367 if (a == reg) last = pc; /* change register `a' */
368 }
369 if (testTMode(op)) {
370 check(pc+2 < pt->sizecode); /* check skip */
371 check(GET_OPCODE(pt->code[pc+1]) == OP_JMP);
372 }
373 switch (op) { 348 switch (op) {
374 case OP_LOADBOOL: {
375 if (c == 1) { /* does it jump? */
376 check(pc+2 < pt->sizecode); /* check its jump */
377 check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST ||
378 GETARG_C(pt->code[pc+1]) != 0);
379 }
380 break;
381 }
382 case OP_LOADNIL: { 349 case OP_LOADNIL: {
383 if (a <= reg && reg <= b) 350 int b = GETARG_B(i);
384 last = pc; /* set registers from `a' to `b' */ 351 if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */
385 break; 352 setreg = filterpc(pc, jmptarget);
386 }
387 case OP_GETUPVAL:
388 case OP_SETUPVAL: {
389 check(b < pt->nups);
390 break;
391 }
392 case OP_GETGLOBAL:
393 case OP_SETGLOBAL: {
394 check(ttisstring(&pt->k[b]));
395 break;
396 }
397 case OP_SELF: {
398 checkreg(pt, a+1);
399 if (reg == a+1) last = pc;
400 break;
401 }
402 case OP_CONCAT: {
403 check(b < c); /* at least two operands */
404 break;
405 }
406 case OP_TFORLOOP: {
407 check(c >= 1); /* at least one result (control variable) */
408 checkreg(pt, a+2+c); /* space for results */
409 if (reg >= a+2) last = pc; /* affect all regs above its base */
410 break; 353 break;
411 } 354 }
412 case OP_FORLOOP: 355 case OP_TFORCALL: {
413 case OP_FORPREP: 356 if (reg >= a + 2) /* affect all regs above its base */
414 checkreg(pt, a+3); 357 setreg = filterpc(pc, jmptarget);
415 /* go through */
416 case OP_JMP: {
417 int dest = pc+1+b;
418 /* not full check and jump is forward and do not skip `lastpc'? */
419 if (reg != NO_REG && pc < dest && dest <= lastpc)
420 pc += b; /* do the jump */
421 break; 358 break;
422 } 359 }
423 case OP_CALL: 360 case OP_CALL:
424 case OP_TAILCALL: { 361 case OP_TAILCALL: {
425 if (b != 0) { 362 if (reg >= a) /* affect all registers above base */
426 checkreg(pt, a+b-1); 363 setreg = filterpc(pc, jmptarget);
427 }
428 c--; /* c = num. returns */
429 if (c == LUA_MULTRET) {
430 check(checkopenop(pt, pc));
431 }
432 else if (c != 0)
433 checkreg(pt, a+c-1);
434 if (reg >= a) last = pc; /* affect all registers above base */
435 break; 364 break;
436 } 365 }
437 case OP_RETURN: { 366 case OP_JMP: {
438 b--; /* b = num. returns */ 367 int b = GETARG_sBx(i);
439 if (b > 0) checkreg(pt, a+b-1); 368 int dest = pc + 1 + b;
440 break; 369 /* jump is forward and do not skip `lastpc'? */
441 } 370 if (pc < dest && dest <= lastpc) {
442 case OP_SETLIST: { 371 if (dest > jmptarget)
443 if (b > 0) checkreg(pt, a + b); 372 jmptarget = dest; /* update 'jmptarget' */
444 if (c == 0) {
445 pc++;
446 check(pc < pt->sizecode - 1);
447 } 373 }
448 break; 374 break;
449 } 375 }
450 case OP_CLOSURE: { 376 case OP_TEST: {
451 int nup, j; 377 if (reg == a) /* jumped code can change 'a' */
452 check(b < pt->sizep); 378 setreg = filterpc(pc, jmptarget);
453 nup = pt->p[b]->nups;
454 check(pc + nup < pt->sizecode);
455 for (j = 1; j <= nup; j++) {
456 OpCode op1 = GET_OPCODE(pt->code[pc + j]);
457 check(op1 == OP_GETUPVAL || op1 == OP_MOVE);
458 }
459 if (reg != NO_REG) /* tracing? */
460 pc += nup; /* do not 'execute' these pseudo-instructions */
461 break; 379 break;
462 } 380 }
463 case OP_VARARG: { 381 default:
464 check((pt->is_vararg & VARARG_ISVARARG) && 382 if (testAMode(op) && reg == a) /* any instruction that set A */
465 !(pt->is_vararg & VARARG_NEEDSARG)); 383 setreg = filterpc(pc, jmptarget);
466 b--;
467 if (b == LUA_MULTRET) check(checkopenop(pt, pc));
468 checkreg(pt, a+b-1);
469 break; 384 break;
470 }
471 default: break;
472 } 385 }
473 } 386 }
474 return pt->code[last]; 387 return setreg;
475}
476
477#undef check
478#undef checkjump
479#undef checkreg
480
481/* }====================================================== */
482
483
484int luaG_checkcode (const Proto *pt) {
485 return (symbexec(pt, pt->sizecode, NO_REG) != 0);
486} 388}
487 389
488 390
489static const char *kname (Proto *p, int c) { 391static const char *getobjname (Proto *p, int lastpc, int reg,
490 if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
491 return svalue(&p->k[INDEXK(c)]);
492 else
493 return "?";
494}
495
496
497static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
498 const char **name) { 392 const char **name) {
499 if (isLua(ci)) { /* a Lua function? */ 393 int pc;
500 Proto *p = ci_func(ci)->l.p; 394 *name = luaF_getlocalname(p, reg + 1, lastpc);
501 int pc = currentpc(L, ci); 395 if (*name) /* is a local? */
502 Instruction i; 396 return "local";
503 *name = luaF_getlocalname(p, stackpos+1, pc); 397 /* else try symbolic execution */
504 if (*name) /* is a local? */ 398 pc = findsetreg(p, lastpc, reg);
505 return "local"; 399 if (pc != -1) { /* could find instruction? */
506 i = symbexec(p, pc, stackpos); /* try symbolic execution */ 400 Instruction i = p->code[pc];
507 lua_assert(pc != -1); 401 OpCode op = GET_OPCODE(i);
508 switch (GET_OPCODE(i)) { 402 switch (op) {
509 case OP_GETGLOBAL: {
510 int g = GETARG_Bx(i); /* global index */
511 lua_assert(ttisstring(&p->k[g]));
512 *name = svalue(&p->k[g]);
513 return "global";
514 }
515 case OP_MOVE: { 403 case OP_MOVE: {
516 int a = GETARG_A(i); 404 int b = GETARG_B(i); /* move from 'b' to 'a' */
517 int b = GETARG_B(i); /* move from `b' to `a' */ 405 if (b < GETARG_A(i))
518 if (b < a) 406 return getobjname(p, pc, b, name); /* get name for 'b' */
519 return getobjname(L, ci, b, name); /* get name for `b' */
520 break; 407 break;
521 } 408 }
409 case OP_GETTABUP:
522 case OP_GETTABLE: { 410 case OP_GETTABLE: {
523 int k = GETARG_C(i); /* key index */ 411 int k = GETARG_C(i); /* key index */
524 *name = kname(p, k); 412 int t = GETARG_B(i); /* table index */
525 return "field"; 413 const char *vn = (op == OP_GETTABLE) /* name of indexed variable */
414 ? luaF_getlocalname(p, t + 1, pc)
415 : upvalname(p, t);
416 kname(p, pc, k, name);
417 return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
526 } 418 }
527 case OP_GETUPVAL: { 419 case OP_GETUPVAL: {
528 int u = GETARG_B(i); /* upvalue index */ 420 *name = upvalname(p, GETARG_B(i));
529 *name = p->upvalues ? getstr(p->upvalues[u]) : "?";
530 return "upvalue"; 421 return "upvalue";
531 } 422 }
423 case OP_LOADK:
424 case OP_LOADKX: {
425 int b = (op == OP_LOADK) ? GETARG_Bx(i)
426 : GETARG_Ax(p->code[pc + 1]);
427 if (ttisstring(&p->k[b])) {
428 *name = svalue(&p->k[b]);
429 return "constant";
430 }
431 break;
432 }
532 case OP_SELF: { 433 case OP_SELF: {
533 int k = GETARG_C(i); /* key index */ 434 int k = GETARG_C(i); /* key index */
534 *name = kname(p, k); 435 kname(p, pc, k, name);
535 return "method"; 436 return "method";
536 } 437 }
537 default: break; 438 default: break; /* go through to return NULL */
538 } 439 }
539 } 440 }
540 return NULL; /* no useful name found */ 441 return NULL; /* could not find reasonable name */
541} 442}
542 443
543 444
544static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { 445static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
545 Instruction i; 446 TMS tm;
546 if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1)) 447 Proto *p = ci_func(ci)->p; /* calling function */
547 return NULL; /* calling function is not Lua (or is unknown) */ 448 int pc = currentpc(ci); /* calling instruction index */
548 ci--; /* calling function */ 449 Instruction i = p->code[pc]; /* calling instruction */
549 i = ci_func(ci)->l.p->code[currentpc(L, ci)]; 450 switch (GET_OPCODE(i)) {
550 if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || 451 case OP_CALL:
551 GET_OPCODE(i) == OP_TFORLOOP) 452 case OP_TAILCALL: /* get function name */
552 return getobjname(L, ci, GETARG_A(i), name); 453 return getobjname(p, pc, GETARG_A(i), name);
553 else 454 case OP_TFORCALL: { /* for iterator */
554 return NULL; /* no useful name can be found */ 455 *name = "for iterator";
456 return "for iterator";
457 }
458 /* all other instructions can call only through metamethods */
459 case OP_SELF:
460 case OP_GETTABUP:
461 case OP_GETTABLE: tm = TM_INDEX; break;
462 case OP_SETTABUP:
463 case OP_SETTABLE: tm = TM_NEWINDEX; break;
464 case OP_EQ: tm = TM_EQ; break;
465 case OP_ADD: tm = TM_ADD; break;
466 case OP_SUB: tm = TM_SUB; break;
467 case OP_MUL: tm = TM_MUL; break;
468 case OP_DIV: tm = TM_DIV; break;
469 case OP_MOD: tm = TM_MOD; break;
470 case OP_POW: tm = TM_POW; break;
471 case OP_UNM: tm = TM_UNM; break;
472 case OP_LEN: tm = TM_LEN; break;
473 case OP_LT: tm = TM_LT; break;
474 case OP_LE: tm = TM_LE; break;
475 case OP_CONCAT: tm = TM_CONCAT; break;
476 default:
477 return NULL; /* else no useful name can be found */
478 }
479 *name = getstr(G(L)->tmname[tm]);
480 return "metamethod";
555} 481}
556 482
483/* }====================================================== */
484
485
557 486
558/* only ANSI way to check whether a pointer points to an array */ 487/*
488** only ANSI way to check whether a pointer points to an array
489** (used only for error messages, so efficiency is not a big concern)
490*/
559static int isinstack (CallInfo *ci, const TValue *o) { 491static int isinstack (CallInfo *ci, const TValue *o) {
560 StkId p; 492 StkId p;
561 for (p = ci->base; p < ci->top; p++) 493 for (p = ci->u.l.base; p < ci->top; p++)
562 if (o == p) return 1; 494 if (o == p) return 1;
563 return 0; 495 return 0;
564} 496}
565 497
566 498
567void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { 499static const char *getupvalname (CallInfo *ci, const TValue *o,
500 const char **name) {
501 LClosure *c = ci_func(ci);
502 int i;
503 for (i = 0; i < c->nupvalues; i++) {
504 if (c->upvals[i]->v == o) {
505 *name = upvalname(c->p, i);
506 return "upvalue";
507 }
508 }
509 return NULL;
510}
511
512
513l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
514 CallInfo *ci = L->ci;
568 const char *name = NULL; 515 const char *name = NULL;
569 const char *t = luaT_typenames[ttype(o)]; 516 const char *t = objtypename(o);
570 const char *kind = (isinstack(L->ci, o)) ? 517 const char *kind = NULL;
571 getobjname(L, L->ci, cast_int(o - L->base), &name) : 518 if (isLua(ci)) {
572 NULL; 519 kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
520 if (!kind && isinstack(ci, o)) /* no? try a register */
521 kind = getobjname(ci_func(ci)->p, currentpc(ci),
522 cast_int(o - ci->u.l.base), &name);
523 }
573 if (kind) 524 if (kind)
574 luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", 525 luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
575 op, kind, name, t); 526 op, kind, name, t);
@@ -578,14 +529,14 @@ void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
578} 529}
579 530
580 531
581void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { 532l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
582 if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; 533 if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
583 lua_assert(!ttisstring(p1) && !ttisnumber(p1)); 534 lua_assert(!ttisstring(p1) && !ttisnumber(p1));
584 luaG_typeerror(L, p1, "concatenate"); 535 luaG_typeerror(L, p1, "concatenate");
585} 536}
586 537
587 538
588void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { 539l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
589 TValue temp; 540 TValue temp;
590 if (luaV_tonumber(p1, &temp) == NULL) 541 if (luaV_tonumber(p1, &temp) == NULL)
591 p2 = p1; /* first operand is wrong */ 542 p2 = p1; /* first operand is wrong */
@@ -593,14 +544,13 @@ void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
593} 544}
594 545
595 546
596int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { 547l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
597 const char *t1 = luaT_typenames[ttype(p1)]; 548 const char *t1 = objtypename(p1);
598 const char *t2 = luaT_typenames[ttype(p2)]; 549 const char *t2 = objtypename(p2);
599 if (t1[2] == t2[2]) 550 if (t1 == t2)
600 luaG_runerror(L, "attempt to compare two %s values", t1); 551 luaG_runerror(L, "attempt to compare two %s values", t1);
601 else 552 else
602 luaG_runerror(L, "attempt to compare %s with %s", t1, t2); 553 luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
603 return 0;
604} 554}
605 555
606 556
@@ -608,27 +558,32 @@ static void addinfo (lua_State *L, const char *msg) {
608 CallInfo *ci = L->ci; 558 CallInfo *ci = L->ci;
609 if (isLua(ci)) { /* is Lua code? */ 559 if (isLua(ci)) { /* is Lua code? */
610 char buff[LUA_IDSIZE]; /* add file:line information */ 560 char buff[LUA_IDSIZE]; /* add file:line information */
611 int line = currentline(L, ci); 561 int line = currentline(ci);
612 luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE); 562 TString *src = ci_func(ci)->p->source;
563 if (src)
564 luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
565 else { /* no source available; use "?" instead */
566 buff[0] = '?'; buff[1] = '\0';
567 }
613 luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); 568 luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
614 } 569 }
615} 570}
616 571
617 572
618void luaG_errormsg (lua_State *L) { 573l_noret luaG_errormsg (lua_State *L) {
619 if (L->errfunc != 0) { /* is there an error handling function? */ 574 if (L->errfunc != 0) { /* is there an error handling function? */
620 StkId errfunc = restorestack(L, L->errfunc); 575 StkId errfunc = restorestack(L, L->errfunc);
621 if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); 576 if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
622 setobjs2s(L, L->top, L->top - 1); /* move argument */ 577 setobjs2s(L, L->top, L->top - 1); /* move argument */
623 setobjs2s(L, L->top - 1, errfunc); /* push function */ 578 setobjs2s(L, L->top - 1, errfunc); /* push function */
624 incr_top(L); 579 L->top++;
625 luaD_call(L, L->top - 2, 1); /* call it */ 580 luaD_call(L, L->top - 2, 1, 0); /* call it */
626 } 581 }
627 luaD_throw(L, LUA_ERRRUN); 582 luaD_throw(L, LUA_ERRRUN);
628} 583}
629 584
630 585
631void luaG_runerror (lua_State *L, const char *fmt, ...) { 586l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
632 va_list argp; 587 va_list argp;
633 va_start(argp, fmt); 588 va_start(argp, fmt);
634 addinfo(L, luaO_pushvfstring(L, fmt, argp)); 589 addinfo(L, luaO_pushvfstring(L, fmt, argp));
diff --git a/apps/plugins/lua/ldebug.h b/apps/plugins/lua/ldebug.h
index 22226b4096..6445c763ea 100644
--- a/apps/plugins/lua/ldebug.h
+++ b/apps/plugins/lua/ldebug.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: ldebug.h,v 2.7.1.1 2013/04/12 18:48:47 roberto Exp $
3** Auxiliary functions from Debug Interface module 3** Auxiliary functions from Debug Interface module
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -13,21 +13,22 @@
13 13
14#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) 14#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
15 15
16#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) 16#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
17 17
18#define resethookcount(L) (L->hookcount = L->basehookcount) 18#define resethookcount(L) (L->hookcount = L->basehookcount)
19 19
20/* Active Lua function (given call info) */
21#define ci_func(ci) (clLvalue((ci)->func))
20 22
21LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o, 23
22 const char *opname); 24LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
23LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2); 25 const char *opname);
24LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1, 26LUAI_FUNC l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2);
25 const TValue *p2); 27LUAI_FUNC l_noret luaG_aritherror (lua_State *L, const TValue *p1,
26LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1, 28 const TValue *p2);
27 const TValue *p2); 29LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1,
28LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...); 30 const TValue *p2);
29LUAI_FUNC void luaG_errormsg (lua_State *L); 31LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...);
30LUAI_FUNC int luaG_checkcode (const Proto *pt); 32LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
31LUAI_FUNC int luaG_checkopenop (Instruction i);
32 33
33#endif 34#endif
diff --git a/apps/plugins/lua/ldo.c b/apps/plugins/lua/ldo.c
index f303c744c7..e9dd5fa951 100644
--- a/apps/plugins/lua/ldo.c
+++ b/apps/plugins/lua/ldo.c
@@ -1,11 +1,11 @@
1/* 1/*
2** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $ 2** $Id: ldo.c,v 2.108.1.3 2013/11/08 18:22:50 roberto Exp $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
6 6
7 7
8/* #include <setjmp.h> */ 8#include <setjmp.h>
9#include <stdlib.h> 9#include <stdlib.h>
10#include <string.h> 10#include <string.h>
11 11
@@ -14,6 +14,7 @@
14 14
15#include "lua.h" 15#include "lua.h"
16 16
17#include "lapi.h"
17#include "ldebug.h" 18#include "ldebug.h"
18#include "ldo.h" 19#include "ldo.h"
19#include "lfunc.h" 20#include "lfunc.h"
@@ -39,6 +40,38 @@
39** ======================================================= 40** =======================================================
40*/ 41*/
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
42 75
43/* chain list of long jump buffers */ 76/* chain list of long jump buffers */
44struct lua_longjmp { 77struct lua_longjmp {
@@ -48,18 +81,17 @@ struct lua_longjmp {
48}; 81};
49 82
50 83
51void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { 84static void seterrorobj (lua_State *L, int errcode, StkId oldtop) {
52 switch (errcode) { 85 switch (errcode) {
53 case LUA_ERRMEM: { 86 case LUA_ERRMEM: { /* memory error? */
54 setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG)); 87 setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
55 break; 88 break;
56 } 89 }
57 case LUA_ERRERR: { 90 case LUA_ERRERR: {
58 setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); 91 setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
59 break; 92 break;
60 } 93 }
61 case LUA_ERRSYNTAX: 94 default: {
62 case LUA_ERRRUN: {
63 setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ 95 setobjs2s(L, oldtop, L->top - 1); /* error message on current top */
64 break; 96 break;
65 } 97 }
@@ -68,55 +100,39 @@ void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
68} 100}
69 101
70 102
71static void restore_stack_limit (lua_State *L) { 103l_noret luaD_throw (lua_State *L, int errcode) {
72 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); 104 if (L->errorJmp) { /* thread has an error handler? */
73 if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ 105 L->errorJmp->status = errcode; /* set status */
74 int inuse = cast_int(L->ci - L->base_ci); 106 LUAI_THROW(L, L->errorJmp); /* jump to it */
75 if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */
76 luaD_reallocCI(L, LUAI_MAXCALLS);
77 } 107 }
78} 108 else { /* thread has no error handler */
79 109 L->status = cast_byte(errcode); /* mark it as dead */
80 110 if (G(L)->mainthread->errorJmp) { /* main thread has a handler? */
81static void resetstack (lua_State *L, int status) { 111 setobjs2s(L, G(L)->mainthread->top++, L->top - 1); /* copy error obj. */
82 L->ci = L->base_ci; 112 luaD_throw(G(L)->mainthread, errcode); /* re-throw in main thread */
83 L->base = L->ci->base; 113 }
84 luaF_close(L, L->base); /* close eventual pending closures */ 114 else { /* no handler at all; abort */
85 luaD_seterrorobj(L, status, L->base); 115 if (G(L)->panic) { /* panic function? */
86 L->nCcalls = L->baseCcalls; 116 lua_unlock(L);
87 L->allowhook = 1; 117 G(L)->panic(L); /* call it (last chance to jump out) */
88 restore_stack_limit(L); 118 }
89 L->errfunc = 0; 119 abort();
90 L->errorJmp = NULL;
91}
92
93
94void luaD_throw (lua_State *L, int errcode) {
95 if (L->errorJmp) {
96 L->errorJmp->status = errcode;
97 LUAI_THROW(L, L->errorJmp);
98 }
99 else {
100 L->status = cast_byte(errcode);
101 if (G(L)->panic) {
102 resetstack(L, errcode);
103 lua_unlock(L);
104 G(L)->panic(L);
105 } 120 }
106 exit(EXIT_FAILURE);
107 } 121 }
108} 122}
109 123
110 124
111int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { 125int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
126 unsigned short oldnCcalls = L->nCcalls;
112 struct lua_longjmp lj; 127 struct lua_longjmp lj;
113 lj.status = 0; 128 lj.status = LUA_OK;
114 lj.previous = L->errorJmp; /* chain new error handler */ 129 lj.previous = L->errorJmp; /* chain new error handler */
115 L->errorJmp = &lj; 130 L->errorJmp = &lj;
116 LUAI_TRY(L, &lj, 131 LUAI_TRY(L, &lj,
117 (*f)(L, ud); 132 (*f)(L, ud);
118 ); 133 );
119 L->errorJmp = lj.previous; /* restore old error handler */ 134 L->errorJmp = lj.previous; /* restore old error handler */
135 L->nCcalls = oldnCcalls;
120 return lj.status; 136 return lj.status;
121} 137}
122 138
@@ -129,112 +145,127 @@ static void correctstack (lua_State *L, TValue *oldstack) {
129 L->top = (L->top - oldstack) + L->stack; 145 L->top = (L->top - oldstack) + L->stack;
130 for (up = L->openupval; up != NULL; up = up->gch.next) 146 for (up = L->openupval; up != NULL; up = up->gch.next)
131 gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; 147 gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
132 for (ci = L->base_ci; ci <= L->ci; ci++) { 148 for (ci = L->ci; ci != NULL; ci = ci->previous) {
133 ci->top = (ci->top - oldstack) + L->stack; 149 ci->top = (ci->top - oldstack) + L->stack;
134 ci->base = (ci->base - oldstack) + L->stack;
135 ci->func = (ci->func - 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;
136 } 153 }
137 L->base = (L->base - oldstack) + L->stack;
138} 154}
139 155
140 156
157/* some space for error handling */
158#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
159
160
141void luaD_reallocstack (lua_State *L, int newsize) { 161void luaD_reallocstack (lua_State *L, int newsize) {
142 TValue *oldstack = L->stack; 162 TValue *oldstack = L->stack;
143 int realsize = newsize + 1 + EXTRA_STACK; 163 int lim = L->stacksize;
144 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); 164 lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
145 luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue); 165 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK);
146 L->stacksize = realsize; 166 luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue);
147 L->stack_last = L->stack+newsize; 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;
148 correctstack(L, oldstack); 171 correctstack(L, oldstack);
149} 172}
150 173
151 174
152void luaD_reallocCI (lua_State *L, int newsize) { 175void luaD_growstack (lua_State *L, int n) {
153 CallInfo *oldci = L->base_ci; 176 int size = L->stacksize;
154 luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); 177 if (size > LUAI_MAXSTACK) /* error after extra size? */
155 L->size_ci = newsize; 178 luaD_throw(L, LUA_ERRERR);
156 L->ci = (L->ci - oldci) + L->base_ci; 179 else {
157 L->end_ci = L->base_ci + L->size_ci - 1; 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 }
158} 191}
159 192
160 193
161void luaD_growstack (lua_State *L, int n) { 194static int stackinuse (lua_State *L) {
162 if (n <= L->stacksize) /* double size is enough? */ 195 CallInfo *ci;
163 luaD_reallocstack(L, 2*L->stacksize); 196 StkId lim = L->top;
164 else 197 for (ci = L->ci; ci != NULL; ci = ci->previous) {
165 luaD_reallocstack(L, L->stacksize + n); 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 */
166} 202}
167 203
168 204
169static CallInfo *growCI (lua_State *L) { 205void luaD_shrinkstack (lua_State *L) {
170 if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */ 206 int inuse = stackinuse(L);
171 luaD_throw(L, LUA_ERRERR); 207 int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
172 else { 208 if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK;
173 luaD_reallocCI(L, 2*L->size_ci); 209 if (inuse > LUAI_MAXSTACK || /* handling stack overflow? */
174 if (L->size_ci > LUAI_MAXCALLS) 210 goodsize >= L->stacksize) /* would grow instead of shrink? */
175 luaG_runerror(L, "stack overflow"); 211 condmovestack(L); /* don't change stack (change only for debugging) */
176 } 212 else
177 return ++L->ci; 213 luaD_reallocstack(L, goodsize); /* shrink it */
178} 214}
179 215
180 216
181void luaD_callhook (lua_State *L, int event, int line) { 217void luaD_hook (lua_State *L, int event, int line) {
182 lua_Hook hook = L->hook; 218 lua_Hook hook = L->hook;
183 if (hook && L->allowhook) { 219 if (hook && L->allowhook) {
220 CallInfo *ci = L->ci;
184 ptrdiff_t top = savestack(L, L->top); 221 ptrdiff_t top = savestack(L, L->top);
185 ptrdiff_t ci_top = savestack(L, L->ci->top); 222 ptrdiff_t ci_top = savestack(L, ci->top);
186 lua_Debug ar; 223 lua_Debug ar;
187 ar.event = event; 224 ar.event = event;
188 ar.currentline = line; 225 ar.currentline = line;
189 if (event == LUA_HOOKTAILRET) 226 ar.i_ci = ci;
190 ar.i_ci = 0; /* tail call; no debug information about it */
191 else
192 ar.i_ci = cast_int(L->ci - L->base_ci);
193 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 227 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
194 L->ci->top = L->top + LUA_MINSTACK; 228 ci->top = L->top + LUA_MINSTACK;
195 lua_assert(L->ci->top <= L->stack_last); 229 lua_assert(ci->top <= L->stack_last);
196 L->allowhook = 0; /* cannot call hooks inside a hook */ 230 L->allowhook = 0; /* cannot call hooks inside a hook */
231 ci->callstatus |= CIST_HOOKED;
197 lua_unlock(L); 232 lua_unlock(L);
198 (*hook)(L, &ar); 233 (*hook)(L, &ar);
199 lua_lock(L); 234 lua_lock(L);
200 lua_assert(!L->allowhook); 235 lua_assert(!L->allowhook);
201 L->allowhook = 1; 236 L->allowhook = 1;
202 L->ci->top = restorestack(L, ci_top); 237 ci->top = restorestack(L, ci_top);
203 L->top = restorestack(L, 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;
204 } 251 }
252 luaD_hook(L, hook, -1);
253 ci->u.l.savedpc--; /* correct 'pc' */
205} 254}
206 255
207 256
208static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { 257static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
209 int i; 258 int i;
210 int nfixargs = p->numparams; 259 int nfixargs = p->numparams;
211 Table *htab = NULL;
212 StkId base, fixed; 260 StkId base, fixed;
213 for (; actual < nfixargs; ++actual) 261 lua_assert(actual >= nfixargs);
214 setnilvalue(L->top++);
215#if defined(LUA_COMPAT_VARARG)
216 if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */
217 int nvar = actual - nfixargs; /* number of extra arguments */
218 lua_assert(p->is_vararg & VARARG_HASARG);
219 luaC_checkGC(L);
220 htab = luaH_new(L, nvar, 1); /* create `arg' table */
221 for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */
222 setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i);
223 /* store counter in field `n' */
224 setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar));
225 }
226#endif
227 /* move fixed parameters to final position */ 262 /* move fixed parameters to final position */
263 luaD_checkstack(L, p->maxstacksize); /* check again for new 'base' */
228 fixed = L->top - actual; /* first fixed argument */ 264 fixed = L->top - actual; /* first fixed argument */
229 base = L->top; /* final position of first argument */ 265 base = L->top; /* final position of first argument */
230 for (i=0; i<nfixargs; i++) { 266 for (i=0; i<nfixargs; i++) {
231 setobjs2s(L, L->top++, fixed+i); 267 setobjs2s(L, L->top++, fixed + i);
232 setnilvalue(fixed+i); 268 setnilvalue(fixed + i);
233 }
234 /* add `arg' parameter */
235 if (htab) {
236 sethvalue(L, L->top++, htab);
237 lua_assert(iswhite(obj2gco(htab)));
238 } 269 }
239 return base; 270 return base;
240} 271}
@@ -256,100 +287,93 @@ static StkId tryfuncTM (lua_State *L, StkId func) {
256 287
257 288
258 289
259#define inc_ci(L) \ 290#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))
260 ((L->ci == L->end_ci) ? growCI(L) : \
261 (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci))
262 291
263 292
293/*
294** returns true if function has been executed (C function)
295*/
264int luaD_precall (lua_State *L, StkId func, int nresults) { 296int luaD_precall (lua_State *L, StkId func, int nresults) {
265 LClosure *cl; 297 lua_CFunction f;
266 ptrdiff_t funcr; 298 CallInfo *ci;
267 if (!ttisfunction(func)) /* `func' is not a function? */ 299 int n; /* number of arguments (Lua) or returns (C) */
268 func = tryfuncTM(L, func); /* check the `function' tag method */ 300 ptrdiff_t funcr = savestack(L, func);
269 funcr = savestack(L, func); 301 switch (ttype(func)) {
270 cl = &clvalue(func)->l; 302 case LUA_TLCF: /* light C function */
271 L->ci->savedpc = L->savedpc; 303 f = fvalue(func);
272 if (!cl->isC) { /* Lua function? prepare its call */ 304 goto Cfunc;
273 CallInfo *ci; 305 case LUA_TCCL: { /* C closure */
274 StkId st, base; 306 f = clCvalue(func)->f;
275 Proto *p = cl->p; 307 Cfunc:
276 luaD_checkstack(L, p->maxstacksize); 308 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
277 func = restorestack(L, funcr); 309 ci = next_ci(L); /* now 'enter' new function */
278 if (!p->is_vararg) { /* no varargs? */ 310 ci->nresults = nresults;
279 base = func + 1; 311 ci->func = restorestack(L, funcr);
280 if (L->top > base + p->numparams) 312 ci->top = L->top + LUA_MINSTACK;
281 L->top = base + p->numparams; 313 lua_assert(ci->top <= L->stack_last);
282 } 314 ci->callstatus = 0;
283 else { /* vararg function */ 315 luaC_checkGC(L); /* stack grow uses memory */
284 int nargs = cast_int(L->top - func) - 1; 316 if (L->hookmask & LUA_MASKCALL)
285 base = adjust_varargs(L, p, nargs); 317 luaD_hook(L, LUA_HOOKCALL, -1);
286 func = restorestack(L, funcr); /* previous call may change the stack */ 318 lua_unlock(L);
319 n = (*f)(L); /* do the actual call */
320 lua_lock(L);
321 api_checknelems(L, n);
322 luaD_poscall(L, L->top - n);
323 return 1;
287 } 324 }
288 ci = inc_ci(L); /* now `enter' new function */ 325 case LUA_TLCL: { /* Lua function: prepare its call */
289 ci->func = func; 326 StkId base;
290 L->base = ci->base = base; 327 Proto *p = clLvalue(func)->p;
291 ci->top = L->base + p->maxstacksize; 328 n = cast_int(L->top - func) - 1; /* number of real arguments */
292 lua_assert(ci->top <= L->stack_last); 329 luaD_checkstack(L, p->maxstacksize);
293 L->savedpc = p->code; /* starting point */ 330 for (; n < p->numparams; n++)
294 ci->tailcalls = 0; 331 setnilvalue(L->top++); /* complete missing arguments */
295 ci->nresults = nresults; 332 if (!p->is_vararg) {
296 for (st = L->top; st < ci->top; st++) 333 func = restorestack(L, funcr);
297 setnilvalue(st); 334 base = func + 1;
298 L->top = ci->top; 335 }
299 if (L->hookmask & LUA_MASKCALL) { 336 else {
300 L->savedpc++; /* hooks assume 'pc' is already incremented */ 337 base = adjust_varargs(L, p, n);
301 luaD_callhook(L, LUA_HOOKCALL, -1); 338 func = restorestack(L, funcr); /* previous call can change stack */
302 L->savedpc--; /* correct 'pc' */ 339 }
340 ci = next_ci(L); /* now 'enter' new function */
341 ci->nresults = nresults;
342 ci->func = func;
343 ci->u.l.base = base;
344 ci->top = base + p->maxstacksize;
345 lua_assert(ci->top <= L->stack_last);
346 ci->u.l.savedpc = p->code; /* starting point */
347 ci->callstatus = CIST_LUA;
348 L->top = ci->top;
349 luaC_checkGC(L); /* stack grow uses memory */
350 if (L->hookmask & LUA_MASKCALL)
351 callhook(L, ci);
352 return 0;
303 } 353 }
304 return PCRLUA; 354 default: { /* not a function */
305 } 355 func = tryfuncTM(L, func); /* retry with 'function' tag method */
306 else { /* if is a C function, call it */ 356 return luaD_precall(L, func, nresults); /* now it must be a function */
307 CallInfo *ci;
308 int n;
309 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
310 ci = inc_ci(L); /* now `enter' new function */
311 ci->func = restorestack(L, funcr);
312 L->base = ci->base = ci->func + 1;
313 ci->top = L->top + LUA_MINSTACK;
314 lua_assert(ci->top <= L->stack_last);
315 ci->nresults = nresults;
316 if (L->hookmask & LUA_MASKCALL)
317 luaD_callhook(L, LUA_HOOKCALL, -1);
318 lua_unlock(L);
319 n = (*curr_func(L)->c.f)(L); /* do the actual call */
320 lua_lock(L);
321 if (n < 0) /* yielding? */
322 return PCRYIELD;
323 else {
324 luaD_poscall(L, L->top - n);
325 return PCRC;
326 } 357 }
327 } 358 }
328} 359}
329 360
330 361
331static StkId callrethooks (lua_State *L, StkId firstResult) {
332 ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
333 luaD_callhook(L, LUA_HOOKRET, -1);
334 if (f_isLua(L->ci)) { /* Lua function? */
335 while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */
336 luaD_callhook(L, LUA_HOOKTAILRET, -1);
337 }
338 return restorestack(L, fr);
339}
340
341
342int luaD_poscall (lua_State *L, StkId firstResult) { 362int luaD_poscall (lua_State *L, StkId firstResult) {
343 StkId res; 363 StkId res;
344 int wanted, i; 364 int wanted, i;
345 CallInfo *ci; 365 CallInfo *ci = L->ci;
346 if (L->hookmask & LUA_MASKRET) 366 if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
347 firstResult = callrethooks(L, firstResult); 367 if (L->hookmask & LUA_MASKRET) {
348 ci = L->ci--; 368 ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */
369 luaD_hook(L, LUA_HOOKRET, -1);
370 firstResult = restorestack(L, fr);
371 }
372 L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */
373 }
349 res = ci->func; /* res == final position of 1st result */ 374 res = ci->func; /* res == final position of 1st result */
350 wanted = ci->nresults; 375 wanted = ci->nresults;
351 L->base = (ci - 1)->base; /* restore base */ 376 L->ci = ci = ci->previous; /* back to caller */
352 L->savedpc = (ci - 1)->savedpc; /* restore savedpc */
353 /* move results to correct place */ 377 /* move results to correct place */
354 for (i = wanted; i != 0 && firstResult < L->top; i--) 378 for (i = wanted; i != 0 && firstResult < L->top; i--)
355 setobjs2s(L, res++, firstResult++); 379 setobjs2s(L, res++, firstResult++);
@@ -365,112 +389,226 @@ int luaD_poscall (lua_State *L, StkId firstResult) {
365** The arguments are on the stack, right after the function. 389** The arguments are on the stack, right after the function.
366** When returns, all the results are on the stack, starting at the original 390** When returns, all the results are on the stack, starting at the original
367** function position. 391** function position.
368*/ 392*/
369void luaD_call (lua_State *L, StkId func, int nResults) { 393void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) {
370 if (++L->nCcalls >= LUAI_MAXCCALLS) { 394 if (++L->nCcalls >= LUAI_MAXCCALLS) {
371 if (L->nCcalls == LUAI_MAXCCALLS) 395 if (L->nCcalls == LUAI_MAXCCALLS)
372 luaG_runerror(L, "C stack overflow"); 396 luaG_runerror(L, "C stack overflow");
373 else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) 397 else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
374 luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ 398 luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
375 } 399 }
376 if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ 400 if (!allowyield) L->nny++;
377 luaV_execute(L, 1); /* call it */ 401 if (!luaD_precall(L, func, nResults)) /* is a Lua function? */
402 luaV_execute(L); /* call it */
403 if (!allowyield) L->nny--;
378 L->nCcalls--; 404 L->nCcalls--;
379 luaC_checkGC(L);
380} 405}
381 406
382 407
383static void resume (lua_State *L, void *ud) { 408static void finishCcall (lua_State *L) {
384 StkId firstArg = cast(StkId, ud);
385 CallInfo *ci = L->ci; 409 CallInfo *ci = L->ci;
386 if (L->status == 0) { /* start coroutine? */ 410 int n;
387 lua_assert(ci == L->base_ci && firstArg > L->base); 411 lua_assert(ci->u.c.k != NULL); /* must have a continuation */
388 if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) 412 lua_assert(L->nny == 0);
389 return; 413 if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */
414 ci->callstatus &= ~CIST_YPCALL; /* finish 'lua_pcall' */
415 L->errfunc = ci->u.c.old_errfunc;
390 } 416 }
391 else { /* resuming from previous yield */ 417 /* finish 'lua_callk'/'lua_pcall' */
392 lua_assert(L->status == LUA_YIELD); 418 adjustresults(L, ci->nresults);
393 L->status = 0; 419 /* call continuation function */
394 if (!f_isLua(ci)) { /* `common' yield? */ 420 if (!(ci->callstatus & CIST_STAT)) /* no call status? */
395 /* finish interrupted execution of `OP_CALL' */ 421 ci->u.c.status = LUA_YIELD; /* 'default' status */
396 lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || 422 lua_assert(ci->u.c.status != LUA_OK);
397 GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); 423 ci->callstatus = (ci->callstatus & ~(CIST_YPCALL | CIST_STAT)) | CIST_YIELDED;
398 if (luaD_poscall(L, firstArg)) /* complete it... */ 424 lua_unlock(L);
399 L->top = L->ci->top; /* and correct top if not multiple results */ 425 n = (*ci->u.c.k)(L);
426 lua_lock(L);
427 api_checknelems(L, n);
428 /* finish 'luaD_precall' */
429 luaD_poscall(L, L->top - n);
430}
431
432
433static void unroll (lua_State *L, void *ud) {
434 UNUSED(ud);
435 for (;;) {
436 if (L->ci == &L->base_ci) /* stack is empty? */
437 return; /* coroutine finished normally */
438 if (!isLua(L->ci)) /* C function? */
439 finishCcall(L);
440 else { /* Lua function */
441 luaV_finishOp(L); /* finish interrupted instruction */
442 luaV_execute(L); /* execute down to higher C 'boundary' */
400 } 443 }
401 else /* yielded inside a hook: just continue its execution */
402 L->base = L->ci->base;
403 } 444 }
404 luaV_execute(L, cast_int(L->ci - L->base_ci));
405} 445}
406 446
407 447
408static int resume_error (lua_State *L, const char *msg) { 448/*
409 L->top = L->ci->base; 449** check whether thread has a suspended protected call
410 setsvalue2s(L, L->top, luaS_new(L, msg)); 450*/
411 incr_top(L); 451static CallInfo *findpcall (lua_State *L) {
412 lua_unlock(L); 452 CallInfo *ci;
413 return LUA_ERRRUN; 453 for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */
454 if (ci->callstatus & CIST_YPCALL)
455 return ci;
456 }
457 return NULL; /* no pending pcall */
458}
459
460
461static int recover (lua_State *L, int status) {
462 StkId oldtop;
463 CallInfo *ci = findpcall(L);
464 if (ci == NULL) return 0; /* no recovery point */
465 /* "finish" luaD_pcall */
466 oldtop = restorestack(L, ci->extra);
467 luaF_close(L, oldtop);
468 seterrorobj(L, status, oldtop);
469 L->ci = ci;
470 L->allowhook = ci->u.c.old_allowhook;
471 L->nny = 0; /* should be zero to be yieldable */
472 luaD_shrinkstack(L);
473 L->errfunc = ci->u.c.old_errfunc;
474 ci->callstatus |= CIST_STAT; /* call has error status */
475 ci->u.c.status = status; /* (here it is) */
476 return 1; /* continue running the coroutine */
477}
478
479
480/*
481** signal an error in the call to 'resume', not in the execution of the
482** coroutine itself. (Such errors should not be handled by any coroutine
483** error handler and should not kill the coroutine.)
484*/
485static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
486 L->top = firstArg; /* remove args from the stack */
487 setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */
488 api_incr_top(L);
489 luaD_throw(L, -1); /* jump back to 'lua_resume' */
414} 490}
415 491
416 492
417LUA_API int lua_resume (lua_State *L, int nargs) { 493/*
494** do the work for 'lua_resume' in protected mode
495*/
496static void resume (lua_State *L, void *ud) {
497 int nCcalls = L->nCcalls;
498 StkId firstArg = cast(StkId, ud);
499 CallInfo *ci = L->ci;
500 if (nCcalls >= LUAI_MAXCCALLS)
501 resume_error(L, "C stack overflow", firstArg);
502 if (L->status == LUA_OK) { /* may be starting a coroutine */
503 if (ci != &L->base_ci) /* not in base level? */
504 resume_error(L, "cannot resume non-suspended coroutine", firstArg);
505 /* coroutine is in base level; start running it */
506 if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */
507 luaV_execute(L); /* call it */
508 }
509 else if (L->status != LUA_YIELD)
510 resume_error(L, "cannot resume dead coroutine", firstArg);
511 else { /* resuming from previous yield */
512 L->status = LUA_OK;
513 ci->func = restorestack(L, ci->extra);
514 if (isLua(ci)) /* yielded inside a hook? */
515 luaV_execute(L); /* just continue running Lua code */
516 else { /* 'common' yield */
517 if (ci->u.c.k != NULL) { /* does it have a continuation? */
518 int n;
519 ci->u.c.status = LUA_YIELD; /* 'default' status */
520 ci->callstatus |= CIST_YIELDED;
521 lua_unlock(L);
522 n = (*ci->u.c.k)(L); /* call continuation */
523 lua_lock(L);
524 api_checknelems(L, n);
525 firstArg = L->top - n; /* yield results come from continuation */
526 }
527 luaD_poscall(L, firstArg); /* finish 'luaD_precall' */
528 }
529 unroll(L, NULL);
530 }
531 lua_assert(nCcalls == L->nCcalls);
532}
533
534
535LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
418 int status; 536 int status;
537 int oldnny = L->nny; /* save 'nny' */
419 lua_lock(L); 538 lua_lock(L);
420 if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci))
421 return resume_error(L, "cannot resume non-suspended coroutine");
422 if (L->nCcalls >= LUAI_MAXCCALLS)
423 return resume_error(L, "C stack overflow");
424 luai_userstateresume(L, nargs); 539 luai_userstateresume(L, nargs);
425 lua_assert(L->errfunc == 0); 540 L->nCcalls = (from) ? from->nCcalls + 1 : 1;
426 L->baseCcalls = ++L->nCcalls; 541 L->nny = 0; /* allow yields */
542 api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
427 status = luaD_rawrunprotected(L, resume, L->top - nargs); 543 status = luaD_rawrunprotected(L, resume, L->top - nargs);
428 if (status != 0) { /* error? */ 544 if (status == -1) /* error calling 'lua_resume'? */
429 L->status = cast_byte(status); /* mark thread as `dead' */ 545 status = LUA_ERRRUN;
430 luaD_seterrorobj(L, status, L->top); 546 else { /* yield or regular error */
431 L->ci->top = L->top; 547 while (status != LUA_OK && status != LUA_YIELD) { /* error? */
432 } 548 if (recover(L, status)) /* recover point? */
433 else { 549 status = luaD_rawrunprotected(L, unroll, NULL); /* run continuation */
434 lua_assert(L->nCcalls == L->baseCcalls); 550 else { /* unrecoverable error */
435 status = L->status; 551 L->status = cast_byte(status); /* mark thread as `dead' */
552 seterrorobj(L, status, L->top);
553 L->ci->top = L->top;
554 break;
555 }
556 }
557 lua_assert(status == L->status);
436 } 558 }
437 --L->nCcalls; 559 L->nny = oldnny; /* restore 'nny' */
560 L->nCcalls--;
561 lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0));
438 lua_unlock(L); 562 lua_unlock(L);
439 return status; 563 return status;
440} 564}
441 565
442 566
443LUA_API int lua_yield (lua_State *L, int nresults) { 567LUA_API int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k) {
568 CallInfo *ci = L->ci;
444 luai_userstateyield(L, nresults); 569 luai_userstateyield(L, nresults);
445 lua_lock(L); 570 lua_lock(L);
446 if (L->nCcalls > L->baseCcalls) 571 api_checknelems(L, nresults);
447 luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); 572 if (L->nny > 0) {
448 L->base = L->top - nresults; /* protect stack slots below */ 573 if (L != G(L)->mainthread)
574 luaG_runerror(L, "attempt to yield across a C-call boundary");
575 else
576 luaG_runerror(L, "attempt to yield from outside a coroutine");
577 }
449 L->status = LUA_YIELD; 578 L->status = LUA_YIELD;
579 ci->extra = savestack(L, ci->func); /* save current 'func' */
580 if (isLua(ci)) { /* inside a hook? */
581 api_check(L, k == NULL, "hooks cannot continue after yielding");
582 }
583 else {
584 if ((ci->u.c.k = k) != NULL) /* is there a continuation? */
585 ci->u.c.ctx = ctx; /* save context */
586 ci->func = L->top - nresults - 1; /* protect stack below results */
587 luaD_throw(L, LUA_YIELD);
588 }
589 lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */
450 lua_unlock(L); 590 lua_unlock(L);
451 return -1; 591 return 0; /* return to 'luaD_hook' */
452} 592}
453 593
454 594
455int luaD_pcall (lua_State *L, Pfunc func, void *u, 595int luaD_pcall (lua_State *L, Pfunc func, void *u,
456 ptrdiff_t old_top, ptrdiff_t ef) { 596 ptrdiff_t old_top, ptrdiff_t ef) {
457 int status; 597 int status;
458 unsigned short oldnCcalls = L->nCcalls; 598 CallInfo *old_ci = L->ci;
459 ptrdiff_t old_ci = saveci(L, L->ci);
460 lu_byte old_allowhooks = L->allowhook; 599 lu_byte old_allowhooks = L->allowhook;
600 unsigned short old_nny = L->nny;
461 ptrdiff_t old_errfunc = L->errfunc; 601 ptrdiff_t old_errfunc = L->errfunc;
462 L->errfunc = ef; 602 L->errfunc = ef;
463 status = luaD_rawrunprotected(L, func, u); 603 status = luaD_rawrunprotected(L, func, u);
464 if (status != 0) { /* an error occurred? */ 604 if (status != LUA_OK) { /* an error occurred? */
465 StkId oldtop = restorestack(L, old_top); 605 StkId oldtop = restorestack(L, old_top);
466 luaF_close(L, oldtop); /* close eventual pending closures */ 606 luaF_close(L, oldtop); /* close possible pending closures */
467 luaD_seterrorobj(L, status, oldtop); 607 seterrorobj(L, status, oldtop);
468 L->nCcalls = oldnCcalls; 608 L->ci = old_ci;
469 L->ci = restoreci(L, old_ci);
470 L->base = L->ci->base;
471 L->savedpc = L->ci->savedpc;
472 L->allowhook = old_allowhooks; 609 L->allowhook = old_allowhooks;
473 restore_stack_limit(L); 610 L->nny = old_nny;
611 luaD_shrinkstack(L);
474 } 612 }
475 L->errfunc = old_errfunc; 613 L->errfunc = old_errfunc;
476 return status; 614 return status;
@@ -483,35 +621,60 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
483*/ 621*/
484struct SParser { /* data to `f_parser' */ 622struct SParser { /* data to `f_parser' */
485 ZIO *z; 623 ZIO *z;
486 Mbuffer buff; /* buffer to be used by the scanner */ 624 Mbuffer buff; /* dynamic structure used by the scanner */
625 Dyndata dyd; /* dynamic structures used by the parser */
626 const char *mode;
487 const char *name; 627 const char *name;
488}; 628};
489 629
630
631static void checkmode (lua_State *L, const char *mode, const char *x) {
632 if (mode && strchr(mode, x[0]) == NULL) {
633 luaO_pushfstring(L,
634 "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode);
635 luaD_throw(L, LUA_ERRSYNTAX);
636 }
637}
638
639
490static void f_parser (lua_State *L, void *ud) { 640static void f_parser (lua_State *L, void *ud) {
491 int i; 641 int i;
492 Proto *tf;
493 Closure *cl; 642 Closure *cl;
494 struct SParser *p = cast(struct SParser *, ud); 643 struct SParser *p = cast(struct SParser *, ud);
495 int c = luaZ_lookahead(p->z); 644 int c = zgetc(p->z); /* read first character */
496 luaC_checkGC(L); 645 if (c == LUA_SIGNATURE[0]) {
497 tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, 646 checkmode(L, p->mode, "binary");
498 &p->buff, p->name); 647 cl = luaU_undump(L, p->z, &p->buff, p->name);
499 cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); 648 }
500 cl->l.p = tf; 649 else {
501 for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ 650 checkmode(L, p->mode, "text");
502 cl->l.upvals[i] = luaF_newupval(L); 651 cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
503 setclvalue(L, L->top, cl); 652 }
504 incr_top(L); 653 lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues);
654 for (i = 0; i < cl->l.nupvalues; i++) { /* initialize upvalues */
655 UpVal *up = luaF_newupval(L);
656 cl->l.upvals[i] = up;
657 luaC_objbarrier(L, cl, up);
658 }
505} 659}
506 660
507 661
508int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { 662int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
663 const char *mode) {
509 struct SParser p; 664 struct SParser p;
510 int status; 665 int status;
511 p.z = z; p.name = name; 666 L->nny++; /* cannot yield during parsing */
667 p.z = z; p.name = name; p.mode = mode;
668 p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0;
669 p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
670 p.dyd.label.arr = NULL; p.dyd.label.size = 0;
512 luaZ_initbuffer(L, &p.buff); 671 luaZ_initbuffer(L, &p.buff);
513 status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); 672 status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
514 luaZ_freebuffer(L, &p.buff); 673 luaZ_freebuffer(L, &p.buff);
674 luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size);
675 luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size);
676 luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size);
677 L->nny--;
515 return status; 678 return status;
516} 679}
517 680
diff --git a/apps/plugins/lua/ldo.h b/apps/plugins/lua/ldo.h
index 4c97134805..d3d3082c9b 100644
--- a/apps/plugins/lua/ldo.h
+++ b/apps/plugins/lua/ldo.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: ldo.h,v 2.20.1.1 2013/04/12 18:48:47 roberto Exp $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -13,45 +13,34 @@
13#include "lzio.h" 13#include "lzio.h"
14 14
15 15
16#define luaD_checkstack(L,n) \ 16#define luaD_checkstack(L,n) if (L->stack_last - L->top <= (n)) \
17 if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \ 17 luaD_growstack(L, n); else condmovestack(L);
18 luaD_growstack(L, n); \
19 else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1));
20 18
21 19
22#define incr_top(L) {luaD_checkstack(L,1); L->top++;} 20#define incr_top(L) {L->top++; luaD_checkstack(L,0);}
23 21
24#define savestack(L,p) ((char *)(p) - (char *)L->stack) 22#define savestack(L,p) ((char *)(p) - (char *)L->stack)
25#define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) 23#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
26 24
27#define saveci(L,p) ((char *)(p) - (char *)L->base_ci)
28#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n)))
29
30
31/* results from luaD_precall */
32#define PCRLUA 0 /* initiated a call to a Lua function */
33#define PCRC 1 /* did a call to a C function */
34#define PCRYIELD 2 /* C funtion yielded */
35
36 25
37/* type of protected functions, to be ran by `runprotected' */ 26/* type of protected functions, to be ran by `runprotected' */
38typedef void (*Pfunc) (lua_State *L, void *ud); 27typedef void (*Pfunc) (lua_State *L, void *ud);
39 28
40LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); 29LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
41LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line); 30 const char *mode);
31LUAI_FUNC void luaD_hook (lua_State *L, int event, int line);
42LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); 32LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
43LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); 33LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults,
34 int allowyield);
44LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 35LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
45 ptrdiff_t oldtop, ptrdiff_t ef); 36 ptrdiff_t oldtop, ptrdiff_t ef);
46LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); 37LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
47LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize);
48LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); 38LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
49LUAI_FUNC void luaD_growstack (lua_State *L, int n); 39LUAI_FUNC void luaD_growstack (lua_State *L, int n);
40LUAI_FUNC void luaD_shrinkstack (lua_State *L);
50 41
51LUAI_FUNC void luaD_throw (lua_State *L, int errcode); 42LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode);
52LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); 43LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
53 44
54LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop);
55
56#endif 45#endif
57 46
diff --git a/apps/plugins/lua/ldump.c b/apps/plugins/lua/ldump.c
index c9d3d4870f..61fa2cd892 100644
--- a/apps/plugins/lua/ldump.c
+++ b/apps/plugins/lua/ldump.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ 2** $Id: ldump.c,v 2.17.1.1 2013/04/12 18:48:47 roberto Exp $
3** save precompiled Lua chunks 3** save precompiled Lua chunks
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -24,7 +24,7 @@ typedef struct {
24} DumpState; 24} DumpState;
25 25
26#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) 26#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D)
27#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) 27#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D)
28 28
29static void DumpBlock(const void* b, size_t size, DumpState* D) 29static void DumpBlock(const void* b, size_t size, DumpState* D)
30{ 30{
@@ -60,7 +60,7 @@ static void DumpVector(const void* b, int n, size_t size, DumpState* D)
60 60
61static void DumpString(const TString* s, DumpState* D) 61static void DumpString(const TString* s, DumpState* D)
62{ 62{
63 if (s==NULL || getstr(s)==NULL) 63 if (s==NULL)
64 { 64 {
65 size_t size=0; 65 size_t size=0;
66 DumpVar(size,D); 66 DumpVar(size,D);
@@ -69,13 +69,13 @@ static void DumpString(const TString* s, DumpState* D)
69 { 69 {
70 size_t size=s->tsv.len+1; /* include trailing '\0' */ 70 size_t size=s->tsv.len+1; /* include trailing '\0' */
71 DumpVar(size,D); 71 DumpVar(size,D);
72 DumpBlock(getstr(s),size,D); 72 DumpBlock(getstr(s),size*sizeof(char),D);
73 } 73 }
74} 74}
75 75
76#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) 76#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D)
77 77
78static void DumpFunction(const Proto* f, const TString* p, DumpState* D); 78static void DumpFunction(const Proto* f, DumpState* D);
79 79
80static void DumpConstants(const Proto* f, DumpState* D) 80static void DumpConstants(const Proto* f, DumpState* D)
81{ 81{
@@ -84,8 +84,8 @@ static void DumpConstants(const Proto* f, DumpState* D)
84 for (i=0; i<n; i++) 84 for (i=0; i<n; i++)
85 { 85 {
86 const TValue* o=&f->k[i]; 86 const TValue* o=&f->k[i];
87 DumpChar(ttype(o),D); 87 DumpChar(ttypenv(o),D);
88 switch (ttype(o)) 88 switch (ttypenv(o))
89 { 89 {
90 case LUA_TNIL: 90 case LUA_TNIL:
91 break; 91 break;
@@ -98,19 +98,29 @@ static void DumpConstants(const Proto* f, DumpState* D)
98 case LUA_TSTRING: 98 case LUA_TSTRING:
99 DumpString(rawtsvalue(o),D); 99 DumpString(rawtsvalue(o),D);
100 break; 100 break;
101 default: 101 default: lua_assert(0);
102 lua_assert(0); /* cannot happen */
103 break;
104 } 102 }
105 } 103 }
106 n=f->sizep; 104 n=f->sizep;
107 DumpInt(n,D); 105 DumpInt(n,D);
108 for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,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 }
109} 118}
110 119
111static void DumpDebug(const Proto* f, DumpState* D) 120static void DumpDebug(const Proto* f, DumpState* D)
112{ 121{
113 int i,n; 122 int i,n;
123 DumpString((D->strip) ? NULL : f->source,D);
114 n= (D->strip) ? 0 : f->sizelineinfo; 124 n= (D->strip) ? 0 : f->sizelineinfo;
115 DumpVector(f->lineinfo,n,sizeof(int),D); 125 DumpVector(f->lineinfo,n,sizeof(int),D);
116 n= (D->strip) ? 0 : f->sizelocvars; 126 n= (D->strip) ? 0 : f->sizelocvars;
@@ -123,26 +133,25 @@ static void DumpDebug(const Proto* f, DumpState* D)
123 } 133 }
124 n= (D->strip) ? 0 : f->sizeupvalues; 134 n= (D->strip) ? 0 : f->sizeupvalues;
125 DumpInt(n,D); 135 DumpInt(n,D);
126 for (i=0; i<n; i++) DumpString(f->upvalues[i],D); 136 for (i=0; i<n; i++) DumpString(f->upvalues[i].name,D);
127} 137}
128 138
129static void DumpFunction(const Proto* f, const TString* p, DumpState* D) 139static void DumpFunction(const Proto* f, DumpState* D)
130{ 140{
131 DumpString((f->source==p || D->strip) ? NULL : f->source,D);
132 DumpInt(f->linedefined,D); 141 DumpInt(f->linedefined,D);
133 DumpInt(f->lastlinedefined,D); 142 DumpInt(f->lastlinedefined,D);
134 DumpChar(f->nups,D);
135 DumpChar(f->numparams,D); 143 DumpChar(f->numparams,D);
136 DumpChar(f->is_vararg,D); 144 DumpChar(f->is_vararg,D);
137 DumpChar(f->maxstacksize,D); 145 DumpChar(f->maxstacksize,D);
138 DumpCode(f,D); 146 DumpCode(f,D);
139 DumpConstants(f,D); 147 DumpConstants(f,D);
148 DumpUpvalues(f,D);
140 DumpDebug(f,D); 149 DumpDebug(f,D);
141} 150}
142 151
143static void DumpHeader(DumpState* D) 152static void DumpHeader(DumpState* D)
144{ 153{
145 char h[LUAC_HEADERSIZE]; 154 lu_byte h[LUAC_HEADERSIZE];
146 luaU_header(h); 155 luaU_header(h);
147 DumpBlock(h,LUAC_HEADERSIZE,D); 156 DumpBlock(h,LUAC_HEADERSIZE,D);
148} 157}
@@ -159,6 +168,6 @@ int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip
159 D.strip=strip; 168 D.strip=strip;
160 D.status=0; 169 D.status=0;
161 DumpHeader(&D); 170 DumpHeader(&D);
162 DumpFunction(f,NULL,&D); 171 DumpFunction(f,&D);
163 return D.status; 172 return D.status;
164} 173}
diff --git a/apps/plugins/lua/lfunc.c b/apps/plugins/lua/lfunc.c
index 813e88f583..e90e1520ce 100644
--- a/apps/plugins/lua/lfunc.c
+++ b/apps/plugins/lua/lfunc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $ 2** $Id: lfunc.c,v 2.30.1.1 2013/04/12 18:48:47 roberto Exp $
3** Auxiliary functions to manipulate prototypes and closures 3** Auxiliary functions to manipulate prototypes and closures
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -20,30 +20,24 @@
20 20
21 21
22 22
23Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) { 23Closure *luaF_newCclosure (lua_State *L, int n) {
24 Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); 24 Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n), NULL, 0)->cl;
25 luaC_link(L, obj2gco(c), LUA_TFUNCTION); 25 c->c.nupvalues = cast_byte(n);
26 c->c.isC = 1;
27 c->c.env = e;
28 c->c.nupvalues = cast_byte(nelems);
29 return c; 26 return c;
30} 27}
31 28
32 29
33Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) { 30Closure *luaF_newLclosure (lua_State *L, int n) {
34 Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); 31 Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n), NULL, 0)->cl;
35 luaC_link(L, obj2gco(c), LUA_TFUNCTION); 32 c->l.p = NULL;
36 c->l.isC = 0; 33 c->l.nupvalues = cast_byte(n);
37 c->l.env = e; 34 while (n--) c->l.upvals[n] = NULL;
38 c->l.nupvalues = cast_byte(nelems);
39 while (nelems--) c->l.upvals[nelems] = NULL;
40 return c; 35 return c;
41} 36}
42 37
43 38
44UpVal *luaF_newupval (lua_State *L) { 39UpVal *luaF_newupval (lua_State *L) {
45 UpVal *uv = luaM_new(L, UpVal); 40 UpVal *uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), NULL, 0)->uv;
46 luaC_link(L, obj2gco(uv), LUA_TUPVAL);
47 uv->v = &uv->u.value; 41 uv->v = &uv->u.value;
48 setnilvalue(uv->v); 42 setnilvalue(uv->v);
49 return uv; 43 return uv;
@@ -55,21 +49,20 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
55 GCObject **pp = &L->openupval; 49 GCObject **pp = &L->openupval;
56 UpVal *p; 50 UpVal *p;
57 UpVal *uv; 51 UpVal *uv;
58 while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) { 52 while (*pp != NULL && (p = gco2uv(*pp))->v >= level) {
53 GCObject *o = obj2gco(p);
59 lua_assert(p->v != &p->u.value); 54 lua_assert(p->v != &p->u.value);
55 lua_assert(!isold(o) || isold(obj2gco(L)));
60 if (p->v == level) { /* found a corresponding upvalue? */ 56 if (p->v == level) { /* found a corresponding upvalue? */
61 if (isdead(g, obj2gco(p))) /* is it dead? */ 57 if (isdead(g, o)) /* is it dead? */
62 changewhite(obj2gco(p)); /* ressurect it */ 58 changewhite(o); /* resurrect it */
63 return p; 59 return p;
64 } 60 }
65 pp = &p->next; 61 pp = &p->next;
66 } 62 }
67 uv = luaM_new(L, UpVal); /* not found: create a new one */ 63 /* not found: create a new one */
68 uv->tt = LUA_TUPVAL; 64 uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), pp, 0)->uv;
69 uv->marked = luaC_white(g);
70 uv->v = level; /* current value lives in the stack */ 65 uv->v = level; /* current value lives in the stack */
71 uv->next = *pp; /* chain it in the proper position */
72 *pp = obj2gco(uv);
73 uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ 66 uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */
74 uv->u.l.next = g->uvhead.u.l.next; 67 uv->u.l.next = g->uvhead.u.l.next;
75 uv->u.l.next->u.l.prev = uv; 68 uv->u.l.next->u.l.prev = uv;
@@ -96,41 +89,42 @@ void luaF_freeupval (lua_State *L, UpVal *uv) {
96void luaF_close (lua_State *L, StkId level) { 89void luaF_close (lua_State *L, StkId level) {
97 UpVal *uv; 90 UpVal *uv;
98 global_State *g = G(L); 91 global_State *g = G(L);
99 while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) { 92 while (L->openupval != NULL && (uv = gco2uv(L->openupval))->v >= level) {
100 GCObject *o = obj2gco(uv); 93 GCObject *o = obj2gco(uv);
101 lua_assert(!isblack(o) && uv->v != &uv->u.value); 94 lua_assert(!isblack(o) && uv->v != &uv->u.value);
102 L->openupval = uv->next; /* remove from `open' list */ 95 L->openupval = uv->next; /* remove from `open' list */
103 if (isdead(g, o)) 96 if (isdead(g, o))
104 luaF_freeupval(L, uv); /* free upvalue */ 97 luaF_freeupval(L, uv); /* free upvalue */
105 else { 98 else {
106 unlinkupval(uv); 99 unlinkupval(uv); /* remove upvalue from 'uvhead' list */
107 setobj(L, &uv->u.value, uv->v); 100 setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */
108 uv->v = &uv->u.value; /* now current value lives here */ 101 uv->v = &uv->u.value; /* now current value lives here */
109 luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ 102 gch(o)->next = g->allgc; /* link upvalue into 'allgc' list */
103 g->allgc = o;
104 luaC_checkupvalcolor(g, uv);
110 } 105 }
111 } 106 }
112} 107}
113 108
114 109
115Proto *luaF_newproto (lua_State *L) { 110Proto *luaF_newproto (lua_State *L) {
116 Proto *f = luaM_new(L, Proto); 111 Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p;
117 luaC_link(L, obj2gco(f), LUA_TPROTO);
118 f->k = NULL; 112 f->k = NULL;
119 f->sizek = 0; 113 f->sizek = 0;
120 f->p = NULL; 114 f->p = NULL;
121 f->sizep = 0; 115 f->sizep = 0;
122 f->code = NULL; 116 f->code = NULL;
117 f->cache = NULL;
123 f->sizecode = 0; 118 f->sizecode = 0;
119 f->lineinfo = NULL;
124 f->sizelineinfo = 0; 120 f->sizelineinfo = 0;
125 f->sizeupvalues = 0;
126 f->nups = 0;
127 f->upvalues = NULL; 121 f->upvalues = NULL;
122 f->sizeupvalues = 0;
128 f->numparams = 0; 123 f->numparams = 0;
129 f->is_vararg = 0; 124 f->is_vararg = 0;
130 f->maxstacksize = 0; 125 f->maxstacksize = 0;
131 f->lineinfo = NULL;
132 f->sizelocvars = 0;
133 f->locvars = NULL; 126 f->locvars = NULL;
127 f->sizelocvars = 0;
134 f->linedefined = 0; 128 f->linedefined = 0;
135 f->lastlinedefined = 0; 129 f->lastlinedefined = 0;
136 f->source = NULL; 130 f->source = NULL;
@@ -139,23 +133,16 @@ Proto *luaF_newproto (lua_State *L) {
139 133
140 134
141void luaF_freeproto (lua_State *L, Proto *f) { 135void luaF_freeproto (lua_State *L, Proto *f) {
142 luaM_freearray(L, f->code, f->sizecode, Instruction); 136 luaM_freearray(L, f->code, f->sizecode);
143 luaM_freearray(L, f->p, f->sizep, Proto *); 137 luaM_freearray(L, f->p, f->sizep);
144 luaM_freearray(L, f->k, f->sizek, TValue); 138 luaM_freearray(L, f->k, f->sizek);
145 luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); 139 luaM_freearray(L, f->lineinfo, f->sizelineinfo);
146 luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); 140 luaM_freearray(L, f->locvars, f->sizelocvars);
147 luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); 141 luaM_freearray(L, f->upvalues, f->sizeupvalues);
148 luaM_free(L, f); 142 luaM_free(L, f);
149} 143}
150 144
151 145
152void luaF_freeclosure (lua_State *L, Closure *c) {
153 int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) :
154 sizeLclosure(c->l.nupvalues);
155 luaM_freemem(L, c, size);
156}
157
158
159/* 146/*
160** Look for n-th local variable at line `line' in function `func'. 147** Look for n-th local variable at line `line' in function `func'.
161** Returns NULL if not found. 148** Returns NULL if not found.
diff --git a/apps/plugins/lua/lfunc.h b/apps/plugins/lua/lfunc.h
index 4c2b7fd138..ca0d3a3e0b 100644
--- a/apps/plugins/lua/lfunc.h
+++ b/apps/plugins/lua/lfunc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: lfunc.h,v 2.8.1.1 2013/04/12 18:48:47 roberto Exp $
3** Auxiliary functions to manipulate prototypes and closures 3** Auxiliary functions to manipulate prototypes and closures
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -19,13 +19,12 @@
19 19
20 20
21LUAI_FUNC Proto *luaF_newproto (lua_State *L); 21LUAI_FUNC Proto *luaF_newproto (lua_State *L);
22LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e); 22LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems);
23LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e); 23LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems);
24LUAI_FUNC UpVal *luaF_newupval (lua_State *L); 24LUAI_FUNC UpVal *luaF_newupval (lua_State *L);
25LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); 25LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
26LUAI_FUNC void luaF_close (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); 27LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
28LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c);
29LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); 28LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv);
30LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 29LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
31 int pc); 30 int pc);
diff --git a/apps/plugins/lua/lgc.c b/apps/plugins/lua/lgc.c
index d9e0b78294..52460dcdd5 100644
--- a/apps/plugins/lua/lgc.c
+++ b/apps/plugins/lua/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.38.1.1 2007/12/27 13:02:25 roberto Exp $ 2** $Id: lgc.c,v 2.140.1.2 2013/04/26 18:22:05 roberto Exp $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -23,376 +23,663 @@
23#include "ltm.h" 23#include "ltm.h"
24 24
25 25
26#define GCSTEPSIZE 1024u
27#define GCSWEEPMAX 40
28#define GCSWEEPCOST 10
29#define GCFINALIZECOST 100
30 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)
31 32
32#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS)) 33/* maximum number of elements to sweep in each single step */
34#define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4))
33 35
34#define makewhite(g,x) \ 36/* maximum number of finalizers to call in each GC step */
35 ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g))) 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
36 52
37#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
38#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT)
39 53
40#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT) 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)))
41 61
62#define white2gray(x) resetbits(gch(x)->marked, WHITEBITS)
63#define black2gray(x) resetbit(gch(x)->marked, BLACKBIT)
42 64
43#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT)
44#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT)
45 65
66#define isfinalized(x) testbit(gch(x)->marked, FINALIZEDBIT)
46 67
47#define KEYWEAK bitmask(KEYWEAKBIT) 68#define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n)))
48#define VALUEWEAK bitmask(VALUEWEAKBIT)
49 69
50 70
71#define checkconsistency(obj) \
72 lua_longassert(!iscollectable(obj) || righttt(obj))
73
51 74
52#define markvalue(g,o) { checkconsistency(o); \ 75#define markvalue(g,o) { checkconsistency(o); \
53 if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); } 76 if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
54 77
55#define markobject(g,t) { if (iswhite(obj2gco(t))) \ 78#define markobject(g,t) { if ((t) && iswhite(obj2gco(t))) \
56 reallymarkobject(g, obj2gco(t)); } 79 reallymarkobject(g, obj2gco(t)); }
57 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
58 96
59#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause) 97/*
98** link table 'h' into list pointed by 'p'
99*/
100#define linktable(h,p) ((h)->gclist = *(p), *(p) = obj2gco(h))
60 101
61 102
103/*
104** if key is not marked, mark its entry as dead (therefore removing it
105** from the table)
106*/
62static void removeentry (Node *n) { 107static void removeentry (Node *n) {
63 lua_assert(ttisnil(gval(n))); 108 lua_assert(ttisnil(gval(n)));
64 if (iscollectable(gkey(n))) 109 if (valiswhite(gkey(n)))
65 setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */ 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));
66} 128}
67 129
68 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*/
69static void reallymarkobject (global_State *g, GCObject *o) { 243static void reallymarkobject (global_State *g, GCObject *o) {
70 lua_assert(iswhite(o) && !isdead(g, o)); 244 lu_mem size;
71 white2gray(o); 245 white2gray(o);
72 switch (o->gch.tt) { 246 switch (gch(o)->tt) {
73 case LUA_TSTRING: { 247 case LUA_TSHRSTR:
74 return; 248 case LUA_TLNGSTR: {
249 size = sizestring(gco2ts(o));
250 break; /* nothing else to mark; make it black */
75 } 251 }
76 case LUA_TUSERDATA: { 252 case LUA_TUSERDATA: {
77 Table *mt = gco2u(o)->metatable; 253 Table *mt = gco2u(o)->metatable;
78 gray2black(o); /* udata are never gray */ 254 markobject(g, mt);
79 if (mt) markobject(g, mt);
80 markobject(g, gco2u(o)->env); 255 markobject(g, gco2u(o)->env);
81 return; 256 size = sizeudata(gco2u(o));
257 break;
82 } 258 }
83 case LUA_TUPVAL: { 259 case LUA_TUPVAL: {
84 UpVal *uv = gco2uv(o); 260 UpVal *uv = gco2uv(o);
85 markvalue(g, uv->v); 261 markvalue(g, uv->v);
86 if (uv->v == &uv->u.value) /* closed? */ 262 if (uv->v != &uv->u.value) /* open? */
87 gray2black(o); /* open upvalues are never black */ 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;
88 return; 270 return;
89 } 271 }
90 case LUA_TFUNCTION: { 272 case LUA_TCCL: {
91 gco2cl(o)->c.gclist = g->gray; 273 gco2ccl(o)->gclist = g->gray;
92 g->gray = o; 274 g->gray = o;
93 break; 275 return;
94 } 276 }
95 case LUA_TTABLE: { 277 case LUA_TTABLE: {
96 gco2h(o)->gclist = g->gray; 278 linktable(gco2t(o), &g->gray);
97 g->gray = o; 279 return;
98 break;
99 } 280 }
100 case LUA_TTHREAD: { 281 case LUA_TTHREAD: {
101 gco2th(o)->gclist = g->gray; 282 gco2th(o)->gclist = g->gray;
102 g->gray = o; 283 g->gray = o;
103 break; 284 return;
104 } 285 }
105 case LUA_TPROTO: { 286 case LUA_TPROTO: {
106 gco2p(o)->gclist = g->gray; 287 gco2p(o)->gclist = g->gray;
107 g->gray = o; 288 g->gray = o;
108 break; 289 return;
109 } 290 }
110 default: lua_assert(0); 291 default: lua_assert(0); return;
111 } 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]);
112} 305}
113 306
114 307
115static void marktmu (global_State *g) { 308/*
116 GCObject *u = g->tmudata; 309** mark all objects in list of being-finalized
117 if (u) { 310*/
118 do { 311static void markbeingfnz (global_State *g) {
119 u = u->gch.next; 312 GCObject *o;
120 makewhite(g, u); /* may be marked, if left from previous GC */ 313 for (o = g->tobefnz; o != NULL; o = gch(o)->next) {
121 reallymarkobject(g, u); 314 makewhite(g, o);
122 } while (u != g->tmudata); 315 reallymarkobject(g, o);
123 } 316 }
124} 317}
125 318
126 319
127/* move `dead' udata that need finalization to list `tmudata' */ 320/*
128size_t luaC_separateudata (lua_State *L, int all) { 321** mark all values stored in marked open upvalues. (See comment in
129 global_State *g = G(L); 322** 'lstate.h'.)
130 size_t deadmem = 0; 323*/
131 GCObject **p = &g->mainthread->next; 324static void remarkupvals (global_State *g) {
132 GCObject *curr; 325 UpVal *uv;
133 while ((curr = *p) != NULL) { 326 for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
134 if (!(iswhite(curr) || all) || isfinalized(gco2u(curr))) 327 if (isgray(obj2gco(uv)))
135 p = &curr->gch.next; /* don't bother with them */ 328 markvalue(g, uv->v);
136 else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) {
137 markfinalized(gco2u(curr)); /* don't need finalization */
138 p = &curr->gch.next;
139 }
140 else { /* must call its gc method */
141 deadmem += sizeudata(gco2u(curr));
142 markfinalized(gco2u(curr));
143 *p = curr->gch.next;
144 /* link `curr' at the end of `tmudata' list */
145 if (g->tmudata == NULL) /* list is empty? */
146 g->tmudata = curr->gch.next = curr; /* creates a circular list */
147 else {
148 curr->gch.next = g->tmudata->gch.next;
149 g->tmudata->gch.next = curr;
150 g->tmudata = curr;
151 }
152 }
153 } 329 }
154 return deadmem;
155} 330}
156 331
157 332
158static int traversetable (global_State *g, Table *h) { 333/*
159 int i; 334** mark root set and reset all gray lists, to start a new
160 int weakkey = 0; 335** incremental (or full) collection
161 int weakvalue = 0; 336*/
162 const TValue *mode; 337static void restartcollection (global_State *g) {
163 if (h->metatable) 338 g->gray = g->grayagain = NULL;
164 markobject(g, h->metatable); 339 g->weak = g->allweak = g->ephemeron = NULL;
165 mode = gfasttm(g, h->metatable, TM_MODE); 340 markobject(g, g->mainthread);
166 if (mode && ttisstring(mode)) { /* is there a weak mode? */ 341 markvalue(g, &g->l_registry);
167 weakkey = (strchr(svalue(mode), 'k') != NULL); 342 markmt(g);
168 weakvalue = (strchr(svalue(mode), 'v') != NULL); 343 markbeingfnz(g); /* mark any finalizing object left from previous cycle */
169 if (weakkey || weakvalue) { /* is really weak? */ 344}
170 h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */ 345
171 h->marked |= cast_byte((weakkey << KEYWEAKBIT) | 346/* }====================================================== */
172 (weakvalue << VALUEWEAKBIT)); 347
173 h->gclist = g->weak; /* must be cleared after GC, ... */ 348
174 g->weak = obj2gco(h); /* ... so put in the appropriate list */ 349/*
175 } 350** {======================================================
176 } 351** Traverse functions
177 if (weakkey && weakvalue) return 1; 352** =======================================================
178 if (!weakvalue) { 353*/
179 i = h->sizearray; 354
180 while (i--) 355static void traverseweakvalue (global_State *g, Table *h) {
181 markvalue(g, &h->array[i]); 356 Node *n, *limit = gnodelast(h);
182 } 357 /* if there is array part, assume it may have white values (do not
183 i = sizenode(h); 358 traverse it just to check) */
184 while (i--) { 359 int hasclears = (h->sizearray > 0);
185 Node *n = gnode(h, i); 360 for (n = gnode(h, 0); n < limit; n++) {
186 lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); 361 checkdeadkey(n);
187 if (ttisnil(gval(n))) 362 if (ttisnil(gval(n))) /* entry is empty? */
188 removeentry(n); /* remove empty entries */ 363 removeentry(n); /* remove it */
189 else { 364 else {
190 lua_assert(!ttisnil(gkey(n))); 365 lua_assert(!ttisnil(gkey(n)));
191 if (!weakkey) markvalue(g, gkey(n)); 366 markvalue(g, gkey(n)); /* mark key */
192 if (!weakvalue) markvalue(g, gval(n)); 367 if (!hasclears && iscleared(g, gval(n))) /* is there a white value? */
368 hasclears = 1; /* table will have to be cleared */
193 } 369 }
194 } 370 }
195 return weakkey || weakvalue; 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 */
196} 375}
197 376
198 377
199/* 378static int traverseephemeron (global_State *g, Table *h) {
200** All marks are conditional because a GC may happen while the 379 int marked = 0; /* true if an object is marked in this traversal */
201** prototype is still being created 380 int hasclears = 0; /* true if table has white keys */
202*/ 381 int prop = 0; /* true if table has entry "white-key -> white-value" */
203static void traverseproto (global_State *g, Proto *f) { 382 Node *n, *limit = gnodelast(h);
204 int i; 383 int i;
205 if (f->source) stringmark(f->source); 384 /* traverse array part (numeric keys are 'strong') */
206 for (i=0; i<f->sizek; i++) /* mark literals */ 385 for (i = 0; i < h->sizearray; i++) {
207 markvalue(g, &f->k[i]); 386 if (valiswhite(&h->array[i])) {
208 for (i=0; i<f->sizeupvalues; i++) { /* mark upvalue names */ 387 marked = 1;
209 if (f->upvalues[i]) 388 reallymarkobject(g, gcvalue(&h->array[i]));
210 stringmark(f->upvalues[i]); 389 }
211 }
212 for (i=0; i<f->sizep; i++) { /* mark nested protos */
213 if (f->p[i])
214 markobject(g, f->p[i]);
215 } 390 }
216 for (i=0; i<f->sizelocvars; i++) { /* mark local-variable names */ 391 /* traverse hash part */
217 if (f->locvars[i].varname) 392 for (n = gnode(h, 0); n < limit; n++) {
218 stringmark(f->locvars[i].varname); 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 }
219 } 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;
220} 413}
221 414
222 415
223 416static void traversestrongtable (global_State *g, Table *h) {
224static void traverseclosure (global_State *g, Closure *cl) { 417 Node *n, *limit = gnodelast(h);
225 markobject(g, cl->c.env); 418 int i;
226 if (cl->c.isC) { 419 for (i = 0; i < h->sizearray; i++) /* traverse array part */
227 int i; 420 markvalue(g, &h->array[i]);
228 for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */ 421 for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */
229 markvalue(g, &cl->c.upvalue[i]); 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 }
230 } 430 }
231 else { 431}
232 int i; 432
233 lua_assert(cl->l.nupvalues == cl->l.p->nups); 433
234 markobject(g, cl->l.p); 434static lu_mem traversetable (global_State *g, Table *h) {
235 for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */ 435 const char *weakkey, *weakvalue;
236 markobject(g, cl->l.upvals[i]); 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 */
237 } 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));
238} 454}
239 455
240 456
241static void checkstacksizes (lua_State *L, StkId max) { 457static int traverseproto (global_State *g, Proto *f) {
242 int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */ 458 int i;
243 int s_used = cast_int(max - L->stack); /* part of stack in use */ 459 if (f->cache && iswhite(obj2gco(f->cache)))
244 if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */ 460 f->cache = NULL; /* allow cache to be collected */
245 return; /* do not touch the stacks */ 461 markobject(g, f->source);
246 if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci) 462 for (i = 0; i < f->sizek; i++) /* mark literals */
247 luaD_reallocCI(L, L->size_ci/2); /* still big enough... */ 463 markvalue(g, &f->k[i]);
248 condhardstacktests(luaD_reallocCI(L, ci_used + 1)); 464 for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */
249 if (4*s_used < L->stacksize && 465 markobject(g, f->upvalues[i].name);
250 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize) 466 for (i = 0; i < f->sizep; i++) /* mark nested protos */
251 luaD_reallocstack(L, L->stacksize/2); /* still big enough... */ 467 markobject(g, f->p[i]);
252 condhardstacktests(luaD_reallocstack(L, s_used)); 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;
253} 476}
254 477
255 478
256static void traversestack (global_State *g, lua_State *l) { 479static lu_mem traverseCclosure (global_State *g, CClosure *cl) {
257 StkId o, lim; 480 int i;
258 CallInfo *ci; 481 for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */
259 markvalue(g, gt(l)); 482 markvalue(g, &cl->upvalue[i]);
260 lim = l->top; 483 return sizeCclosure(cl->nupvalues);
261 for (ci = l->base_ci; ci <= l->ci; ci++) { 484}
262 lua_assert(ci->top <= l->stack_last); 485
263 if (lim < ci->top) lim = ci->top; 486static lu_mem traverseLclosure (global_State *g, LClosure *cl) {
264 } 487 int i;
265 for (o = l->stack; o < l->top; o++) 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 int n = 0;
497 StkId o = th->stack;
498 if (o == NULL)
499 return 1; /* stack not completely built yet */
500 for (; o < th->top; o++) /* mark live elements in the stack */
266 markvalue(g, o); 501 markvalue(g, o);
267 for (; o <= lim; o++) 502 if (g->gcstate == GCSatomic) { /* final traversal? */
268 setnilvalue(o); 503 StkId lim = th->stack + th->stacksize; /* real end of stack */
269 checkstacksizes(l, lim); 504 for (; o < lim; o++) /* clear not-marked stack slice */
505 setnilvalue(o);
506 }
507 else { /* count call infos to compute size */
508 CallInfo *ci;
509 for (ci = &th->base_ci; ci != th->ci; ci = ci->next)
510 n++;
511 }
512 return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
513 sizeof(CallInfo) * n;
270} 514}
271 515
272 516
273/* 517/*
274** traverse one gray object, turning it to black. 518** traverse one gray object, turning it to black (except for threads,
275** Returns `quantity' traversed. 519** which are always gray).
276*/ 520*/
277static l_mem propagatemark (global_State *g) { 521static void propagatemark (global_State *g) {
522 lu_mem size;
278 GCObject *o = g->gray; 523 GCObject *o = g->gray;
279 lua_assert(isgray(o)); 524 lua_assert(isgray(o));
280 gray2black(o); 525 gray2black(o);
281 switch (o->gch.tt) { 526 switch (gch(o)->tt) {
282 case LUA_TTABLE: { 527 case LUA_TTABLE: {
283 Table *h = gco2h(o); 528 Table *h = gco2t(o);
284 g->gray = h->gclist; 529 g->gray = h->gclist; /* remove from 'gray' list */
285 if (traversetable(g, h)) /* table is weak? */ 530 size = traversetable(g, h);
286 black2gray(o); /* keep it gray */ 531 break;
287 return sizeof(Table) + sizeof(TValue) * h->sizearray + 532 }
288 sizeof(Node) * sizenode(h); 533 case LUA_TLCL: {
289 } 534 LClosure *cl = gco2lcl(o);
290 case LUA_TFUNCTION: { 535 g->gray = cl->gclist; /* remove from 'gray' list */
291 Closure *cl = gco2cl(o); 536 size = traverseLclosure(g, cl);
292 g->gray = cl->c.gclist; 537 break;
293 traverseclosure(g, cl); 538 }
294 return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : 539 case LUA_TCCL: {
295 sizeLclosure(cl->l.nupvalues); 540 CClosure *cl = gco2ccl(o);
541 g->gray = cl->gclist; /* remove from 'gray' list */
542 size = traverseCclosure(g, cl);
543 break;
296 } 544 }
297 case LUA_TTHREAD: { 545 case LUA_TTHREAD: {
298 lua_State *th = gco2th(o); 546 lua_State *th = gco2th(o);
299 g->gray = th->gclist; 547 g->gray = th->gclist; /* remove from 'gray' list */
300 th->gclist = g->grayagain; 548 th->gclist = g->grayagain;
301 g->grayagain = o; 549 g->grayagain = o; /* insert into 'grayagain' list */
302 black2gray(o); 550 black2gray(o);
303 traversestack(g, th); 551 size = traversestack(g, th);
304 return sizeof(lua_State) + sizeof(TValue) * th->stacksize + 552 break;
305 sizeof(CallInfo) * th->size_ci;
306 } 553 }
307 case LUA_TPROTO: { 554 case LUA_TPROTO: {
308 Proto *p = gco2p(o); 555 Proto *p = gco2p(o);
309 g->gray = p->gclist; 556 g->gray = p->gclist; /* remove from 'gray' list */
310 traverseproto(g, p); 557 size = traverseproto(g, p);
311 return sizeof(Proto) + sizeof(Instruction) * p->sizecode + 558 break;
312 sizeof(Proto *) * p->sizep +
313 sizeof(TValue) * p->sizek +
314 sizeof(int) * p->sizelineinfo +
315 sizeof(LocVar) * p->sizelocvars +
316 sizeof(TString *) * p->sizeupvalues;
317 } 559 }
318 default: lua_assert(0); return 0; 560 default: lua_assert(0); return;
319 } 561 }
562 g->GCmemtrav += size;
320} 563}
321 564
322 565
323static size_t propagateall (global_State *g) { 566static void propagateall (global_State *g) {
324 size_t m = 0; 567 while (g->gray) propagatemark(g);
325 while (g->gray) m += propagatemark(g);
326 return m;
327} 568}
328 569
329 570
571static void propagatelist (global_State *g, GCObject *l) {
572 lua_assert(g->gray == NULL); /* no grays left */
573 g->gray = l;
574 propagateall(g); /* traverse all elements from 'l' */
575}
576
330/* 577/*
331** The next function tells whether a key or value can be cleared from 578** retraverse all gray lists. Because tables may be reinserted in other
332** a weak table. Non-collectable objects are never removed from weak 579** lists when traversed, traverse the original lists to avoid traversing
333** tables. Strings behave as `values', so are never removed too. for 580** twice the same table (which is not wrong, but inefficient)
334** other objects: if really collected, cannot keep them; for userdata
335** being finalized, keep them in keys, but not in values
336*/ 581*/
337static int iscleared (const TValue *o, int iskey) { 582static void retraversegrays (global_State *g) {
338 if (!iscollectable(o)) return 0; 583 GCObject *weak = g->weak; /* save original lists */
339 if (ttisstring(o)) { 584 GCObject *grayagain = g->grayagain;
340 stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */ 585 GCObject *ephemeron = g->ephemeron;
341 return 0; 586 g->weak = g->grayagain = g->ephemeron = NULL;
342 } 587 propagateall(g); /* traverse main gray list */
343 return iswhite(gcvalue(o)) || 588 propagatelist(g, grayagain);
344 (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); 589 propagatelist(g, weak);
590 propagatelist(g, ephemeron);
591}
592
593
594static void convergeephemerons (global_State *g) {
595 int changed;
596 do {
597 GCObject *w;
598 GCObject *next = g->ephemeron; /* get ephemeron list */
599 g->ephemeron = NULL; /* tables will return to this list when traversed */
600 changed = 0;
601 while ((w = next) != NULL) {
602 next = gco2t(w)->gclist;
603 if (traverseephemeron(g, gco2t(w))) { /* traverse marked some value? */
604 propagateall(g); /* propagate changes */
605 changed = 1; /* will have to revisit all ephemeron tables */
606 }
607 }
608 } while (changed);
345} 609}
346 610
611/* }====================================================== */
612
347 613
348/* 614/*
349** clear collected entries from weaktables 615** {======================================================
616** Sweep Functions
617** =======================================================
350*/ 618*/
351static void cleartable (GCObject *l) { 619
352 while (l) { 620
353 Table *h = gco2h(l); 621/*
354 int i = h->sizearray; 622** clear entries with unmarked keys from all weaktables in list 'l' up
355 lua_assert(testbit(h->marked, VALUEWEAKBIT) || 623** to element 'f'
356 testbit(h->marked, KEYWEAKBIT)); 624*/
357 if (testbit(h->marked, VALUEWEAKBIT)) { 625static void clearkeys (global_State *g, GCObject *l, GCObject *f) {
358 while (i--) { 626 for (; l != f; l = gco2t(l)->gclist) {
359 TValue *o = &h->array[i]; 627 Table *h = gco2t(l);
360 if (iscleared(o, 0)) /* value was collected? */ 628 Node *n, *limit = gnodelast(h);
361 setnilvalue(o); /* remove value */ 629 for (n = gnode(h, 0); n < limit; n++) {
630 if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) {
631 setnilvalue(gval(n)); /* remove value ... */
632 removeentry(n); /* and remove entry from table */
362 } 633 }
363 } 634 }
364 i = sizenode(h); 635 }
365 while (i--) { 636}
366 Node *n = gnode(h, i); 637
367 if (!ttisnil(gval(n)) && /* non-empty entry? */ 638
368 (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) { 639/*
640** clear entries with unmarked values from all weaktables in list 'l' up
641** to element 'f'
642*/
643static void clearvalues (global_State *g, GCObject *l, GCObject *f) {
644 for (; l != f; l = gco2t(l)->gclist) {
645 Table *h = gco2t(l);
646 Node *n, *limit = gnodelast(h);
647 int i;
648 for (i = 0; i < h->sizearray; i++) {
649 TValue *o = &h->array[i];
650 if (iscleared(g, o)) /* value was collected? */
651 setnilvalue(o); /* remove value */
652 }
653 for (n = gnode(h, 0); n < limit; n++) {
654 if (!ttisnil(gval(n)) && iscleared(g, gval(n))) {
369 setnilvalue(gval(n)); /* remove value ... */ 655 setnilvalue(gval(n)); /* remove value ... */
370 removeentry(n); /* remove entry from table */ 656 removeentry(n); /* and remove entry from table */
371 } 657 }
372 } 658 }
373 l = h->gclist;
374 } 659 }
375} 660}
376 661
377 662
378static void freeobj (lua_State *L, GCObject *o) { 663static void freeobj (lua_State *L, GCObject *o) {
379 switch (o->gch.tt) { 664 switch (gch(o)->tt) {
380 case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; 665 case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
381 case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break; 666 case LUA_TLCL: {
382 case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; 667 luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues));
383 case LUA_TTABLE: luaH_free(L, gco2h(o)); break;
384 case LUA_TTHREAD: {
385 lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread);
386 luaE_freethread(L, gco2th(o));
387 break; 668 break;
388 } 669 }
389 case LUA_TSTRING: { 670 case LUA_TCCL: {
390 G(L)->strt.nuse--; 671 luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues));
391 luaM_freemem(L, o, sizestring(gco2ts(o)));
392 break; 672 break;
393 } 673 }
394 case LUA_TUSERDATA: { 674 case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
395 luaM_freemem(L, o, sizeudata(gco2u(o))); 675 case LUA_TTABLE: luaH_free(L, gco2t(o)); break;
676 case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
677 case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
678 case LUA_TSHRSTR:
679 G(L)->strt.nuse--;
680 /* go through */
681 case LUA_TLNGSTR: {
682 luaM_freemem(L, o, sizestring(gco2ts(o)));
396 break; 683 break;
397 } 684 }
398 default: lua_assert(0); 685 default: lua_assert(0);
@@ -400,312 +687,534 @@ static void freeobj (lua_State *L, GCObject *o) {
400} 687}
401 688
402 689
403
404#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) 690#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM)
691static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count);
405 692
406 693
694/*
695** sweep the (open) upvalues of a thread and resize its stack and
696** list of call-info structures.
697*/
698static void sweepthread (lua_State *L, lua_State *L1) {
699 if (L1->stack == NULL) return; /* stack not completely built yet */
700 sweepwholelist(L, &L1->openupval); /* sweep open upvalues */
701 luaE_freeCI(L1); /* free extra CallInfo slots */
702 /* should not change the stack during an emergency gc cycle */
703 if (G(L)->gckind != KGC_EMERGENCY)
704 luaD_shrinkstack(L1);
705}
706
707
708/*
709** sweep at most 'count' elements from a list of GCObjects erasing dead
710** objects, where a dead (not alive) object is one marked with the "old"
711** (non current) white and not fixed.
712** In non-generational mode, change all non-dead objects back to white,
713** preparing for next collection cycle.
714** In generational mode, keep black objects black, and also mark them as
715** old; stop when hitting an old object, as all objects after that
716** one will be old too.
717** When object is a thread, sweep its list of open upvalues too.
718*/
407static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { 719static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
408 GCObject *curr;
409 global_State *g = G(L); 720 global_State *g = G(L);
410 int deadmask = otherwhite(g); 721 int ow = otherwhite(g);
411 while ((curr = *p) != NULL && count-- > 0) { 722 int toclear, toset; /* bits to clear and to set in all live objects */
412 if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */ 723 int tostop; /* stop sweep when this is true */
413 sweepwholelist(L, &gco2th(curr)->openupval); 724 if (isgenerational(g)) { /* generational mode? */
414 if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */ 725 toclear = ~0; /* clear nothing */
415 lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); 726 toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */
416 makewhite(g, curr); /* make it white (for next cycle) */ 727 tostop = bitmask(OLDBIT); /* do not sweep old generation */
417 p = &curr->gch.next; 728 }
418 } 729 else { /* normal mode */
419 else { /* must erase `curr' */ 730 toclear = maskcolors; /* clear all color bits + old bit */
420 lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); 731 toset = luaC_white(g); /* make object white */
421 *p = curr->gch.next; 732 tostop = 0; /* do not stop */
422 if (curr == g->rootgc) /* is the first element of the list? */ 733 }
423 g->rootgc = curr->gch.next; /* adjust first */ 734 while (*p != NULL && count-- > 0) {
424 freeobj(L, curr); 735 GCObject *curr = *p;
736 int marked = gch(curr)->marked;
737 if (isdeadm(ow, marked)) { /* is 'curr' dead? */
738 *p = gch(curr)->next; /* remove 'curr' from list */
739 freeobj(L, curr); /* erase 'curr' */
740 }
741 else {
742 if (testbits(marked, tostop))
743 return NULL; /* stop sweeping this list */
744 if (gch(curr)->tt == LUA_TTHREAD)
745 sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */
746 /* update marks */
747 gch(curr)->marked = cast_byte((marked & toclear) | toset);
748 p = &gch(curr)->next; /* go to next element */
425 } 749 }
426 } 750 }
751 return (*p == NULL) ? NULL : p;
752}
753
754
755/*
756** sweep a list until a live object (or end of list)
757*/
758static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) {
759 GCObject ** old = p;
760 int i = 0;
761 do {
762 i++;
763 p = sweeplist(L, p, 1);
764 } while (p == old);
765 if (n) *n += i;
427 return p; 766 return p;
428} 767}
429 768
769/* }====================================================== */
770
771
772/*
773** {======================================================
774** Finalization
775** =======================================================
776*/
430 777
431static void checkSizes (lua_State *L) { 778static void checkSizes (lua_State *L) {
432 global_State *g = G(L); 779 global_State *g = G(L);
433 /* check size of string hash */ 780 if (g->gckind != KGC_EMERGENCY) { /* do not change sizes in emergency */
434 if (g->strt.nuse < cast(lu_int32, g->strt.size/4) && 781 int hs = g->strt.size / 2; /* half the size of the string table */
435 g->strt.size > MINSTRTABSIZE*2) 782 if (g->strt.nuse < cast(lu_int32, hs)) /* using less than that half? */
436 luaS_resize(L, g->strt.size/2); /* table is too big */ 783 luaS_resize(L, hs); /* halve its size */
437 /* check size of buffer */ 784 luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */
438 if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */
439 size_t newsize = luaZ_sizebuffer(&g->buff) / 2;
440 luaZ_resizebuffer(L, &g->buff, newsize);
441 } 785 }
442} 786}
443 787
444 788
445static void GCTM (lua_State *L) { 789static GCObject *udata2finalize (global_State *g) {
790 GCObject *o = g->tobefnz; /* get first element */
791 lua_assert(isfinalized(o));
792 g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */
793 gch(o)->next = g->allgc; /* return it to 'allgc' list */
794 g->allgc = o;
795 resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */
796 lua_assert(!isold(o)); /* see MOVE OLD rule */
797 if (!keepinvariantout(g)) /* not keeping invariant? */
798 makewhite(g, o); /* "sweep" object */
799 return o;
800}
801
802
803static void dothecall (lua_State *L, void *ud) {
804 UNUSED(ud);
805 luaD_call(L, L->top - 2, 0, 0);
806}
807
808
809static void GCTM (lua_State *L, int propagateerrors) {
446 global_State *g = G(L); 810 global_State *g = G(L);
447 GCObject *o = g->tmudata->gch.next; /* get first element */
448 Udata *udata = rawgco2u(o);
449 const TValue *tm; 811 const TValue *tm;
450 /* remove udata from `tmudata' */ 812 TValue v;
451 if (o == g->tmudata) /* last element? */ 813 setgcovalue(L, &v, udata2finalize(g));
452 g->tmudata = NULL; 814 tm = luaT_gettmbyobj(L, &v, TM_GC);
453 else 815 if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */
454 g->tmudata->gch.next = udata->uv.next; 816 int status;
455 udata->uv.next = g->mainthread->next; /* return it to `root' list */
456 g->mainthread->next = o;
457 makewhite(g, o);
458 tm = fasttm(L, udata->uv.metatable, TM_GC);
459 if (tm != NULL) {
460 lu_byte oldah = L->allowhook; 817 lu_byte oldah = L->allowhook;
461 lu_mem oldt = g->GCthreshold; 818 int running = g->gcrunning;
462 L->allowhook = 0; /* stop debug hooks during GC tag method */ 819 L->allowhook = 0; /* stop debug hooks during GC metamethod */
463 g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */ 820 g->gcrunning = 0; /* avoid GC steps */
464 setobj2s(L, L->top, tm); 821 setobj2s(L, L->top, tm); /* push finalizer... */
465 setuvalue(L, L->top+1, udata); 822 setobj2s(L, L->top + 1, &v); /* ... and its argument */
466 L->top += 2; 823 L->top += 2; /* and (next line) call the finalizer */
467 luaD_call(L, L->top - 2, 0); 824 status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
468 L->allowhook = oldah; /* restore hooks */ 825 L->allowhook = oldah; /* restore hooks */
469 g->GCthreshold = oldt; /* restore threshold */ 826 g->gcrunning = running; /* restore state */
827 if (status != LUA_OK && propagateerrors) { /* error while running __gc? */
828 if (status == LUA_ERRRUN) { /* is there an error object? */
829 const char *msg = (ttisstring(L->top - 1))
830 ? svalue(L->top - 1)
831 : "no message";
832 luaO_pushfstring(L, "error in __gc metamethod (%s)", msg);
833 status = LUA_ERRGCMM; /* error in __gc metamethod */
834 }
835 luaD_throw(L, status); /* re-throw error */
836 }
470 } 837 }
471} 838}
472 839
473 840
474/* 841/*
475** Call all GC tag methods 842** move all unreachable objects (or 'all' objects) that need
843** finalization from list 'finobj' to list 'tobefnz' (to be finalized)
476*/ 844*/
477void luaC_callGCTM (lua_State *L) { 845static void separatetobefnz (lua_State *L, int all) {
478 while (G(L)->tmudata) 846 global_State *g = G(L);
479 GCTM(L); 847 GCObject **p = &g->finobj;
848 GCObject *curr;
849 GCObject **lastnext = &g->tobefnz;
850 /* find last 'next' field in 'tobefnz' list (to add elements in its end) */
851 while (*lastnext != NULL)
852 lastnext = &gch(*lastnext)->next;
853 while ((curr = *p) != NULL) { /* traverse all finalizable objects */
854 lua_assert(!isfinalized(curr));
855 lua_assert(testbit(gch(curr)->marked, SEPARATED));
856 if (!(iswhite(curr) || all)) /* not being collected? */
857 p = &gch(curr)->next; /* don't bother with it */
858 else {
859 l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */
860 *p = gch(curr)->next; /* remove 'curr' from 'finobj' list */
861 gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */
862 *lastnext = curr;
863 lastnext = &gch(curr)->next;
864 }
865 }
480} 866}
481 867
482 868
483void luaC_freeall (lua_State *L) { 869/*
870** if object 'o' has a finalizer, remove it from 'allgc' list (must
871** search the list to find it) and link it in 'finobj' list.
872*/
873void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
484 global_State *g = G(L); 874 global_State *g = G(L);
485 int i; 875 if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */
486 g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */ 876 isfinalized(o) || /* ... or is finalized... */
487 sweepwholelist(L, &g->rootgc); 877 gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */
488 for (i = 0; i < g->strt.size; i++) /* free all string lists */ 878 return; /* nothing to be done */
489 sweepwholelist(L, &g->strt.hash[i]); 879 else { /* move 'o' to 'finobj' list */
880 GCObject **p;
881 GCheader *ho = gch(o);
882 if (g->sweepgc == &ho->next) { /* avoid removing current sweep object */
883 lua_assert(issweepphase(g));
884 g->sweepgc = sweeptolive(L, g->sweepgc, NULL);
885 }
886 /* search for pointer pointing to 'o' */
887 for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ }
888 *p = ho->next; /* remove 'o' from root list */
889 ho->next = g->finobj; /* link it in list 'finobj' */
890 g->finobj = o;
891 l_setbit(ho->marked, SEPARATED); /* mark it as such */
892 if (!keepinvariantout(g)) /* not keeping invariant? */
893 makewhite(g, o); /* "sweep" object */
894 else
895 resetoldbit(o); /* see MOVE OLD rule */
896 }
490} 897}
491 898
899/* }====================================================== */
492 900
493static void markmt (global_State *g) { 901
494 int i; 902/*
495 for (i=0; i<NUM_TAGS; i++) 903** {======================================================
496 if (g->mt[i]) markobject(g, g->mt[i]); 904** GC control
905** =======================================================
906*/
907
908
909/*
910** set a reasonable "time" to wait before starting a new GC cycle;
911** cycle will start when memory use hits threshold
912*/
913static void setpause (global_State *g, l_mem estimate) {
914 l_mem debt, threshold;
915 estimate = estimate / PAUSEADJ; /* adjust 'estimate' */
916 threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */
917 ? estimate * g->gcpause /* no overflow */
918 : MAX_LMEM; /* overflow; truncate to maximum */
919 debt = -cast(l_mem, threshold - gettotalbytes(g));
920 luaE_setdebt(g, debt);
497} 921}
498 922
499 923
500/* mark root set */ 924#define sweepphases \
501static void markroot (lua_State *L) { 925 (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep))
926
927
928/*
929** enter first sweep phase (strings) and prepare pointers for other
930** sweep phases. The calls to 'sweeptolive' make pointers point to an
931** object inside the list (instead of to the header), so that the real
932** sweep do not need to skip objects created between "now" and the start
933** of the real sweep.
934** Returns how many objects it swept.
935*/
936static int entersweep (lua_State *L) {
502 global_State *g = G(L); 937 global_State *g = G(L);
503 g->gray = NULL; 938 int n = 0;
504 g->grayagain = NULL; 939 g->gcstate = GCSsweepstring;
505 g->weak = NULL; 940 lua_assert(g->sweepgc == NULL && g->sweepfin == NULL);
506 markobject(g, g->mainthread); 941 /* prepare to sweep strings, finalizable objects, and regular objects */
507 /* make global table be traversed before main stack */ 942 g->sweepstrgc = 0;
508 markvalue(g, gt(g->mainthread)); 943 g->sweepfin = sweeptolive(L, &g->finobj, &n);
509 markvalue(g, registry(L)); 944 g->sweepgc = sweeptolive(L, &g->allgc, &n);
510 markmt(g); 945 return n;
511 g->gcstate = GCSpropagate;
512} 946}
513 947
514 948
515static void remarkupvals (global_State *g) { 949/*
516 UpVal *uv; 950** change GC mode
517 for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { 951*/
518 lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); 952void luaC_changemode (lua_State *L, int mode) {
519 if (isgray(obj2gco(uv))) 953 global_State *g = G(L);
520 markvalue(g, uv->v); 954 if (mode == g->gckind) return; /* nothing to change */
955 if (mode == KGC_GEN) { /* change to generational mode */
956 /* make sure gray lists are consistent */
957 luaC_runtilstate(L, bitmask(GCSpropagate));
958 g->GCestimate = gettotalbytes(g);
959 g->gckind = KGC_GEN;
960 }
961 else { /* change to incremental mode */
962 /* sweep all objects to turn them back to white
963 (as white has not changed, nothing extra will be collected) */
964 g->gckind = KGC_NORMAL;
965 entersweep(L);
966 luaC_runtilstate(L, ~sweepphases);
521 } 967 }
522} 968}
523 969
524 970
525static void atomic (lua_State *L) { 971/*
972** call all pending finalizers
973*/
974static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
526 global_State *g = G(L); 975 global_State *g = G(L);
527 size_t udsize; /* total size of userdata to be finalized */ 976 while (g->tobefnz) {
528 /* remark occasional upvalues of (maybe) dead threads */ 977 resetoldbit(g->tobefnz);
529 remarkupvals(g); 978 GCTM(L, propagateerrors);
530 /* traverse objects cautch by write barrier and by 'remarkupvals' */ 979 }
531 propagateall(g); 980}
532 /* remark weak tables */ 981
533 g->gray = g->weak; 982
534 g->weak = NULL; 983void luaC_freeallobjects (lua_State *L) {
984 global_State *g = G(L);
985 int i;
986 separatetobefnz(L, 1); /* separate all objects with finalizers */
987 lua_assert(g->finobj == NULL);
988 callallpendingfinalizers(L, 0);
989 g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
990 g->gckind = KGC_NORMAL;
991 sweepwholelist(L, &g->finobj); /* finalizers can create objs. in 'finobj' */
992 sweepwholelist(L, &g->allgc);
993 for (i = 0; i < g->strt.size; i++) /* free all string lists */
994 sweepwholelist(L, &g->strt.hash[i]);
995 lua_assert(g->strt.nuse == 0);
996}
997
998
999static l_mem atomic (lua_State *L) {
1000 global_State *g = G(L);
1001 l_mem work = -cast(l_mem, g->GCmemtrav); /* start counting work */
1002 GCObject *origweak, *origall;
535 lua_assert(!iswhite(obj2gco(g->mainthread))); 1003 lua_assert(!iswhite(obj2gco(g->mainthread)));
536 markobject(g, L); /* mark running thread */ 1004 markobject(g, L); /* mark running thread */
537 markmt(g); /* mark basic metatables (again) */ 1005 /* registry and global metatables may be changed by API */
538 propagateall(g); 1006 markvalue(g, &g->l_registry);
539 /* remark gray again */ 1007 markmt(g); /* mark basic metatables */
540 g->gray = g->grayagain; 1008 /* remark occasional upvalues of (maybe) dead threads */
541 g->grayagain = NULL; 1009 remarkupvals(g);
542 propagateall(g); 1010 propagateall(g); /* propagate changes */
543 udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */ 1011 work += g->GCmemtrav; /* stop counting (do not (re)count grays) */
544 marktmu(g); /* mark `preserved' userdata */ 1012 /* traverse objects caught by write barrier and by 'remarkupvals' */
545 udsize += propagateall(g); /* remark, to propagate `preserveness' */ 1013 retraversegrays(g);
546 cleartable(g->weak); /* remove collected objects from weak tables */ 1014 work -= g->GCmemtrav; /* restart counting */
547 /* flip current white */ 1015 convergeephemerons(g);
548 g->currentwhite = cast_byte(otherwhite(g)); 1016 /* at this point, all strongly accessible objects are marked. */
549 g->sweepstrgc = 0; 1017 /* clear values from weak tables, before checking finalizers */
550 g->sweepgc = &g->rootgc; 1018 clearvalues(g, g->weak, NULL);
551 g->gcstate = GCSsweepstring; 1019 clearvalues(g, g->allweak, NULL);
552 g->estimate = g->totalbytes - udsize; /* first estimate */ 1020 origweak = g->weak; origall = g->allweak;
1021 work += g->GCmemtrav; /* stop counting (objects being finalized) */
1022 separatetobefnz(L, 0); /* separate objects to be finalized */
1023 markbeingfnz(g); /* mark objects that will be finalized */
1024 propagateall(g); /* remark, to propagate `preserveness' */
1025 work -= g->GCmemtrav; /* restart counting */
1026 convergeephemerons(g);
1027 /* at this point, all resurrected objects are marked. */
1028 /* remove dead objects from weak tables */
1029 clearkeys(g, g->ephemeron, NULL); /* clear keys from all ephemeron tables */
1030 clearkeys(g, g->allweak, NULL); /* clear keys from all allweak tables */
1031 /* clear values from resurrected weak tables */
1032 clearvalues(g, g->weak, origweak);
1033 clearvalues(g, g->allweak, origall);
1034 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
1035 work += g->GCmemtrav; /* complete counting */
1036 return work; /* estimate of memory marked by 'atomic' */
553} 1037}
554 1038
555 1039
556static l_mem singlestep (lua_State *L) { 1040static lu_mem singlestep (lua_State *L) {
557 global_State *g = G(L); 1041 global_State *g = G(L);
558 /*lua_checkmemory(L);*/
559 switch (g->gcstate) { 1042 switch (g->gcstate) {
560 case GCSpause: { 1043 case GCSpause: {
561 markroot(L); /* start a new collection */ 1044 /* start to count memory traversed */
562 return 0; 1045 g->GCmemtrav = g->strt.size * sizeof(GCObject*);
1046 lua_assert(!isgenerational(g));
1047 restartcollection(g);
1048 g->gcstate = GCSpropagate;
1049 return g->GCmemtrav;
563 } 1050 }
564 case GCSpropagate: { 1051 case GCSpropagate: {
565 if (g->gray) 1052 if (g->gray) {
566 return propagatemark(g); 1053 lu_mem oldtrav = g->GCmemtrav;
1054 propagatemark(g);
1055 return g->GCmemtrav - oldtrav; /* memory traversed in this step */
1056 }
567 else { /* no more `gray' objects */ 1057 else { /* no more `gray' objects */
568 atomic(L); /* finish mark phase */ 1058 lu_mem work;
569 return 0; 1059 int sw;
1060 g->gcstate = GCSatomic; /* finish mark phase */
1061 g->GCestimate = g->GCmemtrav; /* save what was counted */;
1062 work = atomic(L); /* add what was traversed by 'atomic' */
1063 g->GCestimate += work; /* estimate of total memory traversed */
1064 sw = entersweep(L);
1065 return work + sw * GCSWEEPCOST;
570 } 1066 }
571 } 1067 }
572 case GCSsweepstring: { 1068 case GCSsweepstring: {
573 lu_mem old = g->totalbytes; 1069 int i;
574 sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); 1070 for (i = 0; i < GCSWEEPMAX && g->sweepstrgc + i < g->strt.size; i++)
575 if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ 1071 sweepwholelist(L, &g->strt.hash[g->sweepstrgc + i]);
576 g->gcstate = GCSsweep; /* end sweep-string phase */ 1072 g->sweepstrgc += i;
577 lua_assert(old >= g->totalbytes); 1073 if (g->sweepstrgc >= g->strt.size) /* no more strings to sweep? */
578 g->estimate -= old - g->totalbytes; 1074 g->gcstate = GCSsweepudata;
579 return GCSWEEPCOST; 1075 return i * GCSWEEPCOST;
580 } 1076 }
581 case GCSsweep: { 1077 case GCSsweepudata: {
582 lu_mem old = g->totalbytes; 1078 if (g->sweepfin) {
583 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); 1079 g->sweepfin = sweeplist(L, g->sweepfin, GCSWEEPMAX);
584 if (*g->sweepgc == NULL) { /* nothing more to sweep? */ 1080 return GCSWEEPMAX*GCSWEEPCOST;
585 checkSizes(L);
586 g->gcstate = GCSfinalize; /* end sweep phase */
587 }
588 lua_assert(old >= g->totalbytes);
589 g->estimate -= old - g->totalbytes;
590 return GCSWEEPMAX*GCSWEEPCOST;
591 }
592 case GCSfinalize: {
593 if (g->tmudata) {
594 GCTM(L);
595 if (g->estimate > GCFINALIZECOST)
596 g->estimate -= GCFINALIZECOST;
597 return GCFINALIZECOST;
598 } 1081 }
599 else { 1082 else {
600 g->gcstate = GCSpause; /* end collection */ 1083 g->gcstate = GCSsweep;
601 g->gcdept = 0;
602 return 0; 1084 return 0;
603 } 1085 }
604 } 1086 }
1087 case GCSsweep: {
1088 if (g->sweepgc) {
1089 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
1090 return GCSWEEPMAX*GCSWEEPCOST;
1091 }
1092 else {
1093 /* sweep main thread */
1094 GCObject *mt = obj2gco(g->mainthread);
1095 sweeplist(L, &mt, 1);
1096 checkSizes(L);
1097 g->gcstate = GCSpause; /* finish collection */
1098 return GCSWEEPCOST;
1099 }
1100 }
605 default: lua_assert(0); return 0; 1101 default: lua_assert(0); return 0;
606 } 1102 }
607} 1103}
608 1104
609 1105
610void luaC_step (lua_State *L) { 1106/*
1107** advances the garbage collector until it reaches a state allowed
1108** by 'statemask'
1109*/
1110void luaC_runtilstate (lua_State *L, int statesmask) {
611 global_State *g = G(L); 1111 global_State *g = G(L);
612 l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; 1112 while (!testbit(statesmask, g->gcstate))
613 if (lim == 0) 1113 singlestep(L);
614 lim = (MAX_LUMEM-1)/2; /* no limit */
615 g->gcdept += g->totalbytes - g->GCthreshold;
616 do {
617 lim -= singlestep(L);
618 if (g->gcstate == GCSpause)
619 break;
620 } while (lim > 0);
621 if (g->gcstate != GCSpause) {
622 if (g->gcdept < GCSTEPSIZE)
623 g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/
624 else {
625 g->gcdept -= GCSTEPSIZE;
626 g->GCthreshold = g->totalbytes;
627 }
628 }
629 else {
630 lua_assert(g->totalbytes >= g->estimate);
631 setthreshold(g);
632 }
633} 1114}
634 1115
635 1116
636void luaC_fullgc (lua_State *L) { 1117static void generationalcollection (lua_State *L) {
637 global_State *g = G(L); 1118 global_State *g = G(L);
638 if (g->gcstate <= GCSpropagate) { 1119 lua_assert(g->gcstate == GCSpropagate);
639 /* reset sweep marks to sweep all elements (returning them to white) */ 1120 if (g->GCestimate == 0) { /* signal for another major collection? */
640 g->sweepstrgc = 0; 1121 luaC_fullgc(L, 0); /* perform a full regular collection */
641 g->sweepgc = &g->rootgc; 1122 g->GCestimate = gettotalbytes(g); /* update control */
642 /* reset other collector lists */
643 g->gray = NULL;
644 g->grayagain = NULL;
645 g->weak = NULL;
646 g->gcstate = GCSsweepstring;
647 }
648 lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate);
649 /* finish any pending sweep phase */
650 while (g->gcstate != GCSfinalize) {
651 lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);
652 singlestep(L);
653 } 1123 }
654 markroot(L); 1124 else {
655 while (g->gcstate != GCSpause) { 1125 lu_mem estimate = g->GCestimate;
656 singlestep(L); 1126 luaC_runtilstate(L, bitmask(GCSpause)); /* run complete (minor) cycle */
1127 g->gcstate = GCSpropagate; /* skip restart */
1128 if (gettotalbytes(g) > (estimate / 100) * g->gcmajorinc)
1129 g->GCestimate = 0; /* signal for a major collection */
1130 else
1131 g->GCestimate = estimate; /* keep estimate from last major coll. */
1132
657 } 1133 }
658 setthreshold(g); 1134 setpause(g, gettotalbytes(g));
1135 lua_assert(g->gcstate == GCSpropagate);
659} 1136}
660 1137
661 1138
662void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { 1139static void incstep (lua_State *L) {
663 global_State *g = G(L); 1140 global_State *g = G(L);
664 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); 1141 l_mem debt = g->GCdebt;
665 lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); 1142 int stepmul = g->gcstepmul;
666 lua_assert(ttype(&o->gch) != LUA_TTABLE); 1143 if (stepmul < 40) stepmul = 40; /* avoid ridiculous low values (and 0) */
667 /* must keep invariant? */ 1144 /* convert debt from Kb to 'work units' (avoid zero debt and overflows) */
668 if (g->gcstate == GCSpropagate) 1145 debt = (debt / STEPMULADJ) + 1;
669 reallymarkobject(g, v); /* restore invariant */ 1146 debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM;
670 else /* don't mind */ 1147 do { /* always perform at least one single step */
671 makewhite(g, o); /* mark as white just to avoid other barriers */ 1148 lu_mem work = singlestep(L); /* do some work */
1149 debt -= work;
1150 } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause);
1151 if (g->gcstate == GCSpause)
1152 setpause(g, g->GCestimate); /* pause until next cycle */
1153 else {
1154 debt = (debt / stepmul) * STEPMULADJ; /* convert 'work units' to Kb */
1155 luaE_setdebt(g, debt);
1156 }
672} 1157}
673 1158
674 1159
675void luaC_barrierback (lua_State *L, Table *t) { 1160/*
1161** performs a basic GC step
1162*/
1163void luaC_forcestep (lua_State *L) {
676 global_State *g = G(L); 1164 global_State *g = G(L);
677 GCObject *o = obj2gco(t); 1165 int i;
678 lua_assert(isblack(o) && !isdead(g, o)); 1166 if (isgenerational(g)) generationalcollection(L);
679 lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); 1167 else incstep(L);
680 black2gray(o); /* make table gray (again) */ 1168 /* run a few finalizers (or all of them at the end of a collect cycle) */
681 t->gclist = g->grayagain; 1169 for (i = 0; g->tobefnz && (i < GCFINALIZENUM || g->gcstate == GCSpause); i++)
682 g->grayagain = o; 1170 GCTM(L, 1); /* call one finalizer */
683} 1171}
684 1172
685 1173
686void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { 1174/*
1175** performs a basic GC step only if collector is running
1176*/
1177void luaC_step (lua_State *L) {
687 global_State *g = G(L); 1178 global_State *g = G(L);
688 o->gch.next = g->rootgc; 1179 if (g->gcrunning) luaC_forcestep(L);
689 g->rootgc = o; 1180 else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */
690 o->gch.marked = luaC_white(g);
691 o->gch.tt = tt;
692} 1181}
693 1182
694 1183
695void luaC_linkupval (lua_State *L, UpVal *uv) { 1184
1185/*
1186** performs a full GC cycle; if "isemergency", does not call
1187** finalizers (which could change stack positions)
1188*/
1189void luaC_fullgc (lua_State *L, int isemergency) {
696 global_State *g = G(L); 1190 global_State *g = G(L);
697 GCObject *o = obj2gco(uv); 1191 int origkind = g->gckind;
698 o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */ 1192 lua_assert(origkind != KGC_EMERGENCY);
699 g->rootgc = o; 1193 if (isemergency) /* do not run finalizers during emergency GC */
700 if (isgray(o)) { 1194 g->gckind = KGC_EMERGENCY;
701 if (g->gcstate == GCSpropagate) { 1195 else {
702 gray2black(o); /* closed upvalues need barrier */ 1196 g->gckind = KGC_NORMAL;
703 luaC_barrier(L, uv, uv->v); 1197 callallpendingfinalizers(L, 1);
704 } 1198 }
705 else { /* sweep phase: sweep it (turning it into white) */ 1199 if (keepinvariant(g)) { /* may there be some black objects? */
706 makewhite(g, o); 1200 /* must sweep all objects to turn them back to white
707 lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); 1201 (as white has not changed, nothing will be collected) */
708 } 1202 entersweep(L);
1203 }
1204 /* finish any pending sweep phase to start a new cycle */
1205 luaC_runtilstate(L, bitmask(GCSpause));
1206 luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */
1207 luaC_runtilstate(L, bitmask(GCSpause)); /* run entire collection */
1208 if (origkind == KGC_GEN) { /* generational mode? */
1209 /* generational mode must be kept in propagate phase */
1210 luaC_runtilstate(L, bitmask(GCSpropagate));
709 } 1211 }
1212 g->gckind = origkind;
1213 setpause(g, gettotalbytes(g));
1214 if (!isemergency) /* do not run finalizers during emergency GC */
1215 callallpendingfinalizers(L, 1);
710} 1216}
711 1217
1218/* }====================================================== */
1219
1220
diff --git a/apps/plugins/lua/lgc.h b/apps/plugins/lua/lgc.h
index 5123ccb479..84bb1cdf99 100644
--- a/apps/plugins/lua/lgc.h
+++ b/apps/plugins/lua/lgc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: lgc.h,v 2.58.1.1 2013/04/12 18:48:47 roberto Exp $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -9,65 +9,107 @@
9 9
10 10
11#include "lobject.h" 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
12 34
13 35
14/* 36/*
15** Possible states of the Garbage Collector 37** Possible states of the Garbage Collector
16*/ 38*/
17#define GCSpause 0 39#define GCSpropagate 0
18#define GCSpropagate 1 40#define GCSatomic 1
19#define GCSsweepstring 2 41#define GCSsweepstring 2
20#define GCSsweep 3 42#define GCSsweepudata 3
21#define GCSfinalize 4 43#define GCSsweep 4
44#define GCSpause 5
45
22 46
47#define issweepphase(g) \
48 (GCSsweepstring <= (g)->gcstate && (g)->gcstate <= GCSsweep)
49
50#define isgenerational(g) ((g)->gckind == KGC_GEN)
23 51
24/* 52/*
25** some userful bit tricks 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.
26*/ 59*/
27#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m)))
28#define setbits(x,m) ((x) |= (m))
29#define testbits(x,m) ((x) & (m))
30#define bitmask(b) (1<<(b))
31#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
32#define l_setbit(x,b) setbits(x, bitmask(b))
33#define resetbit(x,b) resetbits(x, bitmask(b))
34#define testbit(x,b) testbits(x, bitmask(b))
35#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2)))
36#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2)))
37#define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2)))
38 60
61#define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic)
39 62
40 63
41/* 64/*
42** Layout for bit use in `marked' field: 65** Outside the collector, the state in generational mode is kept in
43** bit 0 - object is white (type 0) 66** 'propagate', so 'keepinvariant' is always true.
44** bit 1 - object is white (type 1)
45** bit 2 - object is black
46** bit 3 - for userdata: has been finalized
47** bit 3 - for tables: has weak keys
48** bit 4 - for tables: has weak values
49** bit 5 - object is fixed (should not be collected)
50** bit 6 - object is "super" fixed (only the main thread)
51*/ 67*/
68#define keepinvariantout(g) \
69 check_exp(g->gcstate == GCSpropagate || !isgenerational(g), \
70 g->gcstate <= GCSatomic)
71
52 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) */
53 95
54#define WHITE0BIT 0
55#define WHITE1BIT 1
56#define BLACKBIT 2
57#define FINALIZEDBIT 3
58#define KEYWEAKBIT 3
59#define VALUEWEAKBIT 4
60#define FIXEDBIT 5
61#define SFIXEDBIT 6
62#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) 96#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
63 97
64 98
65#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) 99#define iswhite(x) testbits((x)->gch.marked, WHITEBITS)
66#define isblack(x) testbit((x)->gch.marked, BLACKBIT) 100#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
67#define isgray(x) (!isblack(x) && !iswhite(x)) 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)
68 109
69#define otherwhite(g) (g->currentwhite ^ WHITEBITS) 110#define otherwhite(g) (g->currentwhite ^ WHITEBITS)
70#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS) 111#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow)))
112#define isdead(g,v) isdeadm(otherwhite(g), (v)->gch.marked)
71 113
72#define changewhite(x) ((x)->gch.marked ^= WHITEBITS) 114#define changewhite(x) ((x)->gch.marked ^= WHITEBITS)
73#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) 115#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT)
@@ -77,34 +119,39 @@
77#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) 119#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
78 120
79 121
80#define luaC_checkGC(L) { \ 122#define luaC_condGC(L,c) \
81 condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ 123 {if (G(L)->GCdebt > 0) {c;}; condchangemem(L);}
82 if (G(L)->totalbytes >= G(L)->GCthreshold) \ 124#define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);)
83 luaC_step(L); }
84 125
85 126
86#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ 127#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
87 luaC_barrierf(L,obj2gco(p),gcvalue(v)); } 128 luaC_barrier_(L,obj2gco(p),gcvalue(v)); }
88 129
89#define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \ 130#define luaC_barrierback(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
90 luaC_barrierback(L,t); } 131 luaC_barrierback_(L,p); }
91 132
92#define luaC_objbarrier(L,p,o) \ 133#define luaC_objbarrier(L,p,o) \
93 { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ 134 { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
94 luaC_barrierf(L,obj2gco(p),obj2gco(o)); } 135 luaC_barrier_(L,obj2gco(p),obj2gco(o)); }
95 136
96#define luaC_objbarriert(L,t,o) \ 137#define luaC_objbarrierback(L,p,o) \
97 { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); } 138 { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) luaC_barrierback_(L,p); }
98 139
99LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all); 140#define luaC_barrierproto(L,p,c) \
100LUAI_FUNC void luaC_callGCTM (lua_State *L); 141 { if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); }
101LUAI_FUNC void luaC_freeall (lua_State *L);
102LUAI_FUNC void luaC_step (lua_State *L);
103LUAI_FUNC void luaC_fullgc (lua_State *L);
104LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
105LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv);
106LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);
107LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t);
108 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);
109 156
110#endif 157#endif
diff --git a/apps/plugins/lua/liolib.c b/apps/plugins/lua/liolib.c
index 7a43915f20..a282dd1ac0 100644
--- a/apps/plugins/lua/liolib.c
+++ b/apps/plugins/lua/liolib.c
@@ -1,10 +1,21 @@
1/* 1/*
2** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $ 2** $Id: liolib.c,v 2.112.1.1 2013/04/12 18:48:47 roberto Exp $
3** Standard I/O (and system) library 3** Standard I/O (and system) library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
6 6
7 7
8/*
9** This definition must come before the inclusion of 'stdio.h'; it
10** should not affect non-POSIX systems
11*/
12#if !defined(_FILE_OFFSET_BITS)
13#define _LARGEFILE_SOURCE 1
14#define _FILE_OFFSET_BITS 64
15#endif
16
17
18#include <errno.h>
8#include <stdio.h> 19#include <stdio.h>
9#include <stdlib.h> 20#include <stdlib.h>
10#include <string.h> 21#include <string.h>
@@ -19,46 +30,111 @@
19#include "rocklibc.h" 30#include "rocklibc.h"
20 31
21 32
33#if !defined(lua_checkmode)
22 34
23#define IO_INPUT 1 35/*
24#define IO_OUTPUT 2 36** Check whether 'mode' matches '[rwa]%+?b?'.
37** Change this macro to accept other modes for 'fopen' besides
38** the standard ones.
39*/
40#define lua_checkmode(mode) \
41 (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && \
42 (*mode != '+' || ++mode) && /* skip if char is '+' */ \
43 (*mode != 'b' || ++mode) && /* skip if char is 'b' */ \
44 (*mode == '\0'))
25 45
46#endif
26 47
27static const char *const fnames[] = {"input", "output"}; 48/*
49** {======================================================
50** lua_popen spawns a new process connected to the current
51** one through the file streams.
52** =======================================================
53*/
28 54
55#if !defined(lua_popen) /* { */
29 56
30static int pushresult (lua_State *L, int i, const char *filename) { 57#if defined(LUA_USE_POPEN) /* { */
31 int en = errno;
32 if (i) {
33 lua_pushboolean(L, 1);
34 return 1;
35 }
36 else {
37 lua_pushnil(L);
38 if (filename)
39 lua_pushfstring(L, "%s: %s", filename, strerror(en));
40 else
41 lua_pushfstring(L, "%s", strerror(en));
42 lua_pushinteger(L, 0);
43 return 3;
44 }
45}
46 58
59#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m))
60#define lua_pclose(L,file) ((void)L, pclose(file))
47 61
48static void fileerror (lua_State *L, int arg, const char *filename) { 62#elif defined(LUA_WIN) /* }{ */
49 lua_pushfstring(L, "%s: %s", filename, strerror(errno)); 63
50 luaL_argerror(L, arg, lua_tostring(L, -1)); 64#define lua_popen(L,c,m) ((void)L, _popen(c,m))
51} 65#define lua_pclose(L,file) ((void)L, _pclose(file))
66
67
68#else /* }{ */
69
70#define lua_popen(L,c,m) ((void)((void)c, m), \
71 luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0)
72#define lua_pclose(L,file) ((void)((void)L, file), -1)
73
74
75#endif /* } */
76
77#endif /* } */
78
79/* }====================================================== */
80
81
82/*
83** {======================================================
84** lua_fseek: configuration for longer offsets
85** =======================================================
86*/
87
88#if !defined(lua_fseek) && !defined(LUA_ANSI) /* { */
89
90#if defined(LUA_USE_POSIX) /* { */
91
92#define l_fseek(f,o,w) fseeko(f,o,w)
93#define l_ftell(f) ftello(f)
94#define l_seeknum off_t
95
96#elif defined(LUA_WIN) && !defined(_CRTIMP_TYPEINFO) \
97 && defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */
98/* Windows (but not DDK) and Visual C++ 2005 or higher */
99
100#define l_fseek(f,o,w) _fseeki64(f,o,w)
101#define l_ftell(f) _ftelli64(f)
102#define l_seeknum __int64
103
104#endif /* } */
105
106#endif /* } */
107
108
109#if !defined(l_fseek) /* default definitions */
110#define l_fseek(f,o,w) fseek(f,o,w)
111#define l_ftell(f) ftell(f)
112#define l_seeknum long
113#endif
114
115/* }====================================================== */
116
117
118#define IO_PREFIX "_IO_"
119#define IO_INPUT (IO_PREFIX "input")
120#define IO_OUTPUT (IO_PREFIX "output")
121
122
123typedef luaL_Stream LStream;
124
125
126#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE))
127
128#define isclosed(p) ((p)->closef == NULL)
52 129
53 130
54static int io_type (lua_State *L) { 131static int io_type (lua_State *L) {
55 void *ud; 132 LStream *p;
56 luaL_checkany(L, 1); 133 luaL_checkany(L, 1);
57 ud = lua_touserdata(L, 1); 134 p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE);
58 lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); 135 if (p == NULL)
59 if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1))
60 lua_pushnil(L); /* not a file */ 136 lua_pushnil(L); /* not a file */
61 else if (*((int *)ud) < 0) 137 else if (isclosed(p))
62 lua_pushliteral(L, "closed file"); 138 lua_pushliteral(L, "closed file");
63 else 139 else
64 lua_pushliteral(L, "file"); 140 lua_pushliteral(L, "file");
@@ -66,76 +142,97 @@ static int io_type (lua_State *L) {
66} 142}
67 143
68 144
69static int* tofile (lua_State *L) { 145static int f_tostring (lua_State *L) {
70 int *f = (int*) luaL_checkudata(L, 1, LUA_FILEHANDLE); 146 LStream *p = tolstream(L);
71 if (*f < 0) 147 if (isclosed(p))
72 luaL_error(L, "attempt to use a closed file"); 148 lua_pushliteral(L, "file (closed)");
73 return f; 149 else
150 lua_pushfstring(L, "file (%p)", p->f);
151 return 1;
74} 152}
75 153
76 154
155static FILE *tofile (lua_State *L) {
156 LStream *p = tolstream(L);
157 if (isclosed(p))
158 luaL_error(L, "attempt to use a closed file");
159 lua_assert(p->f);
160 return p->f;
161}
162
77 163
78/* 164/*
79** When creating file handles, always creates a `closed' file handle 165** When creating file handles, always creates a `closed' file handle
80** before opening the actual file; so, if there is a memory error, the 166** before opening the actual file; so, if there is a memory error, the
81** file is not left opened. 167** file is not left opened.
82*/ 168*/
83static int* newfile (lua_State *L) { 169static LStream *newprefile (lua_State *L) {
84 int *pf = (int *)lua_newuserdata(L, sizeof(int)); 170 LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream));
85 *pf = -1; /* file handle is currently `closed' */ 171 p->closef = NULL; /* mark file handle as 'closed' */
86 luaL_getmetatable(L, LUA_FILEHANDLE); 172 luaL_setmetatable(L, LUA_FILEHANDLE);
87 lua_setmetatable(L, -2); 173 return p;
88 return pf;
89}
90
91
92/*
93** function to close regular files
94*/
95static int io_fclose (lua_State *L) {
96 int *p = tofile(L);
97 int ok = (rb->close(*p) == 0);
98 *p = -1;
99 return pushresult(L, ok, NULL);
100} 174}
101 175
102 176
103static inline int aux_close (lua_State *L) { 177static int aux_close (lua_State *L) {
104 return io_fclose(L); 178 LStream *p = tolstream(L);
179 lua_CFunction cf = p->closef;
180 p->closef = NULL; /* mark stream as closed */
181 return (*cf)(L); /* close it */
105} 182}
106 183
107 184
108static int io_close (lua_State *L) { 185static int io_close (lua_State *L) {
109 if (lua_isnone(L, 1)) 186 if (lua_isnone(L, 1)) /* no argument? */
110 lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT); 187 lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */
111 tofile(L); /* make sure argument is a file */ 188 tofile(L); /* make sure argument is an open stream */
112 return aux_close(L); 189 return aux_close(L);
113} 190}
114 191
115 192
116static int io_gc (lua_State *L) { 193static int f_gc (lua_State *L) {
117 int f = *(int*) luaL_checkudata(L, 1, LUA_FILEHANDLE); 194 LStream *p = tolstream(L);
118 /* ignore closed files */ 195 if (!isclosed(p) && p->f != NULL)
119 if (f >= 0) 196 aux_close(L); /* ignore closed and incompletely open files */
120 aux_close(L);
121 return 0; 197 return 0;
122} 198}
123 199
124 200
125static int io_tostring (lua_State *L) { 201/*
126 int f = *(int*) luaL_checkudata(L, 1, LUA_FILEHANDLE); 202** function to close regular files
127 if (f < 0) 203*/
128 lua_pushliteral(L, "file (closed)"); 204static int io_fclose (lua_State *L) {
129 else 205 LStream *p = tolstream(L);
130 lua_pushfstring(L, "file (%d)", f); 206 int res = rb->close((int)p->f);
131 return 1; 207 return luaL_fileresult(L, (res == 0), NULL);
208}
209
210
211static LStream *newfile (lua_State *L) {
212 LStream *p = newprefile(L);
213 p->f = NULL;
214 p->closef = &io_fclose;
215 return p;
216}
217
218
219static void opencheck (lua_State *L, const char *fname, const char *mode) {
220 LStream *p = newfile(L);
221 int flags = O_RDONLY;
222 if (strcmp(mode, "w") == 0)
223 flags = O_WRONLY;
224 p->f = (FILE*)rb->open(fname, flags);
225 if (p->f == NULL)
226 luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno));
132} 227}
133 228
134 229
135static int io_open (lua_State *L) { 230static int io_open (lua_State *L) {
136 const char *filename = luaL_checkstring(L, 1); 231 const char *filename = luaL_checkstring(L, 1);
137 const char *mode = luaL_optstring(L, 2, "r"); 232 const char *mode = luaL_optstring(L, 2, "r");
138 int *pf = newfile(L); 233 LStream *p = newfile(L);
234 const char *md = mode; /* to traverse/check mode */
235 luaL_argcheck(L, lua_checkmode(md), 2, "invalid mode");
139 int flags = 0; 236 int flags = 0;
140 if(*(mode+1) == '+') { 237 if(*(mode+1) == '+') {
141 flags = O_RDWR; 238 flags = O_RDWR;
@@ -158,84 +255,117 @@ static int io_open (lua_State *L) {
158 } 255 }
159 if((*mode == 'w' || *mode == 'a') && !rb->file_exists(filename)) 256 if((*mode == 'w' || *mode == 'a') && !rb->file_exists(filename))
160 flags |= O_CREAT; 257 flags |= O_CREAT;
161 *pf = rb->open(filename, flags, 0666); 258 int pf = rb->open(filename, flags, 0666);
162 return (*pf < 0) ? pushresult(L, 0, filename) : 1; 259 p->f = (FILE*)pf;
260 return (pf < 0) ? luaL_fileresult(L, 0, filename) : 1;
163} 261}
164 262
165 263
166static int* getiofile (lua_State *L, int findex) { 264#if 0
167 int *f; 265/*
168 lua_rawgeti(L, LUA_ENVIRONINDEX, findex); 266** function to close 'popen' files
169 f = (int *)lua_touserdata(L, -1); 267*/
170 if (f == NULL || *f < 0) 268static int io_pclose (lua_State *L) {
171 luaL_error(L, "standard %s file is closed", fnames[findex - 1]); 269 LStream *p = tolstream(L);
172 return f; 270 return luaL_execresult(L, lua_pclose(L, p->f));
173} 271}
174 272
175 273
176static int g_iofile (lua_State *L, int f, int flags) { 274static int io_popen (lua_State *L) {
275 const char *filename = luaL_checkstring(L, 1);
276 const char *mode = luaL_optstring(L, 2, "r");
277 LStream *p = newprefile(L);
278 p->f = lua_popen(L, filename, mode);
279 p->closef = &io_pclose;
280 return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
281}
282
283
284static int io_tmpfile (lua_State *L) {
285 LStream *p = newfile(L);
286 p->f = tmpfile();
287 return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1;
288}
289#endif
290
291
292static FILE *getiofile (lua_State *L, const char *findex) {
293 LStream *p;
294 lua_getfield(L, LUA_REGISTRYINDEX, findex);
295 p = (LStream *)lua_touserdata(L, -1);
296 if (isclosed(p))
297 luaL_error(L, "standard %s file is closed", findex + strlen(IO_PREFIX));
298 return p->f;
299}
300
301
302static int g_iofile (lua_State *L, const char *f, const char *mode) {
177 if (!lua_isnoneornil(L, 1)) { 303 if (!lua_isnoneornil(L, 1)) {
178 const char *filename = lua_tostring(L, 1); 304 const char *filename = lua_tostring(L, 1);
179 if (filename) { 305 if (filename)
180 int *pf = newfile(L); 306 opencheck(L, filename, mode);
181 *pf = rb->open(filename, flags);
182 if (*pf < 0)
183 fileerror(L, 1, filename);
184 }
185 else { 307 else {
186 tofile(L); /* check that it's a valid file handle */ 308 tofile(L); /* check that it's a valid file handle */
187 lua_pushvalue(L, 1); 309 lua_pushvalue(L, 1);
188 } 310 }
189 lua_rawseti(L, LUA_ENVIRONINDEX, f); 311 lua_setfield(L, LUA_REGISTRYINDEX, f);
190 } 312 }
191 /* return current value */ 313 /* return current value */
192 lua_rawgeti(L, LUA_ENVIRONINDEX, f); 314 lua_getfield(L, LUA_REGISTRYINDEX, f);
193 return 1; 315 return 1;
194} 316}
195 317
196 318
197static int io_input (lua_State *L) { 319static int io_input (lua_State *L) {
198 return g_iofile(L, IO_INPUT, O_RDONLY); 320 return g_iofile(L, IO_INPUT, "r");
199} 321}
200 322
201 323
202static int io_output (lua_State *L) { 324static int io_output (lua_State *L) {
203 return g_iofile(L, IO_OUTPUT, O_WRONLY); 325 return g_iofile(L, IO_OUTPUT, "w");
204} 326}
205 327
206 328
207static int io_readline (lua_State *L); 329static int io_readline (lua_State *L);
208 330
209 331
210static void aux_lines (lua_State *L, int idx, int toclose) { 332static void aux_lines (lua_State *L, int toclose) {
211 lua_pushvalue(L, idx); 333 int i;
334 int n = lua_gettop(L) - 1; /* number of arguments to read */
335 /* ensure that arguments will fit here and into 'io_readline' stack */
336 luaL_argcheck(L, n <= LUA_MINSTACK - 3, LUA_MINSTACK - 3, "too many options");
337 lua_pushvalue(L, 1); /* file handle */
338 lua_pushinteger(L, n); /* number of arguments to read */
212 lua_pushboolean(L, toclose); /* close/not close file when finished */ 339 lua_pushboolean(L, toclose); /* close/not close file when finished */
213 lua_pushcclosure(L, io_readline, 2); 340 for (i = 1; i <= n; i++) lua_pushvalue(L, i + 1); /* copy arguments */
341 lua_pushcclosure(L, io_readline, 3 + n);
214} 342}
215 343
216 344
217static int f_lines (lua_State *L) { 345static int f_lines (lua_State *L) {
218 tofile(L); /* check that it's a valid file handle */ 346 tofile(L); /* check that it's a valid file handle */
219 aux_lines(L, 1, 0); 347 aux_lines(L, 0);
220 return 1; 348 return 1;
221} 349}
222 350
223 351
224static int io_lines (lua_State *L) { 352static int io_lines (lua_State *L) {
225 if (lua_isnoneornil(L, 1)) { /* no arguments? */ 353 int toclose;
226 /* will iterate over default input */ 354 if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */
227 lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); 355 if (lua_isnil(L, 1)) { /* no file name? */
228 return f_lines(L); 356 lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT); /* get default input */
357 lua_replace(L, 1); /* put it at index 1 */
358 tofile(L); /* check that it's a valid file handle */
359 toclose = 0; /* do not close it after iteration */
229 } 360 }
230 else { 361 else { /* open a new file */
231 const char *filename = luaL_checkstring(L, 1); 362 const char *filename = luaL_checkstring(L, 1);
232 int *pf = newfile(L); 363 opencheck(L, filename, "r");
233 *pf = rb->open(filename, O_RDONLY); 364 lua_replace(L, 1); /* put file at index 1 */
234 if (*pf < 0) 365 toclose = 1; /* close it after iteration */
235 fileerror(L, 1, filename);
236 aux_lines(L, lua_gettop(L), 1);
237 return 1;
238 } 366 }
367 aux_lines(L, toclose);
368 return 1;
239} 369}
240 370
241 371
@@ -245,72 +375,89 @@ static int io_lines (lua_State *L) {
245** ======================================================= 375** =======================================================
246*/ 376*/
247 377
248static int read_number (lua_State *L, int *f) { 378
379static int read_number (lua_State *L, FILE *f) {
249 lua_Number d; 380 lua_Number d;
250 if (PREFIX(fscanf)(*f, LUA_NUMBER_SCAN, &d) == 1) { 381 if (PREFIX(fscanf)(f, LUA_NUMBER_SCAN, &d) == 1) {
251 lua_pushnumber(L, d); 382 lua_pushnumber(L, d);
252 return 1; 383 return 1;
253 } 384 }
254 else return 0; /* read fails */ 385 else {
386 lua_pushnil(L); /* "result" to be removed */
387 return 0; /* read fails */
388 }
255} 389}
256 390
257 391
258static int test_eof (lua_State *L, int *f) { 392static int test_eof (lua_State *L, FILE *f) {
259 ssize_t s = rb->lseek(*f, 0, SEEK_CUR); 393 ssize_t s = rb->lseek((int)f, 0, SEEK_CUR);
260 lua_pushlstring(L, NULL, 0); 394 lua_pushlstring(L, NULL, 0);
261 return s != rb->filesize(*f); 395 return s != rb->filesize((int)f);
262} 396}
263 397
264 398
265/* Rockbox already defines read_line() */ 399/* Rockbox already defines read_line() */
266static int _read_line (lua_State *L, int *f) { 400static int _read_line (lua_State *L, FILE *f, int chop) {
267 luaL_Buffer b; 401 luaL_Buffer b;
268 luaL_buffinit(L, &b); 402 luaL_buffinit(L, &b);
269 for (;;) { 403 for (;;) {
270 size_t l; 404 size_t l;
271 size_t r; 405 size_t r;
272 char *p = luaL_prepbuffer(&b); 406 char *p = luaL_prepbuffer(&b);
273 r = rb->read_line(*f, p, LUAL_BUFFERSIZE); 407 r = rb->read_line((int)f, p, LUAL_BUFFERSIZE);
274 l = strlen(p); 408 l = strlen(p);
275 if (l == 0 || p[l-1] != '\n') 409 if (l == 0 || p[l-1] != '\n')
276 luaL_addsize(&b, l); 410 luaL_addsize(&b, l);
277 else { 411 else {
278 luaL_addsize(&b, l - 1); /* do not include `eol' */ 412 luaL_addsize(&b, l - chop); /* chop 'eol' if needed */
279 luaL_pushresult(&b); /* close buffer */ 413 luaL_pushresult(&b); /* close buffer */
280 return 1; /* read at least an `eol' */ 414 return 1; /* read at least an `eol' */
281 } 415 }
282 if (r < LUAL_BUFFERSIZE) { /* eof? */ 416 if (r < LUAL_BUFFERSIZE) { /* eof? */
283 luaL_pushresult(&b); /* close buffer */ 417 luaL_pushresult(&b); /* close buffer */
284 return (lua_objlen(L, -1) > 0); /* check whether read something */ 418 return (lua_rawlen(L, -1) > 0); /* check whether read something */
285 } 419 }
286 } 420 }
287} 421}
288 422
289 423
290static int read_chars (lua_State *L, int *f, size_t n) { 424#define MAX_SIZE_T (~(size_t)0)
291 size_t rlen; /* how much to read */ 425
292 size_t nr; /* number of chars actually read */ 426static void read_all (lua_State *L, FILE *f) {
427 size_t rlen = LUAL_BUFFERSIZE; /* how much to read in each cycle */
293 luaL_Buffer b; 428 luaL_Buffer b;
294 luaL_buffinit(L, &b); 429 luaL_buffinit(L, &b);
295 rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ 430 for (;;) {
296 do { 431 char *p = luaL_prepbuffsize(&b, rlen);
297 char *p = luaL_prepbuffer(&b); 432 size_t nr = rb->read((int)f, p, rlen);
298 if (rlen > n) rlen = n; /* cannot read more than asked */
299 nr = rb->read(*f, p, rlen);
300 luaL_addsize(&b, nr); 433 luaL_addsize(&b, nr);
301 n -= nr; /* still have to read `n' chars */ 434 if (nr < rlen) break; /* eof? */
302 } while (n > 0 && nr == rlen); /* until end of count or eof */ 435 else if (rlen <= (MAX_SIZE_T / 4)) /* avoid buffers too large */
436 rlen *= 2; /* double buffer size at each iteration */
437 }
438 luaL_pushresult(&b); /* close buffer */
439}
440
441
442static int read_chars (lua_State *L, FILE *f, size_t n) {
443 size_t nr; /* number of chars actually read */
444 char *p;
445 luaL_Buffer b;
446 luaL_buffinit(L, &b);
447 p = luaL_prepbuffsize(&b, n); /* prepare buffer to read whole block */
448 nr = rb->read((int)f, p, n); /* try to read 'n' chars */
449 luaL_addsize(&b, nr);
303 luaL_pushresult(&b); /* close buffer */ 450 luaL_pushresult(&b); /* close buffer */
304 return (n == 0 || lua_objlen(L, -1) > 0); 451 return (nr > 0); /* true iff read something */
305} 452}
306 453
307 454
308static int g_read (lua_State *L, int *f, int first) { 455static int g_read (lua_State *L, FILE *f, int first) {
309 int nargs = lua_gettop(L) - 1; 456 int nargs = lua_gettop(L) - 1;
310 int success; 457 int success;
311 int n; 458 int n;
312 if (nargs == 0) { /* no arguments? */ 459 if (nargs == 0) { /* no arguments? */
313 success = _read_line(L, f); 460 success = _read_line(L, f, 1);
314 n = first+1; /* to return 1 result */ 461 n = first+1; /* to return 1 result */
315 } 462 }
316 else { /* ensure stack space for all results and for auxlib's buffer */ 463 else { /* ensure stack space for all results and for auxlib's buffer */
@@ -329,10 +476,13 @@ static int g_read (lua_State *L, int *f, int first) {
329 success = read_number(L, f); 476 success = read_number(L, f);
330 break; 477 break;
331 case 'l': /* line */ 478 case 'l': /* line */
332 success = _read_line(L, f); 479 success = _read_line(L, f, 1);
480 break;
481 case 'L': /* line with end-of-line */
482 success = _read_line(L, f, 0);
333 break; 483 break;
334 case 'a': /* file */ 484 case 'a': /* file */
335 read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ 485 read_all(L, f); /* read entire file */
336 success = 1; /* always success */ 486 success = 1; /* always success */
337 break; 487 break;
338 default: 488 default:
@@ -360,14 +510,24 @@ static int f_read (lua_State *L) {
360 510
361 511
362static int io_readline (lua_State *L) { 512static int io_readline (lua_State *L) {
363 int *f = (int *) lua_touserdata(L, lua_upvalueindex(1)); 513 LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1));
364 int sucess; 514 int i;
365 if (*f < 0) /* file is already closed? */ 515 int n = (int)lua_tointeger(L, lua_upvalueindex(2));
366 luaL_error(L, "file is already closed"); 516 if (isclosed(p)) /* file is already closed? */
367 sucess = _read_line(L, f); 517 return luaL_error(L, "file is already closed");
368 if (sucess) return 1; 518 lua_settop(L , 1);
369 else { /* EOF */ 519 for (i = 1; i <= n; i++) /* push arguments to 'g_read' */
370 if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ 520 lua_pushvalue(L, lua_upvalueindex(3 + i));
521 n = g_read(L, p->f, 2); /* 'n' is number of results */
522 lua_assert(n > 0); /* should return at least a nil */
523 if (!lua_isnil(L, -n)) /* read at least one value? */
524 return n; /* return them */
525 else { /* first result is nil: EOF or error */
526 if (n > 1) { /* is there error information? */
527 /* 2nd result is error message */
528 return luaL_error(L, "%s", lua_tostring(L, -n + 1));
529 }
530 if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */
371 lua_settop(L, 0); 531 lua_settop(L, 0);
372 lua_pushvalue(L, lua_upvalueindex(1)); 532 lua_pushvalue(L, lua_upvalueindex(1));
373 aux_close(L); /* close it */ 533 aux_close(L); /* close it */
@@ -379,22 +539,23 @@ static int io_readline (lua_State *L) {
379/* }====================================================== */ 539/* }====================================================== */
380 540
381 541
382static int g_write (lua_State *L, int *f, int arg) { 542static int g_write (lua_State *L, FILE *f, int arg) {
383 int nargs = lua_gettop(L) - 1; 543 int nargs = lua_gettop(L) - arg;
384 int status = 1; 544 int status = 1;
385 for (; nargs--; arg++) { 545 for (; nargs--; arg++) {
386 if (lua_type(L, arg) == LUA_TNUMBER) { 546 if (lua_type(L, arg) == LUA_TNUMBER) {
387 /* optimization: could be done exactly as for strings */ 547 /* optimization: could be done exactly as for strings */
388 status = status && 548 status = status &&
389 rb->fdprintf(*f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; 549 rb->fdprintf((int)f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
390 } 550 }
391 else { 551 else {
392 size_t l; 552 size_t l;
393 const char *s = luaL_checklstring(L, arg, &l); 553 const char *s = luaL_checklstring(L, arg, &l);
394 status = status && (rb->write(*f, s, l) == (ssize_t)l); 554 status = status && (rb->write((int)f, s, l) == (ssize_t)l);
395 } 555 }
396 } 556 }
397 return pushresult(L, status, NULL); 557 if (status) return 1; /* file handle already on stack top */
558 else return luaL_fileresult(L, status, NULL);
398} 559}
399 560
400 561
@@ -404,47 +565,86 @@ static int io_write (lua_State *L) {
404 565
405 566
406static int f_write (lua_State *L) { 567static int f_write (lua_State *L) {
407 return g_write(L, tofile(L), 2); 568 FILE *f = tofile(L);
569 lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */
570 return g_write(L, f, 2);
408} 571}
409 572
410 573
411static int f_seek (lua_State *L) { 574static int f_seek (lua_State *L) {
412 static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; 575 static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
413 static const char *const modenames[] = {"set", "cur", "end", NULL}; 576 static const char *const modenames[] = {"set", "cur", "end", NULL};
414 int f = *tofile(L); 577 FILE *f = tofile(L);
415 int op = luaL_checkoption(L, 2, "cur", modenames); 578 int op = luaL_checkoption(L, 2, "cur", modenames);
416 long offset = luaL_optlong(L, 3, 0); 579 lua_Number p3 = luaL_optnumber(L, 3, 0);
417 op = rb->lseek(f, offset, mode[op]); 580 l_seeknum offset = (l_seeknum)p3;
581 luaL_argcheck(L, (lua_Number)offset == p3, 3,
582 "not an integer in proper range");
583 op = rb->lseek((int)f, offset, mode[op]);
418 if (op) 584 if (op)
419 return pushresult(L, 0, NULL); /* error */ 585 return luaL_fileresult(L, 0, NULL); /* error */
420 else { 586 else {
421 lua_pushinteger(L, rb->lseek(f, 0, SEEK_CUR)); 587 lua_pushnumber(L, (lua_Number)rb->lseek((int)f, 0, SEEK_CUR));
422 return 1; 588 return 1;
423 } 589 }
424} 590}
425 591
592#if 0
593static int f_setvbuf (lua_State *L) {
594 static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
595 static const char *const modenames[] = {"no", "full", "line", NULL};
596 FILE *f = tofile(L);
597 int op = luaL_checkoption(L, 2, NULL, modenames);
598 lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
599 int res = setvbuf(f, NULL, mode[op], sz);
600 return luaL_fileresult(L, res == 0, NULL);
601}
602
426 603
604
605static int io_flush (lua_State *L) {
606 return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
607}
608
609
610static int f_flush (lua_State *L) {
611 return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL);
612}
613#endif
614
615
616/*
617** functions for 'io' library
618*/
427static const luaL_Reg iolib[] = { 619static const luaL_Reg iolib[] = {
428 {"close", io_close}, 620 {"close", io_close},
621 /*{"flush", io_flush},*/
429 {"input", io_input}, 622 {"input", io_input},
430 {"lines", io_lines}, 623 {"lines", io_lines},
431 {"open", io_open}, 624 {"open", io_open},
432 {"output", io_output}, 625 {"output", io_output},
626 /*{"popen", io_popen},*/
433 {"read", io_read}, 627 {"read", io_read},
628 /*{"tmpfile", io_tmpfile},*/
434 {"type", io_type}, 629 {"type", io_type},
435 {"write", io_write}, 630 {"write", io_write},
436 {NULL, NULL} 631 {NULL, NULL}
437}; 632};
438 633
439 634
635/*
636** methods for file handles
637*/
440static const luaL_Reg flib[] = { 638static const luaL_Reg flib[] = {
441 {"close", io_close}, 639 {"close", io_close},
640 /*{"flush", f_flush},*/
442 {"lines", f_lines}, 641 {"lines", f_lines},
443 {"read", f_read}, 642 {"read", f_read},
444 {"seek", f_seek}, 643 {"seek", f_seek},
644 /*{"setvbuf", f_setvbuf},*/
445 {"write", f_write}, 645 {"write", f_write},
446 {"__gc", io_gc}, 646 {"__gc", f_gc},
447 {"__tostring", io_tostring}, 647 {"__tostring", f_tostring},
448 {NULL, NULL} 648 {NULL, NULL}
449}; 649};
450 650
@@ -453,16 +653,40 @@ static void createmeta (lua_State *L) {
453 luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ 653 luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
454 lua_pushvalue(L, -1); /* push metatable */ 654 lua_pushvalue(L, -1); /* push metatable */
455 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ 655 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
456 luaL_register(L, NULL, flib); /* file methods */ 656 luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */
657 lua_pop(L, 1); /* pop new metatable */
457} 658}
458 659
459 660
460LUALIB_API int luaopen_io (lua_State *L) { 661/*
662** function to (not) close the standard files stdin, stdout, and stderr
663*/
664#if 0
665static int io_noclose (lua_State *L) {
666 LStream *p = tolstream(L);
667 p->closef = &io_noclose; /* keep file opened */
668 lua_pushnil(L);
669 lua_pushliteral(L, "cannot close standard file");
670 return 2;
671}
672
673
674static void createstdfile (lua_State *L, FILE *f, const char *k,
675 const char *fname) {
676 LStream *p = newprefile(L);
677 p->f = f;
678 p->closef = &io_noclose;
679 if (k != NULL) {
680 lua_pushvalue(L, -1);
681 lua_setfield(L, LUA_REGISTRYINDEX, k); /* add file to registry */
682 }
683 lua_setfield(L, -2, fname); /* add file to module */
684}
685#endif
686
687LUAMOD_API int luaopen_io (lua_State *L) {
688 luaL_newlib(L, iolib); /* new module */
461 createmeta(L); 689 createmeta(L);
462 lua_replace(L, LUA_ENVIRONINDEX);
463 /* open library */
464 luaL_register(L, LUA_IOLIBNAME, iolib);
465 /* create (and set) default files */ 690 /* create (and set) default files */
466 lua_pop(L, 1); /* pop environment for default files */
467 return 1; 691 return 1;
468} 692}
diff --git a/apps/plugins/lua/llex.c b/apps/plugins/lua/llex.c
index 85ac516be3..8d410f620d 100644
--- a/apps/plugins/lua/llex.c
+++ b/apps/plugins/lua/llex.c
@@ -1,12 +1,10 @@
1/* 1/*
2** $Id: llex.c,v 2.20.1.1 2007/12/27 13:02:25 roberto Exp $ 2** $Id: llex.c,v 2.63.1.2 2013/08/30 15:49:41 roberto Exp $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
6 6
7 7
8#include <ctype.h>
9/* #include <locale.h> */
10#include <string.h> 8#include <string.h>
11 9
12#define llex_c 10#define llex_c
@@ -14,6 +12,7 @@
14 12
15#include "lua.h" 13#include "lua.h"
16 14
15#include "lctype.h"
17#include "ldo.h" 16#include "ldo.h"
18#include "llex.h" 17#include "llex.h"
19#include "lobject.h" 18#include "lobject.h"
@@ -29,35 +28,36 @@
29 28
30 29
31 30
32
33#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') 31#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
34 32
35 33
36/* ORDER RESERVED */ 34/* ORDER RESERVED */
37const char *const luaX_tokens [] = { 35static const char *const luaX_tokens [] = {
38 "and", "break", "do", "else", "elseif", 36 "and", "break", "do", "else", "elseif",
39 "end", "false", "for", "function", "if", 37 "end", "false", "for", "function", "goto", "if",
40 "in", "local", "nil", "not", "or", "repeat", 38 "in", "local", "nil", "not", "or", "repeat",
41 "return", "then", "true", "until", "while", 39 "return", "then", "true", "until", "while",
42 "..", "...", "==", ">=", "<=", "~=", 40 "..", "...", "==", ">=", "<=", "~=", "::", "<eof>",
43 "<number>", "<name>", "<string>", "<eof>", 41 "<number>", "<name>", "<string>"
44 NULL
45}; 42};
46 43
47 44
48#define save_and_next(ls) (save(ls, ls->current), next(ls)) 45#define save_and_next(ls) (save(ls, ls->current), next(ls))
49 46
50 47
48static l_noret lexerror (LexState *ls, const char *msg, int token);
49
50
51static void save (LexState *ls, int c) { 51static void save (LexState *ls, int c) {
52 Mbuffer *b = ls->buff; 52 Mbuffer *b = ls->buff;
53 if (b->n + 1 > b->buffsize) { 53 if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) {
54 size_t newsize; 54 size_t newsize;
55 if (b->buffsize >= MAX_SIZET/2) 55 if (luaZ_sizebuffer(b) >= MAX_SIZET/2)
56 luaX_lexerror(ls, "lexical element too long", 0); 56 lexerror(ls, "lexical element too long", 0);
57 newsize = b->buffsize * 2; 57 newsize = luaZ_sizebuffer(b) * 2;
58 luaZ_resizebuffer(ls->L, b, newsize); 58 luaZ_resizebuffer(ls->L, b, newsize);
59 } 59 }
60 b->buffer[b->n++] = cast(char, c); 60 b->buffer[luaZ_bufflen(b)++] = cast(char, c);
61} 61}
62 62
63 63
@@ -66,23 +66,24 @@ void luaX_init (lua_State *L) {
66 for (i=0; i<NUM_RESERVED; i++) { 66 for (i=0; i<NUM_RESERVED; i++) {
67 TString *ts = luaS_new(L, luaX_tokens[i]); 67 TString *ts = luaS_new(L, luaX_tokens[i]);
68 luaS_fix(ts); /* reserved words are never collected */ 68 luaS_fix(ts); /* reserved words are never collected */
69 lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN); 69 ts->tsv.extra = cast_byte(i+1); /* reserved word */
70 ts->tsv.reserved = cast_byte(i+1); /* reserved word */
71 } 70 }
72} 71}
73 72
74 73
75#define MAXSRC 80
76
77
78const char *luaX_token2str (LexState *ls, int token) { 74const char *luaX_token2str (LexState *ls, int token) {
79 if (token < FIRST_RESERVED) { 75 if (token < FIRST_RESERVED) { /* single-byte symbols? */
80 lua_assert(token == cast(unsigned char, token)); 76 lua_assert(token == cast(unsigned char, token));
81 return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) : 77 return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) :
82 luaO_pushfstring(ls->L, "%c", token); 78 luaO_pushfstring(ls->L, "char(%d)", token);
79 }
80 else {
81 const char *s = luaX_tokens[token - FIRST_RESERVED];
82 if (token < TK_EOS) /* fixed format (symbols and reserved words)? */
83 return luaO_pushfstring(ls->L, LUA_QS, s);
84 else /* names, strings, and numerals */
85 return s;
83 } 86 }
84 else
85 return luaX_tokens[token-FIRST_RESERVED];
86} 87}
87 88
88 89
@@ -92,38 +93,57 @@ static const char *txtToken (LexState *ls, int token) {
92 case TK_STRING: 93 case TK_STRING:
93 case TK_NUMBER: 94 case TK_NUMBER:
94 save(ls, '\0'); 95 save(ls, '\0');
95 return luaZ_buffer(ls->buff); 96 return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff));
96 default: 97 default:
97 return luaX_token2str(ls, token); 98 return luaX_token2str(ls, token);
98 } 99 }
99} 100}
100 101
101 102
102void luaX_lexerror (LexState *ls, const char *msg, int token) { 103static l_noret lexerror (LexState *ls, const char *msg, int token) {
103 char buff[MAXSRC]; 104 char buff[LUA_IDSIZE];
104 luaO_chunkid(buff, getstr(ls->source), MAXSRC); 105 luaO_chunkid(buff, getstr(ls->source), LUA_IDSIZE);
105 msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg); 106 msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
106 if (token) 107 if (token)
107 luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token)); 108 luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token));
108 luaD_throw(ls->L, LUA_ERRSYNTAX); 109 luaD_throw(ls->L, LUA_ERRSYNTAX);
109} 110}
110 111
111 112
112void luaX_syntaxerror (LexState *ls, const char *msg) { 113l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
113 luaX_lexerror(ls, msg, ls->t.token); 114 lexerror(ls, msg, ls->t.token);
114} 115}
115 116
116 117
118/*
119** creates a new string and anchors it in function's table so that
120** it will not be collected until the end of the function's compilation
121** (by that time it should be anchored in function's prototype)
122*/
117TString *luaX_newstring (LexState *ls, const char *str, size_t l) { 123TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
118 lua_State *L = ls->L; 124 lua_State *L = ls->L;
119 TString *ts = luaS_newlstr(L, str, l); 125 TValue *o; /* entry for `str' */
120 TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */ 126 TString *ts = luaS_newlstr(L, str, l); /* create new string */
121 if (ttisnil(o)) 127 setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */
122 setbvalue(o, 1); /* make sure `str' will not be collected */ 128 o = luaH_set(L, ls->fs->h, L->top - 1);
129 if (ttisnil(o)) { /* not in use yet? (see 'addK') */
130 /* boolean value does not need GC barrier;
131 table has no metatable, so it does not need to invalidate cache */
132 setbvalue(o, 1); /* t[string] = true */
133 luaC_checkGC(L);
134 }
135 else { /* string already present */
136 ts = rawtsvalue(keyfromval(o)); /* re-use value previously stored */
137 }
138 L->top--; /* remove string from stack */
123 return ts; 139 return ts;
124} 140}
125 141
126 142
143/*
144** increment line number and skips newline sequence (any of
145** \n, \r, \n\r, or \r\n)
146*/
127static void inclinenumber (LexState *ls) { 147static void inclinenumber (LexState *ls) {
128 int old = ls->current; 148 int old = ls->current;
129 lua_assert(currIsNewline(ls)); 149 lua_assert(currIsNewline(ls));
@@ -135,17 +155,20 @@ static void inclinenumber (LexState *ls) {
135} 155}
136 156
137 157
138void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { 158void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
159 int firstchar) {
139 ls->decpoint = '.'; 160 ls->decpoint = '.';
140 ls->L = L; 161 ls->L = L;
162 ls->current = firstchar;
141 ls->lookahead.token = TK_EOS; /* no look-ahead token */ 163 ls->lookahead.token = TK_EOS; /* no look-ahead token */
142 ls->z = z; 164 ls->z = z;
143 ls->fs = NULL; 165 ls->fs = NULL;
144 ls->linenumber = 1; 166 ls->linenumber = 1;
145 ls->lastline = 1; 167 ls->lastline = 1;
146 ls->source = source; 168 ls->source = source;
169 ls->envn = luaS_new(L, LUA_ENV); /* create env name */
170 luaS_fix(ls->envn); /* never collect this name */
147 luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ 171 luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
148 next(ls); /* read first char */
149} 172}
150 173
151 174
@@ -159,13 +182,16 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) {
159 182
160 183
161static int check_next (LexState *ls, const char *set) { 184static int check_next (LexState *ls, const char *set) {
162 if (!strchr(set, ls->current)) 185 if (ls->current == '\0' || !strchr(set, ls->current))
163 return 0; 186 return 0;
164 save_and_next(ls); 187 save_and_next(ls);
165 return 1; 188 return 1;
166} 189}
167 190
168 191
192/*
193** change all characters 'from' in buffer to 'to'
194*/
169static void buffreplace (LexState *ls, char from, char to) { 195static void buffreplace (LexState *ls, char from, char to) {
170 size_t n = luaZ_bufflen(ls->buff); 196 size_t n = luaZ_bufflen(ls->buff);
171 char *p = luaZ_buffer(ls->buff); 197 char *p = luaZ_buffer(ls->buff);
@@ -174,37 +200,59 @@ static void buffreplace (LexState *ls, char from, char to) {
174} 200}
175 201
176 202
203#if !defined(getlocaledecpoint)
204#define getlocaledecpoint() (localeconv()->decimal_point[0])
205#endif
206
207
208#define buff2d(b,e) luaO_str2d(luaZ_buffer(b), luaZ_bufflen(b) - 1, e)
209
210/*
211** in case of format error, try to change decimal point separator to
212** the one defined in the current locale and check again
213*/
177static void trydecpoint (LexState *ls, SemInfo *seminfo) { 214static void trydecpoint (LexState *ls, SemInfo *seminfo) {
178 /* format error: try to update decimal point separator */
179 /* struct lconv *cv = localeconv(); */
180 char old = ls->decpoint; 215 char old = ls->decpoint;
181 ls->decpoint = '.'; /* (cv ? cv->decimal_point[0] : '.'); */ 216 ls->decpoint = getlocaledecpoint();
182 buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */ 217 buffreplace(ls, old, ls->decpoint); /* try new decimal separator */
183 if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { 218 if (!buff2d(ls->buff, &seminfo->r)) {
184 /* format error with correct decimal point: no more options */ 219 /* format error with correct decimal point: no more options */
185 buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ 220 buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
186 luaX_lexerror(ls, "malformed number", TK_NUMBER); 221 lexerror(ls, "malformed number", TK_NUMBER);
187 } 222 }
188} 223}
189 224
190 225
191/* LUA_NUMBER */ 226/* LUA_NUMBER */
227/*
228** this function is quite liberal in what it accepts, as 'luaO_str2d'
229** will reject ill-formed numerals.
230*/
192static void read_numeral (LexState *ls, SemInfo *seminfo) { 231static void read_numeral (LexState *ls, SemInfo *seminfo) {
193 lua_assert(isdigit(ls->current)); 232 const char *expo = "Ee";
194 do { 233 int first = ls->current;
195 save_and_next(ls); 234 lua_assert(lisdigit(ls->current));
196 } while (isdigit(ls->current) || ls->current == '.'); 235 save_and_next(ls);
197 if (check_next(ls, "Ee")) /* `E'? */ 236 if (first == '0' && check_next(ls, "Xx")) /* hexadecimal? */
198 check_next(ls, "+-"); /* optional exponent sign */ 237 expo = "Pp";
199 while (isalnum(ls->current) || ls->current == '_') 238 for (;;) {
200 save_and_next(ls); 239 if (check_next(ls, expo)) /* exponent part? */
240 check_next(ls, "+-"); /* optional exponent sign */
241 if (lisxdigit(ls->current) || ls->current == '.')
242 save_and_next(ls);
243 else break;
244 }
201 save(ls, '\0'); 245 save(ls, '\0');
202 buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ 246 buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
203 if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */ 247 if (!buff2d(ls->buff, &seminfo->r)) /* format error? */
204 trydecpoint(ls, seminfo); /* try to update decimal point separator */ 248 trydecpoint(ls, seminfo); /* try to update decimal point separator */
205} 249}
206 250
207 251
252/*
253** skip a sequence '[=*[' or ']=*]' and return its number of '='s or
254** -1 if sequence is malformed
255*/
208static int skip_sep (LexState *ls) { 256static int skip_sep (LexState *ls) {
209 int count = 0; 257 int count = 0;
210 int s = ls->current; 258 int s = ls->current;
@@ -219,43 +267,23 @@ static int skip_sep (LexState *ls) {
219 267
220 268
221static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { 269static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
222 int cont = 0;
223 (void)(cont); /* avoid warnings when `cont' is not used */
224 save_and_next(ls); /* skip 2nd `[' */ 270 save_and_next(ls); /* skip 2nd `[' */
225 if (currIsNewline(ls)) /* string starts with a newline? */ 271 if (currIsNewline(ls)) /* string starts with a newline? */
226 inclinenumber(ls); /* skip it */ 272 inclinenumber(ls); /* skip it */
227 for (;;) { 273 for (;;) {
228 switch (ls->current) { 274 switch (ls->current) {
229 case EOZ: 275 case EOZ:
230 luaX_lexerror(ls, (seminfo) ? "unfinished long string" : 276 lexerror(ls, (seminfo) ? "unfinished long string" :
231 "unfinished long comment", TK_EOS); 277 "unfinished long comment", TK_EOS);
232 break; /* to avoid warnings */ 278 break; /* to avoid warnings */
233#if defined(LUA_COMPAT_LSTR)
234 case '[': {
235 if (skip_sep(ls) == sep) {
236 save_and_next(ls); /* skip 2nd `[' */
237 cont++;
238#if LUA_COMPAT_LSTR == 1
239 if (sep == 0)
240 luaX_lexerror(ls, "nesting of [[...]] is deprecated", '[');
241#endif
242 }
243 break;
244 }
245#endif
246 case ']': { 279 case ']': {
247 if (skip_sep(ls) == sep) { 280 if (skip_sep(ls) == sep) {
248 save_and_next(ls); /* skip 2nd `]' */ 281 save_and_next(ls); /* skip 2nd `]' */
249#if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2
250 cont--;
251 if (sep == 0 && cont >= 0) break;
252#endif
253 goto endloop; 282 goto endloop;
254 } 283 }
255 break; 284 break;
256 } 285 }
257 case '\n': 286 case '\n': case '\r': {
258 case '\r': {
259 save(ls, '\n'); 287 save(ls, '\n');
260 inclinenumber(ls); 288 inclinenumber(ls);
261 if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ 289 if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */
@@ -273,51 +301,91 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
273} 301}
274 302
275 303
304static void escerror (LexState *ls, int *c, int n, const char *msg) {
305 int i;
306 luaZ_resetbuffer(ls->buff); /* prepare error message */
307 save(ls, '\\');
308 for (i = 0; i < n && c[i] != EOZ; i++)
309 save(ls, c[i]);
310 lexerror(ls, msg, TK_STRING);
311}
312
313
314static int readhexaesc (LexState *ls) {
315 int c[3], i; /* keep input for error message */
316 int r = 0; /* result accumulator */
317 c[0] = 'x'; /* for error message */
318 for (i = 1; i < 3; i++) { /* read two hexadecimal digits */
319 c[i] = next(ls);
320 if (!lisxdigit(c[i]))
321 escerror(ls, c, i + 1, "hexadecimal digit expected");
322 r = (r << 4) + luaO_hexavalue(c[i]);
323 }
324 return r;
325}
326
327
328static int readdecesc (LexState *ls) {
329 int c[3], i;
330 int r = 0; /* result accumulator */
331 for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */
332 c[i] = ls->current;
333 r = 10*r + c[i] - '0';
334 next(ls);
335 }
336 if (r > UCHAR_MAX)
337 escerror(ls, c, i, "decimal escape too large");
338 return r;
339}
340
341
276static void read_string (LexState *ls, int del, SemInfo *seminfo) { 342static void read_string (LexState *ls, int del, SemInfo *seminfo) {
277 save_and_next(ls); 343 save_and_next(ls); /* keep delimiter (for error messages) */
278 while (ls->current != del) { 344 while (ls->current != del) {
279 switch (ls->current) { 345 switch (ls->current) {
280 case EOZ: 346 case EOZ:
281 luaX_lexerror(ls, "unfinished string", TK_EOS); 347 lexerror(ls, "unfinished string", TK_EOS);
282 continue; /* to avoid warnings */ 348 break; /* to avoid warnings */
283 case '\n': 349 case '\n':
284 case '\r': 350 case '\r':
285 luaX_lexerror(ls, "unfinished string", TK_STRING); 351 lexerror(ls, "unfinished string", TK_STRING);
286 continue; /* to avoid warnings */ 352 break; /* to avoid warnings */
287 case '\\': { 353 case '\\': { /* escape sequences */
288 int c; 354 int c; /* final character to be saved */
289 next(ls); /* do not save the `\' */ 355 next(ls); /* do not save the `\' */
290 switch (ls->current) { 356 switch (ls->current) {
291 case 'a': c = '\a'; break; 357 case 'a': c = '\a'; goto read_save;
292 case 'b': c = '\b'; break; 358 case 'b': c = '\b'; goto read_save;
293 case 'f': c = '\f'; break; 359 case 'f': c = '\f'; goto read_save;
294 case 'n': c = '\n'; break; 360 case 'n': c = '\n'; goto read_save;
295 case 'r': c = '\r'; break; 361 case 'r': c = '\r'; goto read_save;
296 case 't': c = '\t'; break; 362 case 't': c = '\t'; goto read_save;
297 case 'v': c = '\v'; break; 363 case 'v': c = '\v'; goto read_save;
298 case '\n': /* go through */ 364 case 'x': c = readhexaesc(ls); goto read_save;
299 case '\r': save(ls, '\n'); inclinenumber(ls); continue; 365 case '\n': case '\r':
300 case EOZ: continue; /* will raise an error next loop */ 366 inclinenumber(ls); c = '\n'; goto only_save;
301 default: { 367 case '\\': case '\"': case '\'':
302 if (!isdigit(ls->current)) 368 c = ls->current; goto read_save;
303 save_and_next(ls); /* handles \\, \", \', and \? */ 369 case EOZ: goto no_save; /* will raise an error next loop */
304 else { /* \xxx */ 370 case 'z': { /* zap following span of spaces */
305 int i = 0; 371 next(ls); /* skip the 'z' */
306 c = 0; 372 while (lisspace(ls->current)) {
307 do { 373 if (currIsNewline(ls)) inclinenumber(ls);
308 c = 10*c + (ls->current-'0'); 374 else next(ls);
309 next(ls);
310 } while (++i<3 && isdigit(ls->current));
311 if (c > UCHAR_MAX)
312 luaX_lexerror(ls, "escape sequence too large", TK_STRING);
313 save(ls, c);
314 } 375 }
315 continue; 376 goto no_save;
377 }
378 default: {
379 if (!lisdigit(ls->current))
380 escerror(ls, &ls->current, 1, "invalid escape sequence");
381 /* digital escape \ddd */
382 c = readdecesc(ls);
383 goto only_save;
316 } 384 }
317 } 385 }
318 save(ls, c); 386 read_save: next(ls); /* read next character */
319 next(ls); 387 only_save: save(ls, c); /* save 'c' */
320 continue; 388 no_save: break;
321 } 389 }
322 default: 390 default:
323 save_and_next(ls); 391 save_and_next(ls);
@@ -333,38 +401,41 @@ static int llex (LexState *ls, SemInfo *seminfo) {
333 luaZ_resetbuffer(ls->buff); 401 luaZ_resetbuffer(ls->buff);
334 for (;;) { 402 for (;;) {
335 switch (ls->current) { 403 switch (ls->current) {
336 case '\n': 404 case '\n': case '\r': { /* line breaks */
337 case '\r': {
338 inclinenumber(ls); 405 inclinenumber(ls);
339 continue; 406 break;
340 } 407 }
341 case '-': { 408 case ' ': case '\f': case '\t': case '\v': { /* spaces */
409 next(ls);
410 break;
411 }
412 case '-': { /* '-' or '--' (comment) */
342 next(ls); 413 next(ls);
343 if (ls->current != '-') return '-'; 414 if (ls->current != '-') return '-';
344 /* else is a comment */ 415 /* else is a comment */
345 next(ls); 416 next(ls);
346 if (ls->current == '[') { 417 if (ls->current == '[') { /* long comment? */
347 int sep = skip_sep(ls); 418 int sep = skip_sep(ls);
348 luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ 419 luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */
349 if (sep >= 0) { 420 if (sep >= 0) {
350 read_long_string(ls, NULL, sep); /* long comment */ 421 read_long_string(ls, NULL, sep); /* skip long comment */
351 luaZ_resetbuffer(ls->buff); 422 luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */
352 continue; 423 break;
353 } 424 }
354 } 425 }
355 /* else short comment */ 426 /* else short comment */
356 while (!currIsNewline(ls) && ls->current != EOZ) 427 while (!currIsNewline(ls) && ls->current != EOZ)
357 next(ls); 428 next(ls); /* skip until end of line (or end of file) */
358 continue; 429 break;
359 } 430 }
360 case '[': { 431 case '[': { /* long string or simply '[' */
361 int sep = skip_sep(ls); 432 int sep = skip_sep(ls);
362 if (sep >= 0) { 433 if (sep >= 0) {
363 read_long_string(ls, seminfo, sep); 434 read_long_string(ls, seminfo, sep);
364 return TK_STRING; 435 return TK_STRING;
365 } 436 }
366 else if (sep == -1) return '['; 437 else if (sep == -1) return '[';
367 else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING); 438 else lexerror(ls, "invalid long string delimiter", TK_STRING);
368 } 439 }
369 case '=': { 440 case '=': {
370 next(ls); 441 next(ls);
@@ -386,56 +457,52 @@ static int llex (LexState *ls, SemInfo *seminfo) {
386 if (ls->current != '=') return '~'; 457 if (ls->current != '=') return '~';
387 else { next(ls); return TK_NE; } 458 else { next(ls); return TK_NE; }
388 } 459 }
389 case '"': 460 case ':': {
390 case '\'': { 461 next(ls);
462 if (ls->current != ':') return ':';
463 else { next(ls); return TK_DBCOLON; }
464 }
465 case '"': case '\'': { /* short literal strings */
391 read_string(ls, ls->current, seminfo); 466 read_string(ls, ls->current, seminfo);
392 return TK_STRING; 467 return TK_STRING;
393 } 468 }
394 case '.': { 469 case '.': { /* '.', '..', '...', or number */
395 save_and_next(ls); 470 save_and_next(ls);
396 if (check_next(ls, ".")) { 471 if (check_next(ls, ".")) {
397 if (check_next(ls, ".")) 472 if (check_next(ls, "."))
398 return TK_DOTS; /* ... */ 473 return TK_DOTS; /* '...' */
399 else return TK_CONCAT; /* .. */ 474 else return TK_CONCAT; /* '..' */
400 }
401 else if (!isdigit(ls->current)) return '.';
402 else {
403 read_numeral(ls, seminfo);
404 return TK_NUMBER;
405 } 475 }
476 else if (!lisdigit(ls->current)) return '.';
477 /* else go through */
478 }
479 case '0': case '1': case '2': case '3': case '4':
480 case '5': case '6': case '7': case '8': case '9': {
481 read_numeral(ls, seminfo);
482 return TK_NUMBER;
406 } 483 }
407 case EOZ: { 484 case EOZ: {
408 return TK_EOS; 485 return TK_EOS;
409 } 486 }
410 default: { 487 default: {
411 if (isspace(ls->current)) { 488 if (lislalpha(ls->current)) { /* identifier or reserved word? */
412 lua_assert(!currIsNewline(ls));
413 next(ls);
414 continue;
415 }
416 else if (isdigit(ls->current)) {
417 read_numeral(ls, seminfo);
418 return TK_NUMBER;
419 }
420 else if (isalpha(ls->current) || ls->current == '_') {
421 /* identifier or reserved word */
422 TString *ts; 489 TString *ts;
423 do { 490 do {
424 save_and_next(ls); 491 save_and_next(ls);
425 } while (isalnum(ls->current) || ls->current == '_'); 492 } while (lislalnum(ls->current));
426 ts = luaX_newstring(ls, luaZ_buffer(ls->buff), 493 ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
427 luaZ_bufflen(ls->buff)); 494 luaZ_bufflen(ls->buff));
428 if (ts->tsv.reserved > 0) /* reserved word? */ 495 seminfo->ts = ts;
429 return ts->tsv.reserved - 1 + FIRST_RESERVED; 496 if (isreserved(ts)) /* reserved word? */
497 return ts->tsv.extra - 1 + FIRST_RESERVED;
430 else { 498 else {
431 seminfo->ts = ts;
432 return TK_NAME; 499 return TK_NAME;
433 } 500 }
434 } 501 }
435 else { 502 else { /* single-char tokens (+ - / ...) */
436 int c = ls->current; 503 int c = ls->current;
437 next(ls); 504 next(ls);
438 return c; /* single-char tokens (+ - / ...) */ 505 return c;
439 } 506 }
440 } 507 }
441 } 508 }
@@ -454,8 +521,9 @@ void luaX_next (LexState *ls) {
454} 521}
455 522
456 523
457void luaX_lookahead (LexState *ls) { 524int luaX_lookahead (LexState *ls) {
458 lua_assert(ls->lookahead.token == TK_EOS); 525 lua_assert(ls->lookahead.token == TK_EOS);
459 ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); 526 ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
527 return ls->lookahead.token;
460} 528}
461 529
diff --git a/apps/plugins/lua/llex.h b/apps/plugins/lua/llex.h
index fa8b7a2a28..a4acdd3021 100644
--- a/apps/plugins/lua/llex.h
+++ b/apps/plugins/lua/llex.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: llex.h,v 1.72.1.1 2013/04/12 18:48:47 roberto Exp $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -13,8 +13,6 @@
13 13
14#define FIRST_RESERVED 257 14#define FIRST_RESERVED 257
15 15
16/* maximum length of a reserved word */
17#define TOKEN_LEN (sizeof("function")/sizeof(char))
18 16
19 17
20/* 18/*
@@ -25,21 +23,17 @@ enum RESERVED {
25 /* terminal symbols denoted by reserved words */ 23 /* terminal symbols denoted by reserved words */
26 TK_AND = FIRST_RESERVED, TK_BREAK, 24 TK_AND = FIRST_RESERVED, TK_BREAK,
27 TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, 25 TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
28 TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, 26 TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
29 TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, 27 TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
30 /* other terminal symbols */ 28 /* other terminal symbols */
31 TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, 29 TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_DBCOLON, TK_EOS,
32 TK_NAME, TK_STRING, TK_EOS 30 TK_NUMBER, TK_NAME, TK_STRING
33}; 31};
34 32
35/* number of reserved words */ 33/* number of reserved words */
36#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) 34#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
37 35
38 36
39/* array with token `names' */
40LUAI_DATA const char *const luaX_tokens [];
41
42
43typedef union { 37typedef union {
44 lua_Number r; 38 lua_Number r;
45 TString *ts; 39 TString *ts;
@@ -52,29 +46,32 @@ typedef struct Token {
52} Token; 46} Token;
53 47
54 48
49/* state of the lexer plus state of the parser when shared by all
50 functions */
55typedef struct LexState { 51typedef struct LexState {
56 int current; /* current character (charint) */ 52 int current; /* current character (charint) */
57 int linenumber; /* input line counter */ 53 int linenumber; /* input line counter */
58 int lastline; /* line of last token `consumed' */ 54 int lastline; /* line of last token `consumed' */
59 Token t; /* current token */ 55 Token t; /* current token */
60 Token lookahead; /* look ahead token */ 56 Token lookahead; /* look ahead token */
61 struct FuncState *fs; /* `FuncState' is private to the parser */ 57 struct FuncState *fs; /* current function (parser) */
62 struct lua_State *L; 58 struct lua_State *L;
63 ZIO *z; /* input stream */ 59 ZIO *z; /* input stream */
64 Mbuffer *buff; /* buffer for tokens */ 60 Mbuffer *buff; /* buffer for tokens */
61 struct Dyndata *dyd; /* dynamic structures used by the parser */
65 TString *source; /* current source name */ 62 TString *source; /* current source name */
63 TString *envn; /* environment variable name */
66 char decpoint; /* locale decimal point */ 64 char decpoint; /* locale decimal point */
67} LexState; 65} LexState;
68 66
69 67
70LUAI_FUNC void luaX_init (lua_State *L); 68LUAI_FUNC void luaX_init (lua_State *L);
71LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, 69LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
72 TString *source); 70 TString *source, int firstchar);
73LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); 71LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
74LUAI_FUNC void luaX_next (LexState *ls); 72LUAI_FUNC void luaX_next (LexState *ls);
75LUAI_FUNC void luaX_lookahead (LexState *ls); 73LUAI_FUNC int luaX_lookahead (LexState *ls);
76LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token); 74LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s);
77LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s);
78LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); 75LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);
79 76
80 77
diff --git a/apps/plugins/lua/llimits.h b/apps/plugins/lua/llimits.h
index a31ad160ad..152dd05515 100644
--- a/apps/plugins/lua/llimits.h
+++ b/apps/plugins/lua/llimits.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: llimits.h,v 1.103.1.1 2013/04/12 18:48:47 roberto Exp $
3** Limits, basic types, and some other `installation-dependent' definitions 3** Limits, basic types, and some other `installation-dependent' definitions
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -15,7 +15,7 @@
15#include "lua.h" 15#include "lua.h"
16 16
17 17
18typedef LUAI_UINT32 lu_int32; 18typedef unsigned LUA_INT32 lu_int32;
19 19
20typedef LUAI_UMEM lu_mem; 20typedef LUAI_UMEM lu_mem;
21 21
@@ -31,6 +31,8 @@ typedef unsigned char lu_byte;
31 31
32#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) 32#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2)
33 33
34#define MAX_LMEM ((l_mem) ((MAX_LUMEM >> 1) - 2))
35
34 36
35#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ 37#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
36 38
@@ -44,6 +46,10 @@ typedef unsigned char lu_byte;
44 46
45 47
46/* type to ensure maximum alignment */ 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
47typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; 53typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
48 54
49 55
@@ -52,36 +58,75 @@ typedef LUAI_UACNUMBER l_uacNumber;
52 58
53 59
54/* internal assertions for in-house debugging */ 60/* internal assertions for in-house debugging */
55#ifdef lua_assert 61#if defined(lua_assert)
56
57#define check_exp(c,e) (lua_assert(c), (e)) 62#define check_exp(c,e) (lua_assert(c), (e))
58#define api_check(l,e) lua_assert(e) 63/* to avoid problems with conditions too long */
59 64#define lua_longassert(c) { if (!(c)) lua_assert(0); }
60#else 65#else
61
62#define lua_assert(c) ((void)0) 66#define lua_assert(c) ((void)0)
63#define check_exp(c,e) (e) 67#define check_exp(c,e) (e)
64#define api_check luai_apicheck 68#define lua_longassert(c) ((void)0)
69#endif
65 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)
66#endif 81#endif
67 82
83#endif
84
85#define api_check(l,e,msg) luai_apicheck(l,(e) && msg)
86
68 87
69#ifndef UNUSED 88#if !defined(UNUSED)
70#define UNUSED(x) ((void)(x)) /* to avoid warnings */ 89#define UNUSED(x) ((void)(x)) /* to avoid warnings */
71#endif 90#endif
72 91
73 92
74#ifndef cast
75#define cast(t, exp) ((t)(exp)) 93#define cast(t, exp) ((t)(exp))
76#endif
77 94
78#define cast_byte(i) cast(lu_byte, (i)) 95#define cast_byte(i) cast(lu_byte, (i))
79#define cast_num(i) cast(lua_Number, (i)) 96#define cast_num(i) cast(lua_Number, (i))
80#define cast_int(i) cast(int, (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
81 111
82 112
83 113
84/* 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/*
85** type for virtual-machine instructions 130** type for virtual-machine instructions
86** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) 131** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
87*/ 132*/
@@ -95,34 +140,170 @@ typedef lu_int32 Instruction;
95 140
96 141
97/* minimum size for the string table (must be power of 2) */ 142/* minimum size for the string table (must be power of 2) */
98#ifndef MINSTRTABSIZE 143#if !defined(MINSTRTABSIZE)
99#define MINSTRTABSIZE 32 144#define MINSTRTABSIZE 32
100#endif 145#endif
101 146
102 147
103/* minimum size for string buffer */ 148/* minimum size for string buffer */
104#ifndef LUA_MINBUFFER 149#if !defined(LUA_MINBUFFER)
105#define LUA_MINBUFFER 32 150#define LUA_MINBUFFER 32
106#endif 151#endif
107 152
108 153
109#ifndef lua_lock 154#if !defined(lua_lock)
110#define lua_lock(L) ((void) 0) 155#define lua_lock(L) ((void) 0)
111#define lua_unlock(L) ((void) 0) 156#define lua_unlock(L) ((void) 0)
112#endif 157#endif
113 158
114#ifndef luai_threadyield 159#if !defined(luai_threadyield)
115#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} 160#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
116#endif 161#endif
117 162
118 163
119/* 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/*
120** macro to control inclusion of some hard tests on stack reallocation 293** macro to control inclusion of some hard tests on stack reallocation
121*/ 294*/
122#ifndef HARDSTACKTESTS 295#if !defined(HARDSTACKTESTS)
123#define condhardstacktests(x) ((void)0) 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)
124#else 304#else
125#define condhardstacktests(x) x 305#define condchangemem(L) \
306 ((void)(!(G(L)->gcrunning) || (luaC_fullgc(L, 0), 1)))
126#endif 307#endif
127 308
128#endif 309#endif
diff --git a/apps/plugins/lua/lmathlib.c b/apps/plugins/lua/lmathlib.c
index 99a104050c..0b288e6a12 100644
--- a/apps/plugins/lua/lmathlib.c
+++ b/apps/plugins/lua/lmathlib.c
@@ -1,14 +1,12 @@
1/* 1/*
2** $Id: lmathlib.c,v 1.67.1.1 2007/12/27 13:02:25 roberto Exp $ 2** $Id: lmathlib.c,v 1.83.1.1 2013/04/12 18:48:47 roberto Exp $
3** Standard mathematical library 3** Standard mathematical library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
6 6
7 7
8#if 0
9#include <stdlib.h> 8#include <stdlib.h>
10#include <math.h> 9#include <math.h>
11#endif
12 10
13#define lmathlib_c 11#define lmathlib_c
14#define LUA_LIB 12#define LUA_LIB
@@ -20,9 +18,9 @@
20 18
21 19
22#undef PI 20#undef PI
23#define PI (3.14159265358979323846) 21#define PI ((lua_Number)(3.1415926535897932384626433832795))
24#define RADIANS_PER_DEGREE (PI/180.0) 22#define RADIANS_PER_DEGREE ((lua_Number)(PI/180.0))
25#define DEGREES_PER_RADIAN (180.0/PI) 23#define DEGREES_PER_RADIAN ((lua_Number)180.0/PI)
26 24
27 25
28static int math_abs (lua_State *L) { 26static int math_abs (lua_State *L) {
@@ -34,52 +32,53 @@ static int math_abs (lua_State *L) {
34 32
35#if 0 33#if 0
36static int math_sin (lua_State *L) { 34static int math_sin (lua_State *L) {
37 lua_pushnumber(L, sin(luaL_checknumber(L, 1))); 35 lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1)));
38 return 1; 36 return 1;
39} 37}
40 38
41static int math_sinh (lua_State *L) { 39static int math_sinh (lua_State *L) {
42 lua_pushnumber(L, sinh(luaL_checknumber(L, 1))); 40 lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1)));
43 return 1; 41 return 1;
44} 42}
45 43
46static int math_cos (lua_State *L) { 44static int math_cos (lua_State *L) {
47 lua_pushnumber(L, cos(luaL_checknumber(L, 1))); 45 lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1)));
48 return 1; 46 return 1;
49} 47}
50 48
51static int math_cosh (lua_State *L) { 49static int math_cosh (lua_State *L) {
52 lua_pushnumber(L, cosh(luaL_checknumber(L, 1))); 50 lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1)));
53 return 1; 51 return 1;
54} 52}
55 53
56static int math_tan (lua_State *L) { 54static int math_tan (lua_State *L) {
57 lua_pushnumber(L, tan(luaL_checknumber(L, 1))); 55 lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1)));
58 return 1; 56 return 1;
59} 57}
60 58
61static int math_tanh (lua_State *L) { 59static int math_tanh (lua_State *L) {
62 lua_pushnumber(L, tanh(luaL_checknumber(L, 1))); 60 lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1)));
63 return 1; 61 return 1;
64} 62}
65 63
66static int math_asin (lua_State *L) { 64static int math_asin (lua_State *L) {
67 lua_pushnumber(L, asin(luaL_checknumber(L, 1))); 65 lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1)));
68 return 1; 66 return 1;
69} 67}
70 68
71static int math_acos (lua_State *L) { 69static int math_acos (lua_State *L) {
72 lua_pushnumber(L, acos(luaL_checknumber(L, 1))); 70 lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1)));
73 return 1; 71 return 1;
74} 72}
75 73
76static int math_atan (lua_State *L) { 74static int math_atan (lua_State *L) {
77 lua_pushnumber(L, atan(luaL_checknumber(L, 1))); 75 lua_pushnumber(L, l_mathop(atan)(luaL_checknumber(L, 1)));
78 return 1; 76 return 1;
79} 77}
80 78
81static int math_atan2 (lua_State *L) { 79static int math_atan2 (lua_State *L) {
82 lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); 80 lua_pushnumber(L, l_mathop(atan2)(luaL_checknumber(L, 1),
81 luaL_checknumber(L, 2)));
83 return 1; 82 return 1;
84} 83}
85#endif 84#endif
@@ -104,35 +103,48 @@ static int math_fmod (lua_State *L) {
104 103
105#if 0 104#if 0
106static int math_modf (lua_State *L) { 105static int math_modf (lua_State *L) {
107 double ip; 106 lua_Number ip;
108 double fp = modf(luaL_checknumber(L, 1), &ip); 107 lua_Number fp = l_mathop(modf)(luaL_checknumber(L, 1), &ip);
109 lua_pushnumber(L, ip); 108 lua_pushnumber(L, ip);
110 lua_pushnumber(L, fp); 109 lua_pushnumber(L, fp);
111 return 2; 110 return 2;
112} 111}
113 112
114static int math_sqrt (lua_State *L) { 113static int math_sqrt (lua_State *L) {
115 lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); 114 lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1)));
116 return 1; 115 return 1;
117} 116}
118 117
119static int math_pow (lua_State *L) { 118static int math_pow (lua_State *L) {
120 lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); 119 lua_Number x = luaL_checknumber(L, 1);
120 lua_Number y = luaL_checknumber(L, 2);
121 lua_pushnumber(L, l_mathop(pow)(x, y));
121 return 1; 122 return 1;
122} 123}
123 124
124static int math_log (lua_State *L) { 125static int math_log (lua_State *L) {
125 lua_pushnumber(L, log(luaL_checknumber(L, 1))); 126 lua_Number x = luaL_checknumber(L, 1);
127 lua_Number res;
128 if (lua_isnoneornil(L, 2))
129 res = l_mathop(log)(x);
130 else {
131 lua_Number base = luaL_checknumber(L, 2);
132 if (base == (lua_Number)10.0) res = l_mathop(log10)(x);
133 else res = l_mathop(log)(x)/l_mathop(log)(base);
134 }
135 lua_pushnumber(L, res);
126 return 1; 136 return 1;
127} 137}
128 138
139#if defined(LUA_COMPAT_LOG10)
129static int math_log10 (lua_State *L) { 140static int math_log10 (lua_State *L) {
130 lua_pushnumber(L, log10(luaL_checknumber(L, 1))); 141 lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1)));
131 return 1; 142 return 1;
132} 143}
144#endif
133 145
134static int math_exp (lua_State *L) { 146static int math_exp (lua_State *L) {
135 lua_pushnumber(L, exp(luaL_checknumber(L, 1))); 147 lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1)));
136 return 1; 148 return 1;
137} 149}
138#endif 150#endif
@@ -140,6 +152,7 @@ static int math_deg (lua_State *L) {
140 lua_pushnumber(L, luaL_checknumber(L, 1)*DEGREES_PER_RADIAN); 152 lua_pushnumber(L, luaL_checknumber(L, 1)*DEGREES_PER_RADIAN);
141 return 1; 153 return 1;
142} 154}
155
143static int math_rad (lua_State *L) { 156static int math_rad (lua_State *L) {
144 lua_pushnumber(L, (luaL_checknumber(L, 1)*100)/(DEGREES_PER_RADIAN*100)); 157 lua_pushnumber(L, (luaL_checknumber(L, 1)*100)/(DEGREES_PER_RADIAN*100));
145 return 1; 158 return 1;
@@ -148,13 +161,15 @@ static int math_rad (lua_State *L) {
148#if 0 161#if 0
149static int math_frexp (lua_State *L) { 162static int math_frexp (lua_State *L) {
150 int e; 163 int e;
151 lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e)); 164 lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e));
152 lua_pushinteger(L, e); 165 lua_pushinteger(L, e);
153 return 2; 166 return 2;
154} 167}
155 168
156static int math_ldexp (lua_State *L) { 169static int math_ldexp (lua_State *L) {
157 lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2))); 170 lua_Number x = luaL_checknumber(L, 1);
171 int ep = luaL_checkint(L, 2);
172 lua_pushnumber(L, l_mathop(ldexp)(x, ep));
158 return 1; 173 return 1;
159} 174}
160#endif 175#endif
@@ -197,16 +212,16 @@ static int math_random (lua_State *L) {
197 break; 212 break;
198 } 213 }
199 case 1: { /* only upper limit */ 214 case 1: { /* only upper limit */
200 int u = luaL_checkint(L, 1); 215 lua_Number u = luaL_checknumber(L, 1);
201 luaL_argcheck(L, 1<=u, 1, "interval is empty"); 216 luaL_argcheck(L, 1 <= u, 1, "interval is empty");
202 lua_pushnumber(L, r%u+1); /* int between 1 and `u' */ 217 lua_pushnumber(L, r%u+1); /* int between 1 and `u' */
203 break; 218 break;
204 } 219 }
205 case 2: { /* lower and upper limits */ 220 case 2: { /* lower and upper limits */
206 int l = luaL_checkint(L, 1); 221 lua_Number l = luaL_checknumber(L, 1);
207 int u = luaL_checkint(L, 2); 222 lua_Number u = luaL_checknumber(L, 2);
208 luaL_argcheck(L, l<=u, 2, "interval is empty"); 223 luaL_argcheck(L, l <= u, 2, "interval is empty");
209 lua_pushnumber(L, r%(u-l+1)+l); /* int between `l' and `u' */ 224 lua_pushnumber(L, r%(u-l+1)+l); /* [l, u] */
210 break; 225 break;
211 } 226 }
212 default: return luaL_error(L, "wrong number of arguments"); 227 default: return luaL_error(L, "wrong number of arguments");
@@ -216,7 +231,7 @@ static int math_random (lua_State *L) {
216 231
217 232
218static int math_randomseed (lua_State *L) { 233static int math_randomseed (lua_State *L) {
219 rb->srand(luaL_checkint(L, 1)); 234 rb->srand(luaL_checkunsigned(L, 1));
220 return 0; 235 return 0;
221} 236}
222 237
@@ -243,7 +258,9 @@ static const luaL_Reg mathlib[] = {
243#if 0 258#if 0
244 {"frexp", math_frexp}, 259 {"frexp", math_frexp},
245 {"ldexp", math_ldexp}, 260 {"ldexp", math_ldexp},
261#if defined(LUA_COMPAT_LOG10)
246 {"log10", math_log10}, 262 {"log10", math_log10},
263#endif
247 {"log", math_log}, 264 {"log", math_log},
248#endif 265#endif
249 {"max", math_max}, 266 {"max", math_max},
@@ -259,7 +276,7 @@ static const luaL_Reg mathlib[] = {
259 {"sinh", math_sinh}, 276 {"sinh", math_sinh},
260 {"sin", math_sin}, 277 {"sin", math_sin},
261 {"sqrt", math_sqrt}, 278 {"sqrt", math_sqrt},
262 {"tanh", math_tanh}, 279 {"tanh", math_tanh},
263 {"tan", math_tan}, 280 {"tan", math_tan},
264#endif 281#endif
265 {NULL, NULL} 282 {NULL, NULL}
@@ -269,17 +286,14 @@ static const luaL_Reg mathlib[] = {
269/* 286/*
270** Open math library 287** Open math library
271*/ 288*/
272LUALIB_API int luaopen_math (lua_State *L) { 289LUAMOD_API int luaopen_math (lua_State *L) {
273 luaL_register(L, LUA_MATHLIBNAME, mathlib); 290 luaL_newlib(L, mathlib);
274#if 0 /* No use in adding floating point constants when there's no FP */ 291#if 0 /* No use in adding floating point constants when there's no FP */
275 lua_pushnumber(L, PI); 292 lua_pushnumber(L, PI);
276 lua_setfield(L, -2, "pi"); 293 lua_setfield(L, -2, "pi");
277 lua_pushnumber(L, HUGE_VAL); 294 lua_pushnumber(L, HUGE_VAL);
278 lua_setfield(L, -2, "huge"); 295 lua_setfield(L, -2, "huge");
279#if defined(LUA_COMPAT_MOD)
280 lua_getfield(L, -1, "fmod");
281 lua_setfield(L, -2, "mod");
282#endif
283#endif 296#endif
284 return 1; 297 return 1;
285} 298}
299
diff --git a/apps/plugins/lua/lmem.c b/apps/plugins/lua/lmem.c
index ae7d8c965f..ee343e3e03 100644
--- a/apps/plugins/lua/lmem.c
+++ b/apps/plugins/lua/lmem.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lmem.c,v 1.70.1.1 2007/12/27 13:02:25 roberto Exp $ 2** $Id: lmem.c,v 1.84.1.1 2013/04/12 18:48:47 roberto Exp $
3** Interface to Memory Manager 3** Interface to Memory Manager
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -14,6 +14,7 @@
14 14
15#include "ldebug.h" 15#include "ldebug.h"
16#include "ldo.h" 16#include "ldo.h"
17#include "lgc.h"
17#include "lmem.h" 18#include "lmem.h"
18#include "lobject.h" 19#include "lobject.h"
19#include "lstate.h" 20#include "lstate.h"
@@ -25,12 +26,11 @@
25** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); 26** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
26** (`osize' is the old size, `nsize' is the new size) 27** (`osize' is the old size, `nsize' is the new size)
27** 28**
28** Lua ensures that (ptr == NULL) iff (osize == 0). 29** * frealloc(ud, NULL, x, s) creates a new block of size `s' (no
29** 30** matter 'x').
30** * frealloc(ud, NULL, 0, x) creates a new block of size `x'
31** 31**
32** * frealloc(ud, p, x, 0) frees the block `p' 32** * frealloc(ud, p, x, 0) frees the block `p'
33** (in this specific case, frealloc must return NULL). 33** (in this specific case, frealloc must return NULL);
34** particularly, frealloc(ud, NULL, 0, 0) does nothing 34** particularly, frealloc(ud, NULL, 0, 0) does nothing
35** (which is equivalent to free(NULL) in ANSI C) 35** (which is equivalent to free(NULL) in ANSI C)
36** 36**
@@ -44,12 +44,12 @@
44 44
45 45
46void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, 46void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
47 int limit, const char *errormsg) { 47 int limit, const char *what) {
48 void *newblock; 48 void *newblock;
49 int newsize; 49 int newsize;
50 if (*size >= limit/2) { /* cannot double it? */ 50 if (*size >= limit/2) { /* cannot double it? */
51 if (*size >= limit) /* cannot grow even a little? */ 51 if (*size >= limit) /* cannot grow even a little? */
52 luaG_runerror(L, errormsg); 52 luaG_runerror(L, "too many %s (limit is %d)", what, limit);
53 newsize = limit; /* still have at least one free place */ 53 newsize = limit; /* still have at least one free place */
54 } 54 }
55 else { 55 else {
@@ -63,9 +63,8 @@ void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
63} 63}
64 64
65 65
66void *luaM_toobig (lua_State *L) { 66l_noret luaM_toobig (lua_State *L) {
67 luaG_runerror(L, "memory allocation error: block too big"); 67 luaG_runerror(L, "memory allocation error: block too big");
68 return NULL; /* to avoid warnings */
69} 68}
70 69
71 70
@@ -74,13 +73,27 @@ void *luaM_toobig (lua_State *L) {
74** generic allocation routine. 73** generic allocation routine.
75*/ 74*/
76void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { 75void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
76 void *newblock;
77 global_State *g = G(L); 77 global_State *g = G(L);
78 lua_assert((osize == 0) == (block == NULL)); 78 size_t realosize = (block) ? osize : 0;
79 block = (*g->frealloc)(g->ud, block, osize, nsize); 79 lua_assert((realosize == 0) == (block == NULL));
80 if (block == NULL && nsize > 0) 80#if defined(HARDMEMTESTS)
81 luaD_throw(L, LUA_ERRMEM); 81 if (nsize > realosize && g->gcrunning)
82 lua_assert((nsize == 0) == (block == NULL)); 82 luaC_fullgc(L, 1); /* force a GC whenever possible */
83 g->totalbytes = (g->totalbytes - osize) + nsize; 83#endif
84 return block; 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;
85} 98}
86 99
diff --git a/apps/plugins/lua/lmem.h b/apps/plugins/lua/lmem.h
index 97a888c7f8..bd4f4e0726 100644
--- a/apps/plugins/lua/lmem.h
+++ b/apps/plugins/lua/lmem.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: lmem.h,v 1.40.1.1 2013/04/12 18:48:47 roberto Exp $
3** Interface to Memory Manager 3** Interface to Memory Manager
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -13,23 +13,30 @@
13#include "llimits.h" 13#include "llimits.h"
14#include "lua.h" 14#include "lua.h"
15 15
16#define MEMERRMSG "not enough memory"
17
18 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*/
19#define luaM_reallocv(L,b,on,n,e) \ 24#define luaM_reallocv(L,b,on,n,e) \
20 ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ 25 (cast(void, \
21 luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \ 26 (cast(size_t, (n)+1) > MAX_SIZET/(e)) ? (luaM_toobig(L), 0) : 0), \
22 luaM_toobig(L)) 27 luaM_realloc_(L, (b), (on)*(e), (n)*(e)))
23 28
24#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) 29#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
25#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) 30#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
26#define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t)) 31#define luaM_freearray(L, b, n) luaM_reallocv(L, (b), n, 0, sizeof((b)[0]))
27 32
28#define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t)) 33#define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s))
29#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) 34#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t)))
30#define luaM_newvector(L,n,t) \ 35#define luaM_newvector(L,n,t) \
31 cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) 36 cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
32 37
38#define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s))
39
33#define luaM_growvector(L,v,nelems,size,t,limit,e) \ 40#define luaM_growvector(L,v,nelems,size,t,limit,e) \
34 if ((nelems)+1 > (size)) \ 41 if ((nelems)+1 > (size)) \
35 ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) 42 ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
@@ -37,13 +44,14 @@
37#define luaM_reallocvector(L, v,oldn,n,t) \ 44#define luaM_reallocvector(L, v,oldn,n,t) \
38 ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) 45 ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
39 46
47LUAI_FUNC l_noret luaM_toobig (lua_State *L);
40 48
49/* not to be called directly */
41LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, 50LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
42 size_t size); 51 size_t size);
43LUAI_FUNC void *luaM_toobig (lua_State *L);
44LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, 52LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
45 size_t size_elem, int limit, 53 size_t size_elem, int limit,
46 const char *errormsg); 54 const char *what);
47 55
48#endif 56#endif
49 57
diff --git a/apps/plugins/lua/loadlib.c b/apps/plugins/lua/loadlib.c
index 1cc7ebd7db..f5a63386b5 100644
--- a/apps/plugins/lua/loadlib.c
+++ b/apps/plugins/lua/loadlib.c
@@ -1,14 +1,22 @@
1/* 1/*
2** $Id: loadlib.c,v 1.52.1.3 2008/08/06 13:29:28 roberto Exp $ 2** $Id: loadlib.c,v 1.111.1.1 2013/04/12 18:48:47 roberto Exp $
3** Dynamic library loader for Lua 3** Dynamic library loader for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5** 5**
6** This module contains an implementation of loadlib for Unix systems 6** This module contains an implementation of loadlib for Unix systems
7** that have dlfcn, an implementation for Darwin (Mac OS X), an 7** that have dlfcn, an implementation for Windows, and a stub for other
8** implementation for Windows, and a stub for other systems. 8** systems.
9*/ 9*/
10 10
11 11
12/*
13** if needed, includes windows header before everything else
14*/
15#if defined(_WIN32)
16#include <windows.h>
17#endif
18
19
12#include <stdlib.h> 20#include <stdlib.h>
13#include <string.h> 21#include <string.h>
14 22
@@ -20,10 +28,296 @@
20 28
21#include "lauxlib.h" 29#include "lauxlib.h"
22#include "lualib.h" 30#include "lualib.h"
23#include "rocklib.h"
24 31
25 32
26#define setprogdir(L) ((void)0) 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 = rb->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
27 321
28 322
29/* 323/*
@@ -34,70 +328,143 @@
34 328
35 329
36static int readable (const char *filename) { 330static int readable (const char *filename) {
37 int f = rb->open(filename, O_RDONLY); /* try to open file */ 331 return rb->file_exists(filename);
38 if (f < 0) return 0; /* open failed */
39 rb->close(f);
40 return 1;
41} 332}
42 333
43 334
44static const char *pushnexttemplate (lua_State *L, const char *path) { 335static const char *pushnexttemplate (lua_State *L, const char *path) {
45 const char *l; 336 const char *l;
46 while (*path == *LUA_PATHSEP) path++; /* skip separators */ 337 while (*path == *LUA_PATH_SEP) path++; /* skip separators */
47 if (*path == '\0') return NULL; /* no more templates */ 338 if (*path == '\0') return NULL; /* no more templates */
48 l = strchr(path, *LUA_PATHSEP); /* find next separator */ 339 l = strchr(path, *LUA_PATH_SEP); /* find next separator */
49 if (l == NULL) l = path + strlen(path); 340 if (l == NULL) l = path + strlen(path);
50 lua_pushlstring(L, path, l - path); /* template */ 341 lua_pushlstring(L, path, l - path); /* template */
51 return l; 342 return l;
52} 343}
53 344
54 345
55static const char *findfile (lua_State *L, const char *name, 346static const char *searchpath (lua_State *L, const char *name,
56 const char *pname) { 347 const char *path,
57 const char *path, *current_path = get_current_path(L, 2); 348 const char *sep,
58 name = luaL_gsub(L, name, ".", LUA_DIRSEP); 349 const char *dirsep) {
59 lua_getfield(L, LUA_ENVIRONINDEX, pname); 350 luaL_Buffer msg; /* to build error message */
60 path = lua_tostring(L, -1); 351 luaL_buffinit(L, &msg);
61 if (path == NULL) 352 if (*sep != '\0') /* non-empty separator? */
62 luaL_error(L, LUA_QL("package.%s") " must be a string", pname); 353 name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */
63 lua_pushliteral(L, ""); /* error accumulator */
64 while ((path = pushnexttemplate(L, path)) != NULL) { 354 while ((path = pushnexttemplate(L, path)) != NULL) {
65 const char *filename; 355 const char *filename = luaL_gsub(L, lua_tostring(L, -1),
66 filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name); 356 LUA_PATH_MARK, name);
67 if(current_path != NULL) filename = luaL_gsub(L, filename, "$", current_path);
68 lua_remove(L, -2); /* remove path template */ 357 lua_remove(L, -2); /* remove path template */
69 if (readable(filename)) /* does file exist and is readable? */ 358 if (readable(filename)) /* does file exist and is readable? */
70 return filename; /* return that file name */ 359 return filename; /* return that file name */
71 lua_pushfstring(L, "\n\tno file " LUA_QS, filename); 360 lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
72 lua_remove(L, -2); /* remove file name */ 361 lua_remove(L, -2); /* remove file name */
73 lua_concat(L, 2); /* add entry to possible error message */ 362 luaL_addvalue(&msg); /* concatenate error msg. entry */
74 } 363 }
364 luaL_pushresult(&msg); /* create error message */
75 return NULL; /* not found */ 365 return NULL; /* not found */
76} 366}
77 367
78 368
79static void loaderror (lua_State *L, const char *filename) { 369static int ll_searchpath (lua_State *L) {
80 luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s", 370 const char *f = searchpath(L, luaL_checkstring(L, 1),
81 lua_tostring(L, 1), filename, lua_tostring(L, -1)); 371 luaL_checkstring(L, 2),
372 luaL_optstring(L, 3, "."),
373 luaL_optstring(L, 4, LUA_DIRSEP));
374 if (f != NULL) return 1;
375 else { /* error message is on top of the stack */
376 lua_pushnil(L);
377 lua_insert(L, -2);
378 return 2; /* return nil + error message */
379 }
82} 380}
83 381
84 382
85static int loader_Lua (lua_State *L) { 383static const char *findfile (lua_State *L, const char *name,
384 const char *pname,
385 const char *dirsep) {
386 const char *path;
387 lua_getfield(L, lua_upvalueindex(1), pname);
388 path = lua_tostring(L, -1);
389 if (path == NULL)
390 luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
391 return searchpath(L, name, path, ".", dirsep);
392}
393
394
395static int checkload (lua_State *L, int stat, const char *filename) {
396 if (stat) { /* module loaded successfully? */
397 lua_pushstring(L, filename); /* will be 2nd argument to module */
398 return 2; /* return open function and file name */
399 }
400 else
401 return luaL_error(L, "error loading module " LUA_QS
402 " from file " LUA_QS ":\n\t%s",
403 lua_tostring(L, 1), filename, lua_tostring(L, -1));
404}
405
406
407static int searcher_Lua (lua_State *L) {
86 const char *filename; 408 const char *filename;
87 const char *name = luaL_checkstring(L, 1); 409 const char *name = luaL_checkstring(L, 1);
88 filename = findfile(L, name, "path"); 410 filename = findfile(L, name, "path", LUA_LSUBSEP);
89 if (filename == NULL) return 1; /* library not found in this path */ 411 if (filename == NULL) return 1; /* module not found in this path */
90 if (luaL_loadfile(L, filename) != 0) 412 return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename);
91 loaderror(L, filename); 413}
92 return 1; /* library loaded successfully */ 414
415
416static int loadfunc (lua_State *L, const char *filename, const char *modname) {
417 const char *funcname;
418 const char *mark;
419 modname = luaL_gsub(L, modname, ".", LUA_OFSEP);
420 mark = strchr(modname, *LUA_IGMARK);
421 if (mark) {
422 int stat;
423 funcname = lua_pushlstring(L, modname, mark - modname);
424 funcname = lua_pushfstring(L, LUA_POF"%s", funcname);
425 stat = ll_loadfunc(L, filename, funcname);
426 if (stat != ERRFUNC) return stat;
427 modname = mark + 1; /* else go ahead and try old-style name */
428 }
429 funcname = lua_pushfstring(L, LUA_POF"%s", modname);
430 return ll_loadfunc(L, filename, funcname);
93} 431}
94 432
95 433
96static int loader_preload (lua_State *L) { 434static int searcher_C (lua_State *L) {
97 const char *name = luaL_checkstring(L, 1); 435 const char *name = luaL_checkstring(L, 1);
98 lua_getfield(L, LUA_ENVIRONINDEX, "preload"); 436 const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP);
99 if (!lua_istable(L, -1)) 437 if (filename == NULL) return 1; /* module not found in this path */
100 luaL_error(L, LUA_QL("package.preload") " must be a table"); 438 return checkload(L, (loadfunc(L, filename, name) == 0), filename);
439}
440
441
442static int searcher_Croot (lua_State *L) {
443 const char *filename;
444 const char *name = luaL_checkstring(L, 1);
445 const char *p = strchr(name, '.');
446 int stat;
447 if (p == NULL) return 0; /* is root */
448 lua_pushlstring(L, name, p - name);
449 filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP);
450 if (filename == NULL) return 1; /* root not found */
451 if ((stat = loadfunc(L, filename, name)) != 0) {
452 if (stat != ERRFUNC)
453 return checkload(L, 0, filename); /* real error */
454 else { /* open function not found */
455 lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
456 name, filename);
457 return 1;
458 }
459 }
460 lua_pushstring(L, filename); /* will be 2nd argument to module */
461 return 2;
462}
463
464
465static int searcher_preload (lua_State *L) {
466 const char *name = luaL_checkstring(L, 1);
467 lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD");
101 lua_getfield(L, -1, name); 468 lua_getfield(L, -1, name);
102 if (lua_isnil(L, -1)) /* not found? */ 469 if (lua_isnil(L, -1)) /* not found? */
103 lua_pushfstring(L, "\n\tno field package.preload['%s']", name); 470 lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
@@ -105,48 +472,53 @@ static int loader_preload (lua_State *L) {
105} 472}
106 473
107 474
108static const int sentinel_ = 0; 475static void findloader (lua_State *L, const char *name) {
109#define sentinel ((void *)&sentinel_) 476 int i;
477 luaL_Buffer msg; /* to build error message */
478 luaL_buffinit(L, &msg);
479 lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */
480 if (!lua_istable(L, 3))
481 luaL_error(L, LUA_QL("package.searchers") " must be a table");
482 /* iterate over available searchers to find a loader */
483 for (i = 1; ; i++) {
484 lua_rawgeti(L, 3, i); /* get a searcher */
485 if (lua_isnil(L, -1)) { /* no more searchers? */
486 lua_pop(L, 1); /* remove nil */
487 luaL_pushresult(&msg); /* create error message */
488 luaL_error(L, "module " LUA_QS " not found:%s",
489 name, lua_tostring(L, -1));
490 }
491 lua_pushstring(L, name);
492 lua_call(L, 1, 2); /* call it */
493 if (lua_isfunction(L, -2)) /* did it find a loader? */
494 return; /* module loader found */
495 else if (lua_isstring(L, -2)) { /* searcher returned error message? */
496 lua_pop(L, 1); /* remove extra return */
497 luaL_addvalue(&msg); /* concatenate error message */
498 }
499 else
500 lua_pop(L, 2); /* remove both returns */
501 }
502}
110 503
111 504
112static int ll_require (lua_State *L) { 505static int ll_require (lua_State *L) {
113 const char *name = luaL_checkstring(L, 1); 506 const char *name = luaL_checkstring(L, 1);
114 int i;
115 lua_settop(L, 1); /* _LOADED table will be at index 2 */ 507 lua_settop(L, 1); /* _LOADED table will be at index 2 */
116 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); 508 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
117 lua_getfield(L, 2, name); 509 lua_getfield(L, 2, name); /* _LOADED[name] */
118 if (lua_toboolean(L, -1)) { /* is it there? */ 510 if (lua_toboolean(L, -1)) /* is it there? */
119 if (lua_touserdata(L, -1) == sentinel) /* check loops */
120 luaL_error(L, "loop or previous error loading module " LUA_QS, name);
121 return 1; /* package is already loaded */ 511 return 1; /* package is already loaded */
122 } 512 /* else must load package */
123 /* else must load it; iterate over available loaders */ 513 lua_pop(L, 1); /* remove 'getfield' result */
124 lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); 514 findloader(L, name);
125 if (!lua_istable(L, -1)) 515 lua_pushstring(L, name); /* pass name as argument to module loader */
126 luaL_error(L, LUA_QL("package.loaders") " must be a table"); 516 lua_insert(L, -2); /* name is 1st argument (before search data) */
127 lua_pushliteral(L, ""); /* error message accumulator */ 517 lua_call(L, 2, 1); /* run loader to load module */
128 for (i=1; ; i++) {
129 lua_rawgeti(L, -2, i); /* get a loader */
130 if (lua_isnil(L, -1))
131 luaL_error(L, "module " LUA_QS " not found:%s",
132 name, lua_tostring(L, -2));
133 lua_pushstring(L, name);
134 lua_call(L, 1, 1); /* call it */
135 if (lua_isfunction(L, -1)) /* did it find module? */
136 break; /* module loaded successfully */
137 else if (lua_isstring(L, -1)) /* loader returned error message? */
138 lua_concat(L, 2); /* accumulate it */
139 else
140 lua_pop(L, 1);
141 }
142 lua_pushlightuserdata(L, sentinel);
143 lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */
144 lua_pushstring(L, name); /* pass name as argument to module */
145 lua_call(L, 1, 1); /* run loaded module */
146 if (!lua_isnil(L, -1)) /* non-nil return? */ 518 if (!lua_isnil(L, -1)) /* non-nil return? */
147 lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ 519 lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
148 lua_getfield(L, 2, name); 520 lua_getfield(L, 2, name);
149 if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */ 521 if (lua_isnil(L, -1)) { /* module did not set a value? */
150 lua_pushboolean(L, 1); /* use true as result */ 522 lua_pushboolean(L, 1); /* use true as result */
151 lua_pushvalue(L, -1); /* extra copy to be returned */ 523 lua_pushvalue(L, -1); /* extra copy to be returned */
152 lua_setfield(L, 2, name); /* _LOADED[name] = true */ 524 lua_setfield(L, 2, name); /* _LOADED[name] = true */
@@ -163,26 +535,31 @@ static int ll_require (lua_State *L) {
163** 'module' function 535** 'module' function
164** ======================================================= 536** =======================================================
165*/ 537*/
166 538#if defined(LUA_COMPAT_MODULE)
167 539
168static void setfenv (lua_State *L) { 540/*
541** changes the environment variable of calling function
542*/
543static void set_env (lua_State *L) {
169 lua_Debug ar; 544 lua_Debug ar;
170 if (lua_getstack(L, 1, &ar) == 0 || 545 if (lua_getstack(L, 1, &ar) == 0 ||
171 lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ 546 lua_getinfo(L, "f", &ar) == 0 || /* get calling function */
172 lua_iscfunction(L, -1)) 547 lua_iscfunction(L, -1))
173 luaL_error(L, LUA_QL("module") " not called from a Lua function"); 548 luaL_error(L, LUA_QL("module") " not called from a Lua function");
174 lua_pushvalue(L, -2); 549 lua_pushvalue(L, -2); /* copy new environment table to top */
175 lua_setfenv(L, -2); 550 lua_setupvalue(L, -2, 1);
176 lua_pop(L, 1); 551 lua_pop(L, 1); /* remove function */
177} 552}
178 553
179 554
180static void dooptions (lua_State *L, int n) { 555static void dooptions (lua_State *L, int n) {
181 int i; 556 int i;
182 for (i = 2; i <= n; i++) { 557 for (i = 2; i <= n; i++) {
183 lua_pushvalue(L, i); /* get option (a function) */ 558 if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */
184 lua_pushvalue(L, -2); /* module */ 559 lua_pushvalue(L, i); /* get option (a function) */
185 lua_call(L, 1, 0); 560 lua_pushvalue(L, -2); /* module */
561 lua_call(L, 1, 0);
562 }
186 } 563 }
187} 564}
188 565
@@ -204,17 +581,8 @@ static void modinit (lua_State *L, const char *modname) {
204 581
205static int ll_module (lua_State *L) { 582static int ll_module (lua_State *L) {
206 const char *modname = luaL_checkstring(L, 1); 583 const char *modname = luaL_checkstring(L, 1);
207 int loaded = lua_gettop(L) + 1; /* index of _LOADED table */ 584 int lastarg = lua_gettop(L); /* last parameter */
208 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); 585 luaL_pushmodule(L, modname, 1); /* get/create module table */
209 lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
210 if (!lua_istable(L, -1)) { /* not found? */
211 lua_pop(L, 1); /* remove previous result */
212 /* try global variable (and create one if it does not exist) */
213 if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL)
214 return luaL_error(L, "name conflict for module " LUA_QS, modname);
215 lua_pushvalue(L, -1);
216 lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */
217 }
218 /* check whether table already has a _NAME field */ 586 /* check whether table already has a _NAME field */
219 lua_getfield(L, -1, "_NAME"); 587 lua_getfield(L, -1, "_NAME");
220 if (!lua_isnil(L, -1)) /* is table an initialized module? */ 588 if (!lua_isnil(L, -1)) /* is table an initialized module? */
@@ -224,9 +592,9 @@ static int ll_module (lua_State *L) {
224 modinit(L, modname); 592 modinit(L, modname);
225 } 593 }
226 lua_pushvalue(L, -1); 594 lua_pushvalue(L, -1);
227 setfenv(L); 595 set_env(L);
228 dooptions(L, loaded - 1); 596 dooptions(L, lastarg);
229 return 0; 597 return 1;
230} 598}
231 599
232 600
@@ -237,22 +605,38 @@ static int ll_seeall (lua_State *L) {
237 lua_pushvalue(L, -1); 605 lua_pushvalue(L, -1);
238 lua_setmetatable(L, 1); 606 lua_setmetatable(L, 1);
239 } 607 }
240 lua_pushvalue(L, LUA_GLOBALSINDEX); 608 lua_pushglobaltable(L);
241 lua_setfield(L, -2, "__index"); /* mt.__index = _G */ 609 lua_setfield(L, -2, "__index"); /* mt.__index = _G */
242 return 0; 610 return 0;
243} 611}
244 612
245 613#endif
246/* }====================================================== */ 614/* }====================================================== */
247 615
248 616
249 617
250/* auxiliary mark (for internal use) */ 618/* auxiliary mark (for internal use) */
251#define AUXMARK "\1" 619#define AUXMARK "\1"
620
621
622/*
623** return registry.LUA_NOENV as a boolean
624*/
625#if 0
626static int noenv (lua_State *L) {
627 int b;
628 lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
629 b = lua_toboolean(L, -1);
630 lua_pop(L, 1); /* remove value */
631 return b;
632}
633#endif
634
252 635
253static void setpath (lua_State *L, const char *fieldname, const char *envname, 636static void setpath (lua_State *L, const char *fieldname, const char *envname1,
254 const char *def) { 637 const char *envname2, const char *def) {
255 (void)envname; 638 (void)envname1;
639 (void)envname2;
256 lua_pushstring(L, def); /* use default */ 640 lua_pushstring(L, def); /* use default */
257 setprogdir(L); 641 setprogdir(L);
258 lua_setfield(L, -2, fieldname); 642 lua_setfield(L, -2, fieldname);
@@ -260,56 +644,72 @@ static void setpath (lua_State *L, const char *fieldname, const char *envname,
260 644
261 645
262static const luaL_Reg pk_funcs[] = { 646static const luaL_Reg pk_funcs[] = {
647 {"loadlib", ll_loadlib},
648 {"searchpath", ll_searchpath},
649#if defined(LUA_COMPAT_MODULE)
263 {"seeall", ll_seeall}, 650 {"seeall", ll_seeall},
651#endif
264 {NULL, NULL} 652 {NULL, NULL}
265}; 653};
266 654
267 655
268static const luaL_Reg ll_funcs[] = { 656static const luaL_Reg ll_funcs[] = {
657#if defined(LUA_COMPAT_MODULE)
269 {"module", ll_module}, 658 {"module", ll_module},
659#endif
270 {"require", ll_require}, 660 {"require", ll_require},
271 {NULL, NULL} 661 {NULL, NULL}
272}; 662};
273 663
274 664
275static const lua_CFunction loaders[] = 665static void createsearcherstable (lua_State *L) {
276 {loader_preload, loader_Lua, NULL}; 666 static const lua_CFunction searchers[] =
667 {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL};
668 int i;
669 /* create 'searchers' table */
670 lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0);
671 /* fill it with pre-defined searchers */
672 for (i=0; searchers[i] != NULL; i++) {
673 lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */
674 lua_pushcclosure(L, searchers[i], 1);
675 lua_rawseti(L, -2, i+1);
676 }
677}
277 678
278 679
279LUALIB_API int luaopen_package (lua_State *L) { 680LUAMOD_API int luaopen_package (lua_State *L) {
280 int i; 681 /* create table CLIBS to keep track of loaded C libraries */
281 /* create new type _LOADLIB */ 682 luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS);
282 luaL_newmetatable(L, "_LOADLIB"); 683 lua_createtable(L, 0, 1); /* metatable for CLIBS */
684 lua_pushcfunction(L, gctm);
685 lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */
686 lua_setmetatable(L, -2);
283 /* create `package' table */ 687 /* create `package' table */
284 luaL_register(L, LUA_LOADLIBNAME, pk_funcs); 688 luaL_newlib(L, pk_funcs);
285#if defined(LUA_COMPAT_LOADLIB) 689 createsearcherstable(L);
286 lua_getfield(L, -1, "loadlib"); 690#if defined(LUA_COMPAT_LOADERS)
287 lua_setfield(L, LUA_GLOBALSINDEX, "loadlib"); 691 lua_pushvalue(L, -1); /* make a copy of 'searchers' table */
692 lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */
288#endif 693#endif
289 lua_pushvalue(L, -1); 694 lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */
290 lua_replace(L, LUA_ENVIRONINDEX); 695 /* set field 'path' */
291 /* create `loaders' table */ 696 setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT);
292 lua_createtable(L, 0, sizeof(loaders)/sizeof(loaders[0]) - 1); 697 /* set field 'cpath' */
293 /* fill it with pre-defined loaders */ 698 setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT);
294 for (i=0; loaders[i] != NULL; i++) {
295 lua_pushcfunction(L, loaders[i]);
296 lua_rawseti(L, -2, i+1);
297 }
298 lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */
299 setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */
300 /* store config information */ 699 /* store config information */
301 lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" 700 lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
302 LUA_EXECDIR "\n" LUA_IGMARK); 701 LUA_EXEC_DIR "\n" LUA_IGMARK "\n");
303 lua_setfield(L, -2, "config"); 702 lua_setfield(L, -2, "config");
304 /* set field `loaded' */ 703 /* set field `loaded' */
305 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2); 704 luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
306 lua_setfield(L, -2, "loaded"); 705 lua_setfield(L, -2, "loaded");
307 /* set field `preload' */ 706 /* set field `preload' */
308 lua_newtable(L); 707 luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
309 lua_setfield(L, -2, "preload"); 708 lua_setfield(L, -2, "preload");
310 lua_pushvalue(L, LUA_GLOBALSINDEX); 709 lua_pushglobaltable(L);
311 luaL_register(L, NULL, ll_funcs); /* open lib into global table */ 710 lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */
312 lua_pop(L, 1); 711 luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */
712 lua_pop(L, 1); /* pop global table */
313 return 1; /* return 'package' table */ 713 return 1; /* return 'package' table */
314} 714}
315 715
diff --git a/apps/plugins/lua/lobject.c b/apps/plugins/lua/lobject.c
index 62ad8e9359..34bbb25c9a 100644
--- a/apps/plugins/lua/lobject.c
+++ b/apps/plugins/lua/lobject.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $ 2** $Id: lobject.c,v 2.58.1.1 2013/04/12 18:48:47 roberto Exp $
3** Some generic functions over Lua objects 3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -15,6 +15,8 @@
15 15
16#include "lua.h" 16#include "lua.h"
17 17
18#include "lctype.h"
19#include "ldebug.h"
18#include "ldo.h" 20#include "ldo.h"
19#include "lmem.h" 21#include "lmem.h"
20#include "lobject.h" 22#include "lobject.h"
@@ -24,7 +26,7 @@
24 26
25 27
26 28
27const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL}; 29LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT};
28 30
29 31
30/* 32/*
@@ -33,25 +35,25 @@ const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL};
33** eeeee != 0 and (xxx) otherwise. 35** eeeee != 0 and (xxx) otherwise.
34*/ 36*/
35int luaO_int2fb (unsigned int x) { 37int luaO_int2fb (unsigned int x) {
36 int e = 0; /* expoent */ 38 int e = 0; /* exponent */
37 while (x >= 16) { 39 if (x < 8) return x;
40 while (x >= 0x10) {
38 x = (x+1) >> 1; 41 x = (x+1) >> 1;
39 e++; 42 e++;
40 } 43 }
41 if (x < 8) return x; 44 return ((e+1) << 3) | (cast_int(x) - 8);
42 else return ((e+1) << 3) | (cast_int(x) - 8);
43} 45}
44 46
45 47
46/* converts back */ 48/* converts back */
47int luaO_fb2int (int x) { 49int luaO_fb2int (int x) {
48 int e = (x >> 3) & 31; 50 int e = (x >> 3) & 0x1f;
49 if (e == 0) return x; 51 if (e == 0) return x;
50 else return ((x & 7)+8) << (e - 1); 52 else return ((x & 7) + 8) << (e - 1);
51} 53}
52 54
53 55
54int luaO_log2 (unsigned int x) { 56int luaO_ceillog2 (unsigned int x) {
55 static const lu_byte log_2[256] = { 57 static const lu_byte log_2[256] = {
56 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 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,
57 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 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,
@@ -62,109 +64,169 @@ int luaO_log2 (unsigned int x) {
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, 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,
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 65 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 }; 66 };
65 int l = -1; 67 int l = 0;
68 x--;
66 while (x >= 256) { l += 8; x >>= 8; } 69 while (x >= 256) { l += 8; x >>= 8; }
67 return l + log_2[x]; 70 return l + log_2[x];
71}
72
73
74lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) {
75 switch (op) {
76 case LUA_OPADD: return luai_numadd(NULL, v1, v2);
77 case LUA_OPSUB: return luai_numsub(NULL, v1, v2);
78 case LUA_OPMUL: return luai_nummul(NULL, v1, v2);
79 case LUA_OPDIV: return luai_numdiv(NULL, v1, v2);
80 case LUA_OPMOD: return luai_nummod(NULL, v1, v2);
81 case LUA_OPPOW: return luai_numpow(NULL, v1, v2);
82 case LUA_OPUNM: return luai_numunm(NULL, v1);
83 default: lua_assert(0); return 0;
84 }
85}
86
87
88int luaO_hexavalue (int c) {
89 if (lisdigit(c)) return c - '0';
90 else return ltolower(c) - 'a' + 10;
91}
92
93
94#if !defined(lua_strx2number)
95
96#include <math.h>
97
98
99static int isneg (const char **s) {
100 if (**s == '-') { (*s)++; return 1; }
101 else if (**s == '+') (*s)++;
102 return 0;
103}
68 104
105
106static lua_Number readhexa (const char **s, lua_Number r, int *count) {
107 for (; lisxdigit(cast_uchar(**s)); (*s)++) { /* read integer part */
108 r = (r * cast_num(16.0)) + cast_num(luaO_hexavalue(cast_uchar(**s)));
109 (*count)++;
110 }
111 return r;
69} 112}
70 113
71 114
72int luaO_rawequalObj (const TValue *t1, const TValue *t2) { 115/*
73 if (ttype(t1) != ttype(t2)) return 0; 116** convert an hexadecimal numeric string to a number, following
74 else switch (ttype(t1)) { 117** C99 specification for 'strtod'
75 case LUA_TNIL: 118*/
76 return 1; 119static lua_Number lua_strx2number (const char *s, char **endptr) {
77 case LUA_TNUMBER: 120 lua_Number r = 0.0;
78 return luai_numeq(nvalue(t1), nvalue(t2)); 121 int e = 0, i = 0;
79 case LUA_TBOOLEAN: 122 int neg = 0; /* 1 if number is negative */
80 return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ 123 *endptr = cast(char *, s); /* nothing is valid yet */
81 case LUA_TLIGHTUSERDATA: 124 while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
82 return pvalue(t1) == pvalue(t2); 125 neg = isneg(&s); /* check signal */
83 default: 126 if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
84 lua_assert(iscollectable(t1)); 127 return 0.0; /* invalid format (no '0x') */
85 return gcvalue(t1) == gcvalue(t2); 128 s += 2; /* skip '0x' */
129 r = readhexa(&s, r, &i); /* read integer part */
130 if (*s == '.') {
131 s++; /* skip dot */
132 r = readhexa(&s, r, &e); /* read fractional part */
86 } 133 }
134 if (i == 0 && e == 0)
135 return 0.0; /* invalid format (no digit) */
136 e *= -4; /* each fractional digit divides value by 2^-4 */
137 *endptr = cast(char *, s); /* valid up to here */
138 if (*s == 'p' || *s == 'P') { /* exponent part? */
139 int exp1 = 0;
140 int neg1;
141 s++; /* skip 'p' */
142 neg1 = isneg(&s); /* signal */
143 if (!lisdigit(cast_uchar(*s)))
144 goto ret; /* must have at least one digit */
145 while (lisdigit(cast_uchar(*s))) /* read exponent */
146 exp1 = exp1 * 10 + *(s++) - '0';
147 if (neg1) exp1 = -exp1;
148 e += exp1;
149 }
150 *endptr = cast(char *, s); /* valid up to here */
151 ret:
152 if (neg) r = -r;
153 return l_mathop(ldexp)(r, e);
87} 154}
88 155
156#endif
157
89 158
90int luaO_str2d (const char *s, lua_Number *result) { 159int luaO_str2d (const char *s, size_t len, lua_Number *result) {
91 char *endptr; 160 char *endptr;
92 *result = lua_str2number(s, &endptr); 161 if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */
93 if (endptr == s) return 0; /* conversion failed */ 162 return 0;
94 if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ 163 else if (strpbrk(s, "xX")) /* hexa? */
95 *result = cast_num(strtoul(s, &endptr, 16)); 164 *result = lua_strx2number(s, &endptr);
96 if (*endptr == '\0') return 1; /* most common case */ 165 else
97 while (isspace(cast(unsigned char, *endptr))) endptr++; 166 *result = lua_str2number(s, &endptr);
98 if (*endptr != '\0') return 0; /* invalid trailing characters? */ 167 if (endptr == s) return 0; /* nothing recognized */
99 return 1; 168 while (lisspace(cast_uchar(*endptr))) endptr++;
169 return (endptr == s + len); /* OK if no trailing characters */
100} 170}
101 171
102 172
103 173
104static void pushstr (lua_State *L, const char *str) { 174static void pushstr (lua_State *L, const char *str, size_t l) {
105 setsvalue2s(L, L->top, luaS_new(L, str)); 175 setsvalue2s(L, L->top++, luaS_newlstr(L, str, l));
106 incr_top(L);
107} 176}
108 177
109 178
110/* this function handles only `%d', `%c', %f, %p, and `%s' formats */ 179/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
111const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { 180const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
112 int n = 1; 181 int n = 0;
113 pushstr(L, "");
114 for (;;) { 182 for (;;) {
115 const char *e = strchr(fmt, '%'); 183 const char *e = strchr(fmt, '%');
116 if (e == NULL) break; 184 if (e == NULL) break;
117 setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); 185 luaD_checkstack(L, 2); /* fmt + item */
118 incr_top(L); 186 pushstr(L, fmt, e - fmt);
119 switch (*(e+1)) { 187 switch (*(e+1)) {
120 case 's': { 188 case 's': {
121 const char *s = va_arg(argp, char *); 189 const char *s = va_arg(argp, char *);
122 if (s == NULL) s = "(null)"; 190 if (s == NULL) s = "(null)";
123 pushstr(L, s); 191 pushstr(L, s, strlen(s));
124 break; 192 break;
125 } 193 }
126 case 'c': { 194 case 'c': {
127 char buff[2]; 195 char buff;
128 buff[0] = cast(char, va_arg(argp, int)); 196 buff = cast(char, va_arg(argp, int));
129 buff[1] = '\0'; 197 pushstr(L, &buff, 1);
130 pushstr(L, buff);
131 break; 198 break;
132 } 199 }
133 case 'd': { 200 case 'd': {
134 setnvalue(L->top, cast_num(va_arg(argp, int))); 201 setnvalue(L->top++, cast_num(va_arg(argp, int)));
135 incr_top(L);
136 break; 202 break;
137 } 203 }
138 case 'f': { 204 case 'f': {
139 setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); 205 setnvalue(L->top++, cast_num(va_arg(argp, l_uacNumber)));
140 incr_top(L);
141 break; 206 break;
142 } 207 }
143 case 'p': { 208 case 'p': {
144 char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ 209 char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
145 snprintf(buff, 4*sizeof(void *) + 8, "%p", va_arg(argp, void *)); 210 int l = snprintf(buff, sizeof(buff), "%p", va_arg(argp, void *));
146 pushstr(L, buff); 211 pushstr(L, buff, l);
147 break; 212 break;
148 } 213 }
149 case '%': { 214 case '%': {
150 pushstr(L, "%"); 215 pushstr(L, "%", 1);
151 break; 216 break;
152 } 217 }
153 default: { 218 default: {
154 char buff[3]; 219 luaG_runerror(L,
155 buff[0] = '%'; 220 "invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"),
156 buff[1] = *(e+1); 221 *(e + 1));
157 buff[2] = '\0';
158 pushstr(L, buff);
159 break;
160 } 222 }
161 } 223 }
162 n += 2; 224 n += 2;
163 fmt = e+2; 225 fmt = e+2;
164 } 226 }
165 pushstr(L, fmt); 227 luaD_checkstack(L, 1);
166 luaV_concat(L, n+1, cast_int(L->top - L->base) - 1); 228 pushstr(L, fmt, strlen(fmt));
167 L->top -= n; 229 if (n > 0) luaV_concat(L, n + 1);
168 return svalue(L->top - 1); 230 return svalue(L->top - 1);
169} 231}
170 232
@@ -179,36 +241,48 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
179} 241}
180 242
181 243
244/* number of chars of a literal string without the ending \0 */
245#define LL(x) (sizeof(x)/sizeof(char) - 1)
246
247#define RETS "..."
248#define PRE "[string \""
249#define POS "\"]"
250
251#define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) )
252
182void luaO_chunkid (char *out, const char *source, size_t bufflen) { 253void luaO_chunkid (char *out, const char *source, size_t bufflen) {
183 if (*source == '=') { 254 size_t l = strlen(source);
184 strncpy(out, source+1, bufflen); /* remove first char */ 255 if (*source == '=') { /* 'literal' source */
185 out[bufflen-1] = '\0'; /* ensures null termination */ 256 if (l <= bufflen) /* small enough? */
257 memcpy(out, source + 1, l * sizeof(char));
258 else { /* truncate it */
259 addstr(out, source + 1, bufflen - 1);
260 *out = '\0';
261 }
186 } 262 }
187 else { /* out = "source", or "...source" */ 263 else if (*source == '@') { /* file name */
188 if (*source == '@') { 264 if (l <= bufflen) /* small enough? */
189 size_t l; 265 memcpy(out, source + 1, l * sizeof(char));
190 source++; /* skip the `@' */ 266 else { /* add '...' before rest of name */
191 bufflen -= sizeof(" '...' "); 267 addstr(out, RETS, LL(RETS));
192 l = strlen(source); 268 bufflen -= LL(RETS);
193 strcpy(out, ""); 269 memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char));
194 if (l > bufflen) {
195 source += (l-bufflen); /* get last part of file name */
196 strcat(out, "...");
197 }
198 strcat(out, source);
199 } 270 }
200 else { /* out = [string "string"] */ 271 }
201 size_t len = strcspn(source, "\n\r"); /* stop at first newline */ 272 else { /* string; format as [string "source"] */
202 bufflen -= sizeof(" [string \"...\"] "); 273 const char *nl = strchr(source, '\n'); /* find first new line (if any) */
203 if (len > bufflen) len = bufflen; 274 addstr(out, PRE, LL(PRE)); /* add prefix */
204 strcpy(out, "[string \""); 275 bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */
205 if (source[len] != '\0') { /* must truncate? */ 276 if (l < bufflen && nl == NULL) { /* small one-line source? */
206 strncat(out, source, len); 277 addstr(out, source, l); /* keep it */
207 strcat(out, "...");
208 }
209 else
210 strcat(out, source);
211 strcat(out, "\"]");
212 } 278 }
279 else {
280 if (nl != NULL) l = nl - source; /* stop at first newline */
281 if (l > bufflen) l = bufflen;
282 addstr(out, source, l);
283 addstr(out, RETS, LL(RETS));
284 }
285 memcpy(out, POS, (LL(POS) + 1) * sizeof(char));
213 } 286 }
214} 287}
288
diff --git a/apps/plugins/lua/lobject.h b/apps/plugins/lua/lobject.h
index 93288fe0fb..3a630b944c 100644
--- a/apps/plugins/lua/lobject.h
+++ b/apps/plugins/lua/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: lobject.h,v 2.71.1.1 2013/04/12 18:48:47 roberto Exp $
3** Type definitions for Lua objects 3** Type definitions for Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -16,18 +16,52 @@
16#include "lua.h" 16#include "lua.h"
17 17
18 18
19/* tags for values visible from Lua */ 19/*
20#define LAST_TAG LUA_TTHREAD 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)
21 25
22#define NUM_TAGS (LAST_TAG+1) 26/*
27** number of all possible tags (including LUA_TNONE but excluding DEADKEY)
28*/
29#define LUA_TOTALTAGS (LUA_TUPVAL+2)
23 30
24 31
25/* 32/*
26** Extra tags for non-values 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
27*/ 37*/
28#define LUA_TPROTO (LAST_TAG+1) 38
29#define LUA_TUPVAL (LAST_TAG+2) 39#define VARBITS (3 << 4)
30#define LUA_TDEADKEY (LAST_TAG+3) 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)
31 65
32 66
33/* 67/*
@@ -52,120 +86,165 @@ typedef struct GCheader {
52 86
53 87
54 88
55
56/* 89/*
57** Union of all Lua values 90** Union of all Lua values
58*/ 91*/
59typedef union { 92typedef union Value Value;
60 GCObject *gc; 93
61 void *p; 94
62 lua_Number n; 95#define numfield lua_Number n; /* numbers */
63 int b; 96
64} Value;
65 97
66 98
67/* 99/*
68** Tagged Values 100** Tagged Values. This is the basic representation of values in Lua,
101** an actual value plus a tag with its type.
69*/ 102*/
70 103
71#define TValuefields Value value; int tt 104#define TValuefields Value value_; int tt_
72 105
73typedef struct lua_TValue { 106typedef struct lua_TValue TValue;
74 TValuefields; 107
75} TValue; 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)))
76 128
77 129
78/* Macros to test type */ 130/* Macros to test type */
79#define ttisnil(o) (ttype(o) == LUA_TNIL) 131#define checktag(o,t) (rttype(o) == (t))
80#define ttisnumber(o) (ttype(o) == LUA_TNUMBER) 132#define checktype(o,t) (ttypenv(o) == (t))
81#define ttisstring(o) (ttype(o) == LUA_TSTRING) 133#define ttisnumber(o) checktag((o), LUA_TNUMBER)
82#define ttistable(o) (ttype(o) == LUA_TTABLE) 134#define ttisnil(o) checktag((o), LUA_TNIL)
83#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION) 135#define ttisboolean(o) checktag((o), LUA_TBOOLEAN)
84#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) 136#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA)
85#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) 137#define ttisstring(o) checktype((o), LUA_TSTRING)
86#define ttisthread(o) (ttype(o) == LUA_TTHREAD) 138#define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR))
87#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) 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))
88 151
89/* Macros to access values */ 152/* Macros to access values */
90#define ttype(o) ((o)->tt) 153#define nvalue(o) check_exp(ttisnumber(o), num_(o))
91#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc) 154#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc)
92#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p) 155#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
93#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n) 156#define rawtsvalue(o) check_exp(ttisstring(o), &val_(o).gc->ts)
94#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
95#define tsvalue(o) (&rawtsvalue(o)->tsv) 157#define tsvalue(o) (&rawtsvalue(o)->tsv)
96#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u) 158#define rawuvalue(o) check_exp(ttisuserdata(o), &val_(o).gc->u)
97#define uvalue(o) (&rawuvalue(o)->uv) 159#define uvalue(o) (&rawuvalue(o)->uv)
98#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl) 160#define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl)
99#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h) 161#define clLvalue(o) check_exp(ttisLclosure(o), &val_(o).gc->cl.l)
100#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b) 162#define clCvalue(o) check_exp(ttisCclosure(o), &val_(o).gc->cl.c)
101#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th) 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))
102 169
103#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) 170#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
104 171
105/* 172
106** for internal debug only 173#define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE)
107*/ 174
108#define checkconsistency(obj) \ 175
109 lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt)) 176/* Macros for internal tests */
177#define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt)
110 178
111#define checkliveness(g,obj) \ 179#define checkliveness(g,obj) \
112 lua_assert(!iscollectable(obj) || \ 180 lua_longassert(!iscollectable(obj) || \
113 ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc))) 181 (righttt(obj) && !isdead(g,gcvalue(obj))))
114 182
115 183
116/* Macros to set values */ 184/* Macros to set values */
117#define setnilvalue(obj) ((obj)->tt=LUA_TNIL) 185#define settt_(o,t) ((o)->tt_=(t))
118 186
119#define setnvalue(obj,x) \ 187#define setnvalue(obj,x) \
120 { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; } 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); }
121 194
122#define setpvalue(obj,x) \ 195#define setpvalue(obj,x) \
123 { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; } 196 { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); }
124 197
125#define setbvalue(obj,x) \ 198#define setbvalue(obj,x) \
126 { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; } 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)); }
127 204
128#define setsvalue(L,obj,x) \ 205#define setsvalue(L,obj,x) \
129 { TValue *i_o=(obj); \ 206 { TValue *io=(obj); \
130 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \ 207 TString *x_ = (x); \
131 checkliveness(G(L),i_o); } 208 val_(io).gc=cast(GCObject *, x_); settt_(io, ctb(x_->tsv.tt)); \
209 checkliveness(G(L),io); }
132 210
133#define setuvalue(L,obj,x) \ 211#define setuvalue(L,obj,x) \
134 { TValue *i_o=(obj); \ 212 { TValue *io=(obj); \
135 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \ 213 val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TUSERDATA)); \
136 checkliveness(G(L),i_o); } 214 checkliveness(G(L),io); }
137 215
138#define setthvalue(L,obj,x) \ 216#define setthvalue(L,obj,x) \
139 { TValue *i_o=(obj); \ 217 { TValue *io=(obj); \
140 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \ 218 val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); \
141 checkliveness(G(L),i_o); } 219 checkliveness(G(L),io); }
142 220
143#define setclvalue(L,obj,x) \ 221#define setclLvalue(L,obj,x) \
144 { TValue *i_o=(obj); \ 222 { TValue *io=(obj); \
145 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \ 223 val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TLCL)); \
146 checkliveness(G(L),i_o); } 224 checkliveness(G(L),io); }
147 225
148#define sethvalue(L,obj,x) \ 226#define setclCvalue(L,obj,x) \
149 { TValue *i_o=(obj); \ 227 { TValue *io=(obj); \
150 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \ 228 val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TCCL)); \
151 checkliveness(G(L),i_o); } 229 checkliveness(G(L),io); }
152 230
153#define setptvalue(L,obj,x) \ 231#define sethvalue(L,obj,x) \
154 { TValue *i_o=(obj); \ 232 { TValue *io=(obj); \
155 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \ 233 val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTABLE)); \
156 checkliveness(G(L),i_o); } 234 checkliveness(G(L),io); }
157 235
236#define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY)
158 237
159 238
160 239
161#define setobj(L,obj1,obj2) \ 240#define setobj(L,obj1,obj2) \
162 { const TValue *o2=(obj2); TValue *o1=(obj1); \ 241 { const TValue *io2=(obj2); TValue *io1=(obj1); \
163 o1->value = o2->value; o1->tt=o2->tt; \ 242 io1->value_ = io2->value_; io1->tt_ = io2->tt_; \
164 checkliveness(G(L),o1); } 243 checkliveness(G(L),io1); }
165 244
166 245
167/* 246/*
168** different types of sets, according to destination 247** different types of assignments, according to destination
169*/ 248*/
170 249
171/* from stack to (same) stack */ 250/* from stack to (same) stack */
@@ -183,47 +262,204 @@ typedef struct lua_TValue {
183#define setobj2n setobj 262#define setobj2n setobj
184#define setsvalue2n setsvalue 263#define setsvalue2n setsvalue
185 264
186#define setttype(obj, tt) (ttype(obj) = (tt)) 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 /* } */
187 324
188 325
189#define iscollectable(o) (ttype(o) >= LUA_TSTRING) 326/* correspondence with standard representation */
327#undef val_
328#define val_(o) v_(o)
329#undef num_
330#define num_(o) d_(o)
190 331
191 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
192 401
193typedef TValue *StkId; /* index to stack elements */ 402typedef TValue *StkId; /* index to stack elements */
194 403
195 404
405
406
196/* 407/*
197** String headers for string table 408** Header for string value; string bytes follow the end of this structure
198*/ 409*/
199typedef union TString { 410typedef union TString {
200 L_Umaxalign dummy; /* ensures maximum alignment for strings */ 411 L_Umaxalign dummy; /* ensures maximum alignment for strings */
201 struct { 412 struct {
202 CommonHeader; 413 CommonHeader;
203 lu_byte reserved; 414 lu_byte extra; /* reserved words for short strings; "has hash" for longs */
204 unsigned int hash; 415 unsigned int hash;
205 size_t len; 416 size_t len; /* number of characters in string */
206 } tsv; 417 } tsv;
207} TString; 418} TString;
208 419
209 420
421/* get the actual string (array of bytes) from a TString */
210#define getstr(ts) cast(const char *, (ts) + 1) 422#define getstr(ts) cast(const char *, (ts) + 1)
211#define svalue(o) getstr(rawtsvalue(o))
212 423
424/* get the actual string (array of bytes) from a Lua value */
425#define svalue(o) getstr(rawtsvalue(o))
213 426
214 427
428/*
429** Header for userdata; memory area follows the end of this structure
430*/
215typedef union Udata { 431typedef union Udata {
216 L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ 432 L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
217 struct { 433 struct {
218 CommonHeader; 434 CommonHeader;
219 struct Table *metatable; 435 struct Table *metatable;
220 struct Table *env; 436 struct Table *env;
221 size_t len; 437 size_t len; /* number of bytes */
222 } uv; 438 } uv;
223} Udata; 439} Udata;
224 440
225 441
226 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
227 463
228/* 464/*
229** Function Prototypes 465** Function Prototypes
@@ -233,11 +469,12 @@ typedef struct Proto {
233 TValue *k; /* constants used by the function */ 469 TValue *k; /* constants used by the function */
234 Instruction *code; 470 Instruction *code;
235 struct Proto **p; /* functions defined inside the function */ 471 struct Proto **p; /* functions defined inside the function */
236 int *lineinfo; /* map from opcodes to source lines */ 472 int *lineinfo; /* map from opcodes to source lines (debug information) */
237 struct LocVar *locvars; /* information about local variables */ 473 LocVar *locvars; /* information about local variables (debug information) */
238 TString **upvalues; /* upvalue names */ 474 Upvaldesc *upvalues; /* upvalue information */
239 TString *source; 475 union Closure *cache; /* last created closure with this prototype */
240 int sizeupvalues; 476 TString *source; /* used for debug information */
477 int sizeupvalues; /* size of 'upvalues' */
241 int sizek; /* size of `k' */ 478 int sizek; /* size of `k' */
242 int sizecode; 479 int sizecode;
243 int sizelineinfo; 480 int sizelineinfo;
@@ -246,31 +483,16 @@ typedef struct Proto {
246 int linedefined; 483 int linedefined;
247 int lastlinedefined; 484 int lastlinedefined;
248 GCObject *gclist; 485 GCObject *gclist;
249 lu_byte nups; /* number of upvalues */ 486 lu_byte numparams; /* number of fixed parameters */
250 lu_byte numparams;
251 lu_byte is_vararg; 487 lu_byte is_vararg;
252 lu_byte maxstacksize; 488 lu_byte maxstacksize; /* maximum stack used by this function */
253} Proto; 489} Proto;
254 490
255 491
256/* masks for new-style vararg */
257#define VARARG_HASARG 1
258#define VARARG_ISVARARG 2
259#define VARARG_NEEDSARG 4
260
261
262typedef struct LocVar {
263 TString *varname;
264 int startpc; /* first point where variable is active */
265 int endpc; /* first point where variable is dead */
266} LocVar;
267
268
269 492
270/* 493/*
271** Upvalues 494** Lua Upvalues
272*/ 495*/
273
274typedef struct UpVal { 496typedef struct UpVal {
275 CommonHeader; 497 CommonHeader;
276 TValue *v; /* points to stack or to its own value */ 498 TValue *v; /* points to stack or to its own value */
@@ -289,20 +511,19 @@ typedef struct UpVal {
289*/ 511*/
290 512
291#define ClosureHeader \ 513#define ClosureHeader \
292 CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \ 514 CommonHeader; lu_byte nupvalues; GCObject *gclist
293 struct Table *env
294 515
295typedef struct CClosure { 516typedef struct CClosure {
296 ClosureHeader; 517 ClosureHeader;
297 lua_CFunction f; 518 lua_CFunction f;
298 TValue upvalue[1]; 519 TValue upvalue[1]; /* list of upvalues */
299} CClosure; 520} CClosure;
300 521
301 522
302typedef struct LClosure { 523typedef struct LClosure {
303 ClosureHeader; 524 ClosureHeader;
304 struct Proto *p; 525 struct Proto *p;
305 UpVal *upvals[1]; 526 UpVal *upvals[1]; /* list of upvalues */
306} LClosure; 527} LClosure;
307 528
308 529
@@ -312,8 +533,9 @@ typedef union Closure {
312} Closure; 533} Closure;
313 534
314 535
315#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC) 536#define isLfunction(o) ttisLclosure(o)
316#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC) 537
538#define getproto(o) (clLvalue(o)->p)
317 539
318 540
319/* 541/*
@@ -337,7 +559,7 @@ typedef struct Node {
337 559
338typedef struct Table { 560typedef struct Table {
339 CommonHeader; 561 CommonHeader;
340 lu_byte flags; /* 1<<p means tagmethod(p) is not present */ 562 lu_byte flags; /* 1<<p means tagmethod(p) is not present */
341 lu_byte lsizenode; /* log2 of size of `node' array */ 563 lu_byte lsizenode; /* log2 of size of `node' array */
342 struct Table *metatable; 564 struct Table *metatable;
343 TValue *array; /* array part */ 565 TValue *array; /* array part */
@@ -360,17 +582,21 @@ typedef struct Table {
360#define sizenode(t) (twoto((t)->lsizenode)) 582#define sizenode(t) (twoto((t)->lsizenode))
361 583
362 584
585/*
586** (address of) a fixed nil value
587*/
363#define luaO_nilobject (&luaO_nilobject_) 588#define luaO_nilobject (&luaO_nilobject_)
364 589
365LUAI_DATA const TValue luaO_nilobject_;
366 590
367#define ceillog2(x) (luaO_log2((x)-1) + 1) 591LUAI_DDEC const TValue luaO_nilobject_;
592
368 593
369LUAI_FUNC int luaO_log2 (unsigned int x);
370LUAI_FUNC int luaO_int2fb (unsigned int x); 594LUAI_FUNC int luaO_int2fb (unsigned int x);
371LUAI_FUNC int luaO_fb2int (int x); 595LUAI_FUNC int luaO_fb2int (int x);
372LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2); 596LUAI_FUNC int luaO_ceillog2 (unsigned int x);
373LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result); 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);
374LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, 600LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
375 va_list argp); 601 va_list argp);
376LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); 602LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
diff --git a/apps/plugins/lua/lopcodes.c b/apps/plugins/lua/lopcodes.c
index 4cc745230b..4190dc7624 100644
--- a/apps/plugins/lua/lopcodes.c
+++ b/apps/plugins/lua/lopcodes.c
@@ -1,5 +1,6 @@
1/* 1/*
2** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ 2** $Id: lopcodes.c,v 1.49.1.1 2013/04/12 18:48:47 roberto Exp $
3** Opcodes for Lua virtual machine
3** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
4*/ 5*/
5 6
@@ -13,15 +14,16 @@
13 14
14/* ORDER OP */ 15/* ORDER OP */
15 16
16const char *const luaP_opnames[NUM_OPCODES+1] = { 17LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
17 "MOVE", 18 "MOVE",
18 "LOADK", 19 "LOADK",
20 "LOADKX",
19 "LOADBOOL", 21 "LOADBOOL",
20 "LOADNIL", 22 "LOADNIL",
21 "GETUPVAL", 23 "GETUPVAL",
22 "GETGLOBAL", 24 "GETTABUP",
23 "GETTABLE", 25 "GETTABLE",
24 "SETGLOBAL", 26 "SETTABUP",
25 "SETUPVAL", 27 "SETUPVAL",
26 "SETTABLE", 28 "SETTABLE",
27 "NEWTABLE", 29 "NEWTABLE",
@@ -47,27 +49,29 @@ const char *const luaP_opnames[NUM_OPCODES+1] = {
47 "RETURN", 49 "RETURN",
48 "FORLOOP", 50 "FORLOOP",
49 "FORPREP", 51 "FORPREP",
52 "TFORCALL",
50 "TFORLOOP", 53 "TFORLOOP",
51 "SETLIST", 54 "SETLIST",
52 "CLOSE",
53 "CLOSURE", 55 "CLOSURE",
54 "VARARG", 56 "VARARG",
57 "EXTRAARG",
55 NULL 58 NULL
56}; 59};
57 60
58 61
59#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) 62#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
60 63
61const lu_byte luaP_opmodes[NUM_OPCODES] = { 64LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
62/* T A B C mode opcode */ 65/* T A B C mode opcode */
63 opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ 66 opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
64 ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ 67 ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
68 ,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */
65 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ 69 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
66 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ 70 ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */
67 ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ 71 ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
68 ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ 72 ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */
69 ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ 73 ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
70 ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ 74 ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */
71 ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ 75 ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
72 ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ 76 ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
73 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ 77 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
@@ -86,17 +90,18 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
86 ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ 90 ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
87 ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ 91 ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
88 ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ 92 ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
89 ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */ 93 ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */
90 ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ 94 ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
91 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ 95 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
92 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ 96 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
93 ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ 97 ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
94 ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ 98 ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
95 ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ 99 ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
96 ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ 100 ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */
101 ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */
97 ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ 102 ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
98 ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
99 ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ 103 ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
100 ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ 104 ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
105 ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */
101}; 106};
102 107
diff --git a/apps/plugins/lua/lopcodes.h b/apps/plugins/lua/lopcodes.h
index e1aed0f637..51f5791545 100644
--- a/apps/plugins/lua/lopcodes.h
+++ b/apps/plugins/lua/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: lopcodes.h,v 1.142.1.1 2013/04/12 18:48:47 roberto Exp $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -17,6 +17,7 @@
17 `A' : 8 bits 17 `A' : 8 bits
18 `B' : 9 bits 18 `B' : 9 bits
19 `C' : 9 bits 19 `C' : 9 bits
20 'Ax' : 26 bits ('A', 'B', and 'C' together)
20 `Bx' : 18 bits (`B' and `C' together) 21 `Bx' : 18 bits (`B' and `C' together)
21 `sBx' : signed Bx 22 `sBx' : signed Bx
22 23
@@ -28,7 +29,7 @@
28===========================================================================*/ 29===========================================================================*/
29 30
30 31
31enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ 32enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */
32 33
33 34
34/* 35/*
@@ -38,6 +39,7 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
38#define SIZE_B 9 39#define SIZE_B 9
39#define SIZE_Bx (SIZE_C + SIZE_B) 40#define SIZE_Bx (SIZE_C + SIZE_B)
40#define SIZE_A 8 41#define SIZE_A 8
42#define SIZE_Ax (SIZE_C + SIZE_B + SIZE_A)
41 43
42#define SIZE_OP 6 44#define SIZE_OP 6
43 45
@@ -46,6 +48,7 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
46#define POS_C (POS_A + SIZE_A) 48#define POS_C (POS_A + SIZE_A)
47#define POS_B (POS_C + SIZE_C) 49#define POS_B (POS_C + SIZE_C)
48#define POS_Bx POS_C 50#define POS_Bx POS_C
51#define POS_Ax POS_A
49 52
50 53
51/* 54/*
@@ -61,6 +64,12 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
61#define MAXARG_sBx MAX_INT 64#define MAXARG_sBx MAX_INT
62#endif 65#endif
63 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
64 73
65#define MAXARG_A ((1<<SIZE_A)-1) 74#define MAXARG_A ((1<<SIZE_A)-1)
66#define MAXARG_B ((1<<SIZE_B)-1) 75#define MAXARG_B ((1<<SIZE_B)-1)
@@ -68,7 +77,7 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
68 77
69 78
70/* creates a mask with `n' 1 bits at position `p' */ 79/* creates a mask with `n' 1 bits at position `p' */
71#define MASK1(n,p) ((~((~(Instruction)0)<<n))<<p) 80#define MASK1(n,p) ((~((~(Instruction)0)<<(n)))<<(p))
72 81
73/* creates a mask with `n' 0 bits at position `p' */ 82/* creates a mask with `n' 0 bits at position `p' */
74#define MASK0(n,p) (~MASK1(n,p)) 83#define MASK0(n,p) (~MASK1(n,p))
@@ -81,21 +90,24 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
81#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ 90#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
82 ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP)))) 91 ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
83 92
84#define GETARG_A(i) (cast(int, ((i)>>POS_A) & MASK1(SIZE_A,0))) 93#define getarg(i,pos,size) (cast(int, ((i)>>pos) & MASK1(size,0)))
85#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ 94#define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \
86 ((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A)))) 95 ((cast(Instruction, v)<<pos)&MASK1(size,pos))))
87 96
88#define GETARG_B(i) (cast(int, ((i)>>POS_B) & MASK1(SIZE_B,0))) 97#define GETARG_A(i) getarg(i, POS_A, SIZE_A)
89#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ 98#define SETARG_A(i,v) setarg(i, v, POS_A, SIZE_A)
90 ((cast(Instruction, b)<<POS_B)&MASK1(SIZE_B,POS_B))))
91 99
92#define GETARG_C(i) (cast(int, ((i)>>POS_C) & MASK1(SIZE_C,0))) 100#define GETARG_B(i) getarg(i, POS_B, SIZE_B)
93#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \ 101#define SETARG_B(i,v) setarg(i, v, POS_B, SIZE_B)
94 ((cast(Instruction, b)<<POS_C)&MASK1(SIZE_C,POS_C))))
95 102
96#define GETARG_Bx(i) (cast(int, ((i)>>POS_Bx) & MASK1(SIZE_Bx,0))) 103#define GETARG_C(i) getarg(i, POS_C, SIZE_C)
97#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \ 104#define SETARG_C(i,v) setarg(i, v, POS_C, SIZE_C)
98 ((cast(Instruction, b)<<POS_Bx)&MASK1(SIZE_Bx,POS_Bx)))) 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)
99 111
100#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx) 112#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
101#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx)) 113#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
@@ -110,6 +122,9 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
110 | (cast(Instruction, a)<<POS_A) \ 122 | (cast(Instruction, a)<<POS_A) \
111 | (cast(Instruction, bc)<<POS_Bx)) 123 | (cast(Instruction, bc)<<POS_Bx))
112 124
125#define CREATE_Ax(o,a) ((cast(Instruction, o)<<POS_OP) \
126 | (cast(Instruction, a)<<POS_Ax))
127
113 128
114/* 129/*
115** Macros to operate RK indices 130** Macros to operate RK indices
@@ -153,14 +168,15 @@ name args description
153------------------------------------------------------------------------*/ 168------------------------------------------------------------------------*/
154OP_MOVE,/* A B R(A) := R(B) */ 169OP_MOVE,/* A B R(A) := R(B) */
155OP_LOADK,/* A Bx R(A) := Kst(Bx) */ 170OP_LOADK,/* A Bx R(A) := Kst(Bx) */
171OP_LOADKX,/* A R(A) := Kst(extra arg) */
156OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */ 172OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */
157OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */ 173OP_LOADNIL,/* A B R(A), R(A+1), ..., R(A+B) := nil */
158OP_GETUPVAL,/* A B R(A) := UpValue[B] */ 174OP_GETUPVAL,/* A B R(A) := UpValue[B] */
159 175
160OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */ 176OP_GETTABUP,/* A B C R(A) := UpValue[B][RK(C)] */
161OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */ 177OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
162 178
163OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */ 179OP_SETTABUP,/* A B C UpValue[A][RK(B)] := RK(C) */
164OP_SETUPVAL,/* A B UpValue[B] := R(A) */ 180OP_SETUPVAL,/* A B UpValue[B] := R(A) */
165OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */ 181OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
166 182
@@ -180,14 +196,13 @@ OP_LEN,/* A B R(A) := length of R(B) */
180 196
181OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */ 197OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
182 198
183OP_JMP,/* sBx pc+=sBx */ 199OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A) + 1 */
184
185OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ 200OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
186OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ 201OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
187OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ 202OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
188 203
189OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ 204OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
190OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ 205OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
191 206
192OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ 207OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
193OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ 208OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
@@ -197,39 +212,44 @@ OP_FORLOOP,/* A sBx R(A)+=R(A+2);
197 if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/ 212 if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
198OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */ 213OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
199 214
200OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); 215OP_TFORCALL,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
201 if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */ 216OP_TFORLOOP,/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/
217
202OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */ 218OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
203 219
204OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ 220OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */
205OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ 221
222OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-2) = vararg */
206 223
207OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ 224OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
208} OpCode; 225} OpCode;
209 226
210 227
211#define NUM_OPCODES (cast(int, OP_VARARG) + 1) 228#define NUM_OPCODES (cast(int, OP_EXTRAARG) + 1)
212 229
213 230
214 231
215/*=========================================================================== 232/*===========================================================================
216 Notes: 233 Notes:
217 (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, 234 (*) In OP_CALL, if (B == 0) then B = top. If (C == 0), then `top' is
218 and can be 0: OP_CALL then sets `top' to last_result+1, so 235 set to last_result+1, so next open instruction (OP_CALL, OP_RETURN,
219 next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. 236 OP_SETLIST) may use `top'.
220 237
221 (*) In OP_VARARG, if (B == 0) then use actual number of varargs and 238 (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
222 set top (like in OP_CALL with C == 0). 239 set top (like in OP_CALL with C == 0).
223 240
224 (*) In OP_RETURN, if (B == 0) then return up to `top' 241 (*) In OP_RETURN, if (B == 0) then return up to `top'.
225 242
226 (*) In OP_SETLIST, if (B == 0) then B = `top'; 243 (*) In OP_SETLIST, if (B == 0) then B = `top'; if (C == 0) then next
227 if (C == 0) then next `instruction' is real C 244 'instruction' is EXTRAARG(real C).
245
246 (*) In OP_LOADKX, the next 'instruction' is always EXTRAARG.
228 247
229 (*) For comparisons, A specifies what condition the test should accept 248 (*) For comparisons, A specifies what condition the test should accept
230 (true or false). 249 (true or false).
250
251 (*) All `skips' (pc++) assume that next instruction is a jump.
231 252
232 (*) All `skips' (pc++) assume that next instruction is a jump
233===========================================================================*/ 253===========================================================================*/
234 254
235 255
@@ -239,8 +259,8 @@ OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
239** bits 2-3: C arg mode 259** bits 2-3: C arg mode
240** bits 4-5: B arg mode 260** bits 4-5: B arg mode
241** bit 6: instruction set register A 261** bit 6: instruction set register A
242** bit 7: operator is a test 262** bit 7: operator is a test (next instruction must be a jump)
243*/ 263*/
244 264
245enum OpArgMask { 265enum OpArgMask {
246 OpArgN, /* argument is not used */ 266 OpArgN, /* argument is not used */
@@ -249,7 +269,7 @@ enum OpArgMask {
249 OpArgK /* argument is a constant or register/constant */ 269 OpArgK /* argument is a constant or register/constant */
250}; 270};
251 271
252LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES]; 272LUAI_DDEC const lu_byte luaP_opmodes[NUM_OPCODES];
253 273
254#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) 274#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
255#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3)) 275#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
@@ -258,7 +278,7 @@ LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];
258#define testTMode(m) (luaP_opmodes[m] & (1 << 7)) 278#define testTMode(m) (luaP_opmodes[m] & (1 << 7))
259 279
260 280
261LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ 281LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */
262 282
263 283
264/* number of list items to accumulate before a SETLIST instruction */ 284/* number of list items to accumulate before a SETLIST instruction */
diff --git a/apps/plugins/lua/loslib.c b/apps/plugins/lua/loslib.c
index 6cb8c0541b..350e848d38 100644
--- a/apps/plugins/lua/loslib.c
+++ b/apps/plugins/lua/loslib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $ 2** $Id: loslib.c,v 1.40.1.1 2013/04/12 18:48:47 roberto Exp $
3** Standard Operating System library 3** Standard Operating System library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -19,31 +19,109 @@
19#include "lualib.h" 19#include "lualib.h"
20 20
21 21
22static int os_pushresult (lua_State *L, int i, const char *filename) { 22/*
23 int en = errno; /* calls to Lua API may change this value */ 23** list of valid conversion specifiers for the 'strftime' function
24 if (i) { 24*/
25 lua_pushboolean(L, 1); 25#if !defined(LUA_STRFTIMEOPTIONS)
26 return 1; 26
27 } 27#if !defined(LUA_USE_POSIX)
28#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" }
29#else
30#define LUA_STRFTIMEOPTIONS \
31 { "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "" \
32 "", "E", "cCxXyY", \
33 "O", "deHImMSuUVwWy" }
34#endif
35
36#endif
37
38
39
40/*
41** By default, Lua uses tmpnam except when POSIX is available, where it
42** uses mkstemp.
43*/
44#if defined(LUA_USE_MKSTEMP)
45#include <unistd.h>
46#define LUA_TMPNAMBUFSIZE 32
47#define lua_tmpnam(b,e) { \
48 strcpy(b, "/tmp/lua_XXXXXX"); \
49 e = mkstemp(b); \
50 if (e != -1) close(e); \
51 e = (e == -1); }
52
53#elif !defined(lua_tmpnam)
54
55#define LUA_TMPNAMBUFSIZE L_tmpnam
56#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
57
58#endif
59
60
61/*
62** By default, Lua uses gmtime/localtime, except when POSIX is available,
63** where it uses gmtime_r/localtime_r
64*/
65#if defined(LUA_USE_GMTIME_R)
66
67#define l_gmtime(t,r) gmtime_r(t,r)
68#define l_localtime(t,r) localtime_r(t,r)
69
70#elif !defined(l_gmtime)
71
72#define l_gmtime(t,r) ((void)r, gmtime(t))
73#define l_localtime(t,r) ((void)r, localtime(t))
74
75#endif
76
77
78
79static int os_execute (lua_State *L) {
80 const char *cmd = luaL_optstring(L, 1, NULL);
81 int stat = -1;
82 if (cmd != NULL)
83 return luaL_execresult(L, stat);
28 else { 84 else {
29 lua_pushnil(L); 85 lua_pushboolean(L, stat); /* true if there is a shell */
30 lua_pushfstring(L, "%s: %s", filename, strerror(en)); 86 return 1;
31 lua_pushinteger(L, en);
32 return 3;
33 } 87 }
34} 88}
35 89
36 90
37static int os_remove (lua_State *L) { 91static int os_remove (lua_State *L) {
38 const char *filename = luaL_checkstring(L, 1); 92 const char *filename = luaL_checkstring(L, 1);
39 return os_pushresult(L, rb->remove(filename) == 0, filename); 93 return luaL_fileresult(L, rb->remove(filename) == 0, filename);
40} 94}
41 95
42 96
43static int os_rename (lua_State *L) { 97static int os_rename (lua_State *L) {
44 const char *fromname = luaL_checkstring(L, 1); 98 const char *fromname = luaL_checkstring(L, 1);
45 const char *toname = luaL_checkstring(L, 2); 99 const char *toname = luaL_checkstring(L, 2);
46 return os_pushresult(L, rb->rename(fromname, toname) == 0, fromname); 100 return luaL_fileresult(L, rb->rename(fromname, toname) == 0, NULL);
101}
102
103#if 0
104static int os_tmpname (lua_State *L) {
105 char buff[LUA_TMPNAMBUFSIZE];
106 int err;
107 lua_tmpnam(buff, err);
108 if (err)
109 return luaL_error(L, "unable to generate a unique filename");
110 lua_pushstring(L, buff);
111 return 1;
112}
113#endif
114
115
116static int os_getenv (lua_State *L) {
117 lua_pushnil(L);
118 return 1;
119}
120
121
122static int os_clock (lua_State *L) {
123 lua_pushnumber(L, 0);
124 return 1;
47} 125}
48 126
49 127
@@ -67,7 +145,6 @@ static void setboolfield (lua_State *L, const char *key, int value) {
67 lua_setfield(L, -2, key); 145 lua_setfield(L, -2, key);
68} 146}
69 147
70#if CONFIG_RTC
71static int getboolfield (lua_State *L, const char *key) { 148static int getboolfield (lua_State *L, const char *key) {
72 int res; 149 int res;
73 lua_getfield(L, -1, key); 150 lua_getfield(L, -1, key);
@@ -78,11 +155,10 @@ static int getboolfield (lua_State *L, const char *key) {
78 155
79 156
80static int getfield (lua_State *L, const char *key, int d) { 157static int getfield (lua_State *L, const char *key, int d) {
81 int res; 158 int res, isnum;
82 lua_getfield(L, -1, key); 159 lua_getfield(L, -1, key);
83 if (lua_isnumber(L, -1)) 160 res = (int)lua_tointegerx(L, -1, &isnum);
84 res = (int)lua_tointeger(L, -1); 161 if (!isnum) {
85 else {
86 if (d < 0) 162 if (d < 0)
87 return luaL_error(L, "field " LUA_QS " missing in date table", key); 163 return luaL_error(L, "field " LUA_QS " missing in date table", key);
88 res = d; 164 res = d;
@@ -90,22 +166,42 @@ static int getfield (lua_State *L, const char *key, int d) {
90 lua_pop(L, 1); 166 lua_pop(L, 1);
91 return res; 167 return res;
92} 168}
93#endif 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}
94 193
95 194
96static int os_date (lua_State *L) { 195static int os_date (lua_State *L) {
97 const char *s = luaL_optstring(L, 1, "%c"); 196 const char *s = luaL_optstring(L, 1, "%c");
98 time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, 197 time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
99#if CONFIG_RTC 198 struct tm tmr, *stm;
100 rb->mktime(rb->get_time()) 199 if (*s == '!') { /* UTC? */
101#else 200 stm = l_gmtime(&t, &tmr);
102 0
103#endif
104 );
105 struct tm *stm;
106 if (*s == '!') /* UTC? */ /* Rockbox doesn't support timezones */
107 s++; /* skip `!' */ 201 s++; /* skip `!' */
108 stm = gmtime(&t); 202 }
203 else
204 stm = l_localtime(&t, &tmr);
109 if (stm == NULL) /* invalid date? */ 205 if (stm == NULL) /* invalid date? */
110 lua_pushnil(L); 206 lua_pushnil(L);
111 else if (strcmp(s, "*t") == 0) { 207 else if (strcmp(s, "*t") == 0) {
@@ -121,17 +217,17 @@ static int os_date (lua_State *L) {
121 setboolfield(L, "isdst", stm->tm_isdst); 217 setboolfield(L, "isdst", stm->tm_isdst);
122 } 218 }
123 else { 219 else {
124 char cc[3]; 220 char cc[4];
125 luaL_Buffer b; 221 luaL_Buffer b;
126 cc[0] = '%'; cc[2] = '\0'; 222 cc[0] = '%';
127 luaL_buffinit(L, &b); 223 luaL_buffinit(L, &b);
128 for (; *s; s++) { 224 while (*s) {
129 if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */ 225 if (*s != '%') /* no conversion specifier? */
130 luaL_addchar(&b, *s); 226 luaL_addchar(&b, *s++);
131 else { 227 else {
132 size_t reslen; 228 size_t reslen;
133 char buff[200]; /* should be big enough for any conversion result */ 229 char buff[200]; /* should be big enough for any conversion result */
134 cc[1] = *(++s); 230 s = checkoption(L, s + 1, cc);
135 reslen = strftime(buff, sizeof(buff), cc, stm); 231 reslen = strftime(buff, sizeof(buff), cc, stm);
136 luaL_addlstring(&b, buff, reslen); 232 luaL_addlstring(&b, buff, reslen);
137 } 233 }
@@ -141,11 +237,11 @@ static int os_date (lua_State *L) {
141 return 1; 237 return 1;
142} 238}
143 239
240
144static int os_time (lua_State *L) { 241static int os_time (lua_State *L) {
145 time_t t = -1; 242 time_t t;
146#if CONFIG_RTC
147 if (lua_isnoneornil(L, 1)) /* called without args? */ 243 if (lua_isnoneornil(L, 1)) /* called without args? */
148 t = rb->mktime(rb->get_time()); /* get current time */ 244 t = time(NULL); /* get current time */
149 else { 245 else {
150 struct tm ts; 246 struct tm ts;
151 luaL_checktype(L, 1, LUA_TTABLE); 247 luaL_checktype(L, 1, LUA_TTABLE);
@@ -157,9 +253,8 @@ static int os_time (lua_State *L) {
157 ts.tm_mon = getfield(L, "month", -1) - 1; 253 ts.tm_mon = getfield(L, "month", -1) - 1;
158 ts.tm_year = getfield(L, "year", -1) - 1900; 254 ts.tm_year = getfield(L, "year", -1) - 1900;
159 ts.tm_isdst = getboolfield(L, "isdst"); 255 ts.tm_isdst = getboolfield(L, "isdst");
160 t = rb->mktime(&ts); 256 t = mktime(&ts);
161 } 257 }
162#endif
163 if (t == (time_t)(-1)) 258 if (t == (time_t)(-1))
164 lua_pushnil(L); 259 lua_pushnil(L);
165 else 260 else
@@ -168,26 +263,54 @@ static int os_time (lua_State *L) {
168} 263}
169 264
170 265
266static int os_difftime (lua_State *L) {
267 lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
268 (time_t)(luaL_optnumber(L, 2, 0))));
269 return 1;
270}
271
171/* }====================================================== */ 272/* }====================================================== */
172 273
173 274
275#if 0
276static int os_setlocale (lua_State *L) {
277 static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
278 LC_NUMERIC, LC_TIME};
279 static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
280 "numeric", "time", NULL};
281 const char *l = luaL_optstring(L, 1, NULL);
282 int op = luaL_checkoption(L, 2, "all", catnames);
283 lua_pushstring(L, setlocale(cat[op], l));
284 return 1;
285}
286#endif
287
288
174static int os_exit (lua_State *L) { 289static int os_exit (lua_State *L) {
175 exit(luaL_optint(L, 1, EXIT_SUCCESS)); 290 int status;
176 return EXIT_SUCCESS; /* never reached, surpress warning */ 291 if (lua_isboolean(L, 1))
292 status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE);
293 else
294 status = luaL_optint(L, 1, EXIT_SUCCESS);
295 if (lua_toboolean(L, 2))
296 lua_close(L);
297 if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */
298 return 0;
177} 299}
178 300
301
179static const luaL_Reg syslib[] = { 302static const luaL_Reg syslib[] = {
180 //{"clock", os_clock}, 303 {"clock", os_clock},
181 {"date", os_date}, 304 {"date", os_date},
182 //{"difftime", os_difftime}, 305 {"difftime", os_difftime},
183 //{"execute", os_execute}, 306 {"execute", os_execute},
184 {"exit", os_exit}, 307 {"exit", os_exit},
185 //{"getenv", os_getenv}, 308 {"getenv", os_getenv},
186 {"remove", os_remove}, 309 {"remove", os_remove},
187 {"rename", os_rename}, 310 {"rename", os_rename},
188 //{"setlocale", os_setlocale}, 311 /*{"setlocale", os_setlocale},*/
189 {"time", os_time}, 312 {"time", os_time},
190 //{"tmpname", os_tmpname}, 313 /*{"tmpname", os_tmpname},*/
191 {NULL, NULL} 314 {NULL, NULL}
192}; 315};
193 316
@@ -195,8 +318,8 @@ static const luaL_Reg syslib[] = {
195 318
196 319
197 320
198LUALIB_API int luaopen_os (lua_State *L) { 321LUAMOD_API int luaopen_os (lua_State *L) {
199 luaL_register(L, LUA_OSLIBNAME, syslib); 322 luaL_newlib(L, syslib);
200 return 1; 323 return 1;
201} 324}
202 325
diff --git a/apps/plugins/lua/lparser.c b/apps/plugins/lua/lparser.c
index 800cdb1a3b..9e1a9ca2cf 100644
--- a/apps/plugins/lua/lparser.c
+++ b/apps/plugins/lua/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $ 2** $Id: lparser.c,v 2.130.1.1 2013/04/12 18:48:47 roberto Exp $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -27,11 +27,13 @@
27 27
28 28
29 29
30#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) 30/* maximum number of local variables per function (must be smaller
31 than 250, due to the bytecode format) */
32#define MAXVARS 200
33
31 34
32#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) 35#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
33 36
34#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m)
35 37
36 38
37/* 39/*
@@ -39,10 +41,11 @@
39*/ 41*/
40typedef struct BlockCnt { 42typedef struct BlockCnt {
41 struct BlockCnt *previous; /* chain */ 43 struct BlockCnt *previous; /* chain */
42 int breaklist; /* list of jumps out of this loop */ 44 short firstlabel; /* index of first label in this block */
43 lu_byte nactvar; /* # active locals outside the breakable structure */ 45 short firstgoto; /* index of first pending goto in this block */
46 lu_byte nactvar; /* # active locals outside the block */
44 lu_byte upval; /* true if some variable in the block is an upvalue */ 47 lu_byte upval; /* true if some variable in the block is an upvalue */
45 lu_byte isbreakable; /* true if `block' is a loop */ 48 lu_byte isloop; /* true if `block' is a loop */
46} BlockCnt; 49} BlockCnt;
47 50
48 51
@@ -50,11 +53,13 @@ typedef struct BlockCnt {
50/* 53/*
51** prototypes for recursive non-terminal functions 54** prototypes for recursive non-terminal functions
52*/ 55*/
53static void chunk (LexState *ls); 56static void statement (LexState *ls);
54static void expr (LexState *ls, expdesc *v); 57static void expr (LexState *ls, expdesc *v);
55 58
56 59
57static void anchor_token (LexState *ls) { 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);
58 if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) { 63 if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
59 TString *ts = ls->t.seminfo.ts; 64 TString *ts = ls->t.seminfo.ts;
60 luaX_newstring(ls, getstr(ts), ts->tsv.len); 65 luaX_newstring(ls, getstr(ts), ts->tsv.len);
@@ -62,18 +67,34 @@ static void anchor_token (LexState *ls) {
62} 67}
63 68
64 69
65static void error_expected (LexState *ls, int token) { 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) {
66 luaX_syntaxerror(ls, 78 luaX_syntaxerror(ls,
67 luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token))); 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);
68} 93}
69 94
70 95
71static void errorlimit (FuncState *fs, int limit, const char *what) { 96static void checklimit (FuncState *fs, int v, int l, const char *what) {
72 const char *msg = (fs->f->linedefined == 0) ? 97 if (v > l) errorlimit(fs, l, what);
73 luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) :
74 luaO_pushfstring(fs->L, "function at line %d has more than %d %s",
75 fs->f->linedefined, limit, what);
76 luaX_lexerror(fs->ls, msg, 0);
77} 98}
78 99
79 100
@@ -91,6 +112,7 @@ static void check (LexState *ls, int c) {
91 error_expected(ls, c); 112 error_expected(ls, c);
92} 113}
93 114
115
94static void checknext (LexState *ls, int c) { 116static void checknext (LexState *ls, int c) {
95 check(ls, c); 117 check(ls, c);
96 luaX_next(ls); 118 luaX_next(ls);
@@ -107,7 +129,7 @@ static void check_match (LexState *ls, int what, int who, int where) {
107 error_expected(ls, what); 129 error_expected(ls, what);
108 else { 130 else {
109 luaX_syntaxerror(ls, luaO_pushfstring(ls->L, 131 luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
110 LUA_QS " expected (to close " LUA_QS " at line %d)", 132 "%s expected (to close %s at line %d)",
111 luaX_token2str(ls, what), luaX_token2str(ls, who), where)); 133 luaX_token2str(ls, what), luaX_token2str(ls, who), where));
112 } 134 }
113 } 135 }
@@ -126,7 +148,7 @@ static TString *str_checkname (LexState *ls) {
126static void init_exp (expdesc *e, expkind k, int i) { 148static void init_exp (expdesc *e, expkind k, int i) {
127 e->f = e->t = NO_JUMP; 149 e->f = e->t = NO_JUMP;
128 e->k = k; 150 e->k = k;
129 e->u.s.info = i; 151 e->u.info = i;
130} 152}
131 153
132 154
@@ -135,7 +157,7 @@ static void codestring (LexState *ls, expdesc *e, TString *s) {
135} 157}
136 158
137 159
138static void checkname(LexState *ls, expdesc *e) { 160static void checkname (LexState *ls, expdesc *e) {
139 codestring(ls, e, str_checkname(ls)); 161 codestring(ls, e, str_checkname(ls));
140} 162}
141 163
@@ -145,7 +167,7 @@ static int registerlocalvar (LexState *ls, TString *varname) {
145 Proto *f = fs->f; 167 Proto *f = fs->f;
146 int oldsize = f->sizelocvars; 168 int oldsize = f->sizelocvars;
147 luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, 169 luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
148 LocVar, SHRT_MAX, "too many local variables"); 170 LocVar, SHRT_MAX, "local variables");
149 while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; 171 while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
150 f->locvars[fs->nlocvars].varname = varname; 172 f->locvars[fs->nlocvars].varname = varname;
151 luaC_objbarrier(ls->L, f, varname); 173 luaC_objbarrier(ls->L, f, varname);
@@ -153,14 +175,30 @@ static int registerlocalvar (LexState *ls, TString *varname) {
153} 175}
154 176
155 177
156#define new_localvarliteral(ls,v,n) \ 178static void new_localvar (LexState *ls, TString *name) {
157 new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n) 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}
158 188
159 189
160static void new_localvar (LexState *ls, TString *name, int n) { 190static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) {
161 FuncState *fs = ls->fs; 191 new_localvar(ls, luaX_newstring(ls, name, sz));
162 luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables"); 192}
163 fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name)); 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];
164} 202}
165 203
166 204
@@ -168,77 +206,88 @@ static void adjustlocalvars (LexState *ls, int nvars) {
168 FuncState *fs = ls->fs; 206 FuncState *fs = ls->fs;
169 fs->nactvar = cast_byte(fs->nactvar + nvars); 207 fs->nactvar = cast_byte(fs->nactvar + nvars);
170 for (; nvars; nvars--) { 208 for (; nvars; nvars--) {
171 getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; 209 getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc;
172 } 210 }
173} 211}
174 212
175 213
176static void removevars (LexState *ls, int tolevel) { 214static void removevars (FuncState *fs, int tolevel) {
177 FuncState *fs = ls->fs; 215 fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel);
178 while (fs->nactvar > tolevel) 216 while (fs->nactvar > tolevel)
179 getlocvar(fs, --fs->nactvar).endpc = fs->pc; 217 getlocvar(fs, --fs->nactvar)->endpc = fs->pc;
180} 218}
181 219
182 220
183static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { 221static int searchupvalue (FuncState *fs, TString *name) {
184 int i; 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) {
185 Proto *f = fs->f; 232 Proto *f = fs->f;
186 int oldsize = f->sizeupvalues; 233 int oldsize = f->sizeupvalues;
187 for (i=0; i<f->nups; i++) { 234 checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
188 if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) { 235 luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
189 lua_assert(f->upvalues[i] == name); 236 Upvaldesc, MAXUPVAL, "upvalues");
190 return i; 237 while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL;
191 } 238 f->upvalues[fs->nups].instack = (v->k == VLOCAL);
192 } 239 f->upvalues[fs->nups].idx = cast_byte(v->u.info);
193 /* new one */ 240 f->upvalues[fs->nups].name = name;
194 luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues"); 241 luaC_objbarrier(fs->ls->L, f, name);
195 luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues, 242 return fs->nups++;
196 TString *, MAX_INT, "");
197 while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL;
198 f->upvalues[f->nups] = name;
199 luaC_objbarrier(fs->L, f, name);
200 lua_assert(v->k == VLOCAL || v->k == VUPVAL);
201 fs->upvalues[f->nups].k = cast_byte(v->k);
202 fs->upvalues[f->nups].info = cast_byte(v->u.s.info);
203 return f->nups++;
204} 243}
205 244
206 245
207static int searchvar (FuncState *fs, TString *n) { 246static int searchvar (FuncState *fs, TString *n) {
208 int i; 247 int i;
209 for (i=fs->nactvar-1; i >= 0; i--) { 248 for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {
210 if (n == getlocvar(fs, i).varname) 249 if (luaS_eqstr(n, getlocvar(fs, i)->varname))
211 return i; 250 return i;
212 } 251 }
213 return -1; /* not found */ 252 return -1; /* not found */
214} 253}
215 254
216 255
256/*
257 Mark block where variable at given level was defined
258 (to emit close instructions later).
259*/
217static void markupval (FuncState *fs, int level) { 260static void markupval (FuncState *fs, int level) {
218 BlockCnt *bl = fs->bl; 261 BlockCnt *bl = fs->bl;
219 while (bl && bl->nactvar > level) bl = bl->previous; 262 while (bl->nactvar > level) bl = bl->previous;
220 if (bl) bl->upval = 1; 263 bl->upval = 1;
221} 264}
222 265
223 266
267/*
268 Find variable with given name 'n'. If it is an upvalue, add this
269 upvalue into all intermediate functions.
270*/
224static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { 271static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
225 if (fs == NULL) { /* no more levels? */ 272 if (fs == NULL) /* no more levels? */
226 init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ 273 return VVOID; /* default is global */
227 return VGLOBAL;
228 }
229 else { 274 else {
230 int v = searchvar(fs, n); /* look up at current level */ 275 int v = searchvar(fs, n); /* look up locals at current level */
231 if (v >= 0) { 276 if (v >= 0) { /* found? */
232 init_exp(var, VLOCAL, v); 277 init_exp(var, VLOCAL, v); /* variable is local */
233 if (!base) 278 if (!base)
234 markupval(fs, v); /* local will be used as an upval */ 279 markupval(fs, v); /* local will be used as an upval */
235 return VLOCAL; 280 return VLOCAL;
236 } 281 }
237 else { /* not found at current level; try upper one */ 282 else { /* not found as local at current level; try upvalues */
238 if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) 283 int idx = searchupvalue(fs, n); /* try existing upvalues */
239 return VGLOBAL; 284 if (idx < 0) { /* not found? */
240 var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ 285 if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */
241 var->k = VUPVAL; /* upvalue in this level */ 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);
242 return VUPVAL; 291 return VUPVAL;
243 } 292 }
244 } 293 }
@@ -248,8 +297,13 @@ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
248static void singlevar (LexState *ls, expdesc *var) { 297static void singlevar (LexState *ls, expdesc *var) {
249 TString *varname = str_checkname(ls); 298 TString *varname = str_checkname(ls);
250 FuncState *fs = ls->fs; 299 FuncState *fs = ls->fs;
251 if (singlevaraux(fs, varname, var, 1) == VGLOBAL) 300 if (singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */
252 var->u.s.info = luaK_stringK(fs, varname); /* info points to 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 }
253} 307}
254 308
255 309
@@ -274,18 +328,118 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
274 328
275 329
276static void enterlevel (LexState *ls) { 330static void enterlevel (LexState *ls) {
277 if (++ls->L->nCcalls > LUAI_MAXCCALLS) 331 lua_State *L = ls->L;
278 luaX_lexerror(ls, "chunk has too many syntax levels", 0); 332 ++L->nCcalls;
333 checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels");
279} 334}
280 335
281 336
282#define leavelevel(ls) ((ls)->L->nCcalls--) 337#define leavelevel(ls) ((ls)->L->nCcalls--)
283 338
284 339
285static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { 340static void closegoto (LexState *ls, int g, Labeldesc *label) {
286 bl->breaklist = NO_JUMP; 341 int i;
287 bl->isbreakable = isbreakable; 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;
288 bl->nactvar = fs->nactvar; 440 bl->nactvar = fs->nactvar;
441 bl->firstlabel = fs->ls->dyd->label.n;
442 bl->firstgoto = fs->ls->dyd->gt.n;
289 bl->upval = 0; 443 bl->upval = 0;
290 bl->previous = fs->bl; 444 bl->previous = fs->bl;
291 fs->bl = bl; 445 fs->bl = bl;
@@ -293,63 +447,108 @@ static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) {
293} 447}
294 448
295 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
296static void leaveblock (FuncState *fs) { 472static void leaveblock (FuncState *fs) {
297 BlockCnt *bl = fs->bl; 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 */
298 fs->bl = bl->previous; 483 fs->bl = bl->previous;
299 removevars(fs->ls, bl->nactvar); 484 removevars(fs, bl->nactvar);
300 if (bl->upval)
301 luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
302 /* a block either controls scope or breaks (never both) */
303 lua_assert(!bl->isbreakable || !bl->upval);
304 lua_assert(bl->nactvar == fs->nactvar); 485 lua_assert(bl->nactvar == fs->nactvar);
305 fs->freereg = fs->nactvar; /* free registers */ 486 fs->freereg = fs->nactvar; /* free registers */
306 luaK_patchtohere(fs, bl->breaklist); 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 */
307} 492}
308 493
309 494
310static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { 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;
311 FuncState *fs = ls->fs; 501 FuncState *fs = ls->fs;
312 Proto *f = fs->f; 502 Proto *f = fs->f; /* prototype of current function */
313 int oldsize = f->sizep; 503 if (fs->np >= f->sizep) {
314 int i; 504 int oldsize = f->sizep;
315 luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, 505 luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions");
316 MAXARG_Bx, "constant table overflow"); 506 while (oldsize < f->sizep) f->p[oldsize++] = NULL;
317 while (oldsize < f->sizep) f->p[oldsize++] = NULL;
318 f->p[fs->np++] = func->f;
319 luaC_objbarrier(ls->L, f, func->f);
320 init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
321 for (i=0; i<func->f->nups; i++) {
322 OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
323 luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
324 } 507 }
508 f->p[fs->np++] = clp = luaF_newproto(L);
509 luaC_objbarrier(L, f, clp);
510 return clp;
325} 511}
326 512
327 513
328static void lparser_open_func (LexState *ls, FuncState *fs) { 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) {
329 lua_State *L = ls->L; 528 lua_State *L = ls->L;
330 Proto *f = luaF_newproto(L); 529 Proto *f;
331 fs->f = f;
332 fs->prev = ls->fs; /* linked list of funcstates */ 530 fs->prev = ls->fs; /* linked list of funcstates */
333 fs->ls = ls; 531 fs->ls = ls;
334 fs->L = L;
335 ls->fs = fs; 532 ls->fs = fs;
336 fs->pc = 0; 533 fs->pc = 0;
337 fs->lasttarget = -1; 534 fs->lasttarget = 0;
338 fs->jpc = NO_JUMP; 535 fs->jpc = NO_JUMP;
339 fs->freereg = 0; 536 fs->freereg = 0;
340 fs->nk = 0; 537 fs->nk = 0;
341 fs->np = 0; 538 fs->np = 0;
539 fs->nups = 0;
342 fs->nlocvars = 0; 540 fs->nlocvars = 0;
343 fs->nactvar = 0; 541 fs->nactvar = 0;
542 fs->firstlocal = ls->dyd->actvar.n;
344 fs->bl = NULL; 543 fs->bl = NULL;
544 f = fs->f;
345 f->source = ls->source; 545 f->source = ls->source;
346 f->maxstacksize = 2; /* registers 0/1 are always valid */ 546 f->maxstacksize = 2; /* registers 0/1 are always valid */
347 fs->h = luaH_new(L, 0, 0); 547 fs->h = luaH_new(L);
348 /* anchor table of constants and prototype (to avoid being collected) */ 548 /* anchor table of constants (to avoid being collected) */
349 sethvalue2s(L, L->top, fs->h); 549 sethvalue2s(L, L->top, fs->h);
350 incr_top(L); 550 incr_top(L);
351 setptvalue2s(L, L->top, f); 551 enterblock(fs, bl, 0);
352 incr_top(L);
353} 552}
354 553
355 554
@@ -357,8 +556,8 @@ static void close_func (LexState *ls) {
357 lua_State *L = ls->L; 556 lua_State *L = ls->L;
358 FuncState *fs = ls->fs; 557 FuncState *fs = ls->fs;
359 Proto *f = fs->f; 558 Proto *f = fs->f;
360 removevars(ls, 0);
361 luaK_ret(fs, 0, 0); /* final return */ 559 luaK_ret(fs, 0, 0); /* final return */
560 leaveblock(fs);
362 luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); 561 luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
363 f->sizecode = fs->pc; 562 f->sizecode = fs->pc;
364 luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); 563 luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
@@ -369,32 +568,14 @@ static void close_func (LexState *ls) {
369 f->sizep = fs->np; 568 f->sizep = fs->np;
370 luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); 569 luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
371 f->sizelocvars = fs->nlocvars; 570 f->sizelocvars = fs->nlocvars;
372 luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *); 571 luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc);
373 f->sizeupvalues = f->nups; 572 f->sizeupvalues = fs->nups;
374 lua_assert(luaG_checkcode(f));
375 lua_assert(fs->bl == NULL); 573 lua_assert(fs->bl == NULL);
376 ls->fs = fs->prev; 574 ls->fs = fs->prev;
377 L->top -= 2; /* remove table and prototype from the stack */ 575 /* last token read was anchored in defunct function; must re-anchor it */
378 /* last token read was anchored in defunct function; must reanchor it */ 576 anchor_token(ls);
379 if (fs) anchor_token(ls); 577 L->top--; /* pop table of constants */
380} 578 luaC_checkGC(L);
381
382
383Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
384 struct LexState lexstate;
385 struct FuncState funcstate;
386 lexstate.buff = buff;
387 luaX_setinput(L, &lexstate, z, luaS_new(L, name));
388 lparser_open_func(&lexstate, &funcstate);
389 funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */
390 luaX_next(&lexstate); /* read first token */
391 chunk(&lexstate);
392 check(&lexstate, TK_EOS);
393 close_func(&lexstate);
394 lua_assert(funcstate.prev == NULL);
395 lua_assert(funcstate.f->nups == 0);
396 lua_assert(lexstate.fs == NULL);
397 return funcstate.f;
398} 579}
399 580
400 581
@@ -404,11 +585,39 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
404/*============================================================*/ 585/*============================================================*/
405 586
406 587
407static void field (LexState *ls, expdesc *v) { 588/*
408 /* field -> ['.' | ':'] NAME */ 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 */
409 FuncState *fs = ls->fs; 618 FuncState *fs = ls->fs;
410 expdesc key; 619 expdesc key;
411 luaK_exp2anyreg(fs, v); 620 luaK_exp2anyregup(fs, v);
412 luaX_next(ls); /* skip the dot or colon */ 621 luaX_next(ls); /* skip the dot or colon */
413 checkname(ls, &key); 622 checkname(ls, &key);
414 luaK_indexed(fs, v, &key); 623 luaK_indexed(fs, v, &key);
@@ -447,7 +656,7 @@ static void recfield (LexState *ls, struct ConsControl *cc) {
447 expdesc key, val; 656 expdesc key, val;
448 int rkkey; 657 int rkkey;
449 if (ls->t.token == TK_NAME) { 658 if (ls->t.token == TK_NAME) {
450 luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); 659 checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
451 checkname(ls, &key); 660 checkname(ls, &key);
452 } 661 }
453 else /* ls->t.token == '[' */ 662 else /* ls->t.token == '[' */
@@ -456,7 +665,7 @@ static void recfield (LexState *ls, struct ConsControl *cc) {
456 checknext(ls, '='); 665 checknext(ls, '=');
457 rkkey = luaK_exp2RK(fs, &key); 666 rkkey = luaK_exp2RK(fs, &key);
458 expr(ls, &val); 667 expr(ls, &val);
459 luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val)); 668 luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val));
460 fs->freereg = reg; /* free registers */ 669 fs->freereg = reg; /* free registers */
461} 670}
462 671
@@ -466,7 +675,7 @@ static void closelistfield (FuncState *fs, struct ConsControl *cc) {
466 luaK_exp2nextreg(fs, &cc->v); 675 luaK_exp2nextreg(fs, &cc->v);
467 cc->v.k = VVOID; 676 cc->v.k = VVOID;
468 if (cc->tostore == LFIELDS_PER_FLUSH) { 677 if (cc->tostore == LFIELDS_PER_FLUSH) {
469 luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */ 678 luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */
470 cc->tostore = 0; /* no more items pending */ 679 cc->tostore = 0; /* no more items pending */
471 } 680 }
472} 681}
@@ -476,27 +685,51 @@ static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
476 if (cc->tostore == 0) return; 685 if (cc->tostore == 0) return;
477 if (hasmultret(cc->v.k)) { 686 if (hasmultret(cc->v.k)) {
478 luaK_setmultret(fs, &cc->v); 687 luaK_setmultret(fs, &cc->v);
479 luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET); 688 luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET);
480 cc->na--; /* do not count last expression (unknown number of elements) */ 689 cc->na--; /* do not count last expression (unknown number of elements) */
481 } 690 }
482 else { 691 else {
483 if (cc->v.k != VVOID) 692 if (cc->v.k != VVOID)
484 luaK_exp2nextreg(fs, &cc->v); 693 luaK_exp2nextreg(fs, &cc->v);
485 luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); 694 luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore);
486 } 695 }
487} 696}
488 697
489 698
490static void listfield (LexState *ls, struct ConsControl *cc) { 699static void listfield (LexState *ls, struct ConsControl *cc) {
700 /* listfield -> exp */
491 expr(ls, &cc->v); 701 expr(ls, &cc->v);
492 luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); 702 checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
493 cc->na++; 703 cc->na++;
494 cc->tostore++; 704 cc->tostore++;
495} 705}
496 706
497 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
498static void constructor (LexState *ls, expdesc *t) { 730static void constructor (LexState *ls, expdesc *t) {
499 /* constructor -> ?? */ 731 /* constructor -> '{' [ field { sep field } [sep] ] '}'
732 sep -> ',' | ';' */
500 FuncState *fs = ls->fs; 733 FuncState *fs = ls->fs;
501 int line = ls->linenumber; 734 int line = ls->linenumber;
502 int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); 735 int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
@@ -505,30 +738,13 @@ static void constructor (LexState *ls, expdesc *t) {
505 cc.t = t; 738 cc.t = t;
506 init_exp(t, VRELOCABLE, pc); 739 init_exp(t, VRELOCABLE, pc);
507 init_exp(&cc.v, VVOID, 0); /* no value (yet) */ 740 init_exp(&cc.v, VVOID, 0); /* no value (yet) */
508 luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ 741 luaK_exp2nextreg(ls->fs, t); /* fix it at stack top */
509 checknext(ls, '{'); 742 checknext(ls, '{');
510 do { 743 do {
511 lua_assert(cc.v.k == VVOID || cc.tostore > 0); 744 lua_assert(cc.v.k == VVOID || cc.tostore > 0);
512 if (ls->t.token == '}') break; 745 if (ls->t.token == '}') break;
513 closelistfield(fs, &cc); 746 closelistfield(fs, &cc);
514 switch(ls->t.token) { 747 field(ls, &cc);
515 case TK_NAME: { /* may be listfields or recfields */
516 luaX_lookahead(ls);
517 if (ls->lookahead.token != '=') /* expression? */
518 listfield(ls, &cc);
519 else
520 recfield(ls, &cc);
521 break;
522 }
523 case '[': { /* constructor_item -> recfield */
524 recfield(ls, &cc);
525 break;
526 }
527 default: { /* constructor_part -> listfield */
528 listfield(ls, &cc);
529 break;
530 }
531 }
532 } while (testnext(ls, ',') || testnext(ls, ';')); 748 } while (testnext(ls, ',') || testnext(ls, ';'));
533 check_match(ls, '}', '{', line); 749 check_match(ls, '}', '{', line);
534 lastlistfield(fs, &cc); 750 lastlistfield(fs, &cc);
@@ -550,17 +766,13 @@ static void parlist (LexState *ls) {
550 do { 766 do {
551 switch (ls->t.token) { 767 switch (ls->t.token) {
552 case TK_NAME: { /* param -> NAME */ 768 case TK_NAME: { /* param -> NAME */
553 new_localvar(ls, str_checkname(ls), nparams++); 769 new_localvar(ls, str_checkname(ls));
770 nparams++;
554 break; 771 break;
555 } 772 }
556 case TK_DOTS: { /* param -> `...' */ 773 case TK_DOTS: { /* param -> `...' */
557 luaX_next(ls); 774 luaX_next(ls);
558#if defined(LUA_COMPAT_VARARG) 775 f->is_vararg = 1;
559 /* use `arg' as default name */
560 new_localvarliteral(ls, "arg", nparams++);
561 f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG;
562#endif
563 f->is_vararg |= VARARG_ISVARARG;
564 break; 776 break;
565 } 777 }
566 default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected"); 778 default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
@@ -568,33 +780,35 @@ static void parlist (LexState *ls) {
568 } while (!f->is_vararg && testnext(ls, ',')); 780 } while (!f->is_vararg && testnext(ls, ','));
569 } 781 }
570 adjustlocalvars(ls, nparams); 782 adjustlocalvars(ls, nparams);
571 f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG)); 783 f->numparams = cast_byte(fs->nactvar);
572 luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ 784 luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
573} 785}
574 786
575 787
576static void body (LexState *ls, expdesc *e, int needself, int line) { 788static void body (LexState *ls, expdesc *e, int ismethod, int line) {
577 /* body -> `(' parlist `)' chunk END */ 789 /* body -> `(' parlist `)' block END */
578 FuncState new_fs; 790 FuncState new_fs;
579 lparser_open_func(ls, &new_fs); 791 BlockCnt bl;
792 new_fs.f = addprototype(ls);
580 new_fs.f->linedefined = line; 793 new_fs.f->linedefined = line;
794 open_func(ls, &new_fs, &bl);
581 checknext(ls, '('); 795 checknext(ls, '(');
582 if (needself) { 796 if (ismethod) {
583 new_localvarliteral(ls, "self", 0); 797 new_localvarliteral(ls, "self"); /* create 'self' parameter */
584 adjustlocalvars(ls, 1); 798 adjustlocalvars(ls, 1);
585 } 799 }
586 parlist(ls); 800 parlist(ls);
587 checknext(ls, ')'); 801 checknext(ls, ')');
588 chunk(ls); 802 statlist(ls);
589 new_fs.f->lastlinedefined = ls->linenumber; 803 new_fs.f->lastlinedefined = ls->linenumber;
590 check_match(ls, TK_END, TK_FUNCTION, line); 804 check_match(ls, TK_END, TK_FUNCTION, line);
805 codeclosure(ls, e);
591 close_func(ls); 806 close_func(ls);
592 pushclosure(ls, &new_fs, e);
593} 807}
594 808
595 809
596static int explist1 (LexState *ls, expdesc *v) { 810static int explist (LexState *ls, expdesc *v) {
597 /* explist1 -> expr { `,' expr } */ 811 /* explist -> expr { `,' expr } */
598 int n = 1; /* at least one expression */ 812 int n = 1; /* at least one expression */
599 expr(ls, v); 813 expr(ls, v);
600 while (testnext(ls, ',')) { 814 while (testnext(ls, ',')) {
@@ -606,20 +820,17 @@ static int explist1 (LexState *ls, expdesc *v) {
606} 820}
607 821
608 822
609static void funcargs (LexState *ls, expdesc *f) { 823static void funcargs (LexState *ls, expdesc *f, int line) {
610 FuncState *fs = ls->fs; 824 FuncState *fs = ls->fs;
611 expdesc args; 825 expdesc args;
612 int base, nparams; 826 int base, nparams;
613 int line = ls->linenumber;
614 switch (ls->t.token) { 827 switch (ls->t.token) {
615 case '(': { /* funcargs -> `(' [ explist1 ] `)' */ 828 case '(': { /* funcargs -> `(' [ explist ] `)' */
616 if (line != ls->lastline)
617 luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
618 luaX_next(ls); 829 luaX_next(ls);
619 if (ls->t.token == ')') /* arg list is empty? */ 830 if (ls->t.token == ')') /* arg list is empty? */
620 args.k = VVOID; 831 args.k = VVOID;
621 else { 832 else {
622 explist1(ls, &args); 833 explist(ls, &args);
623 luaK_setmultret(fs, &args); 834 luaK_setmultret(fs, &args);
624 } 835 }
625 check_match(ls, ')', '(', line); 836 check_match(ls, ')', '(', line);
@@ -636,11 +847,10 @@ static void funcargs (LexState *ls, expdesc *f) {
636 } 847 }
637 default: { 848 default: {
638 luaX_syntaxerror(ls, "function arguments expected"); 849 luaX_syntaxerror(ls, "function arguments expected");
639 return;
640 } 850 }
641 } 851 }
642 lua_assert(f->k == VNONRELOC); 852 lua_assert(f->k == VNONRELOC);
643 base = f->u.s.info; /* base register for call */ 853 base = f->u.info; /* base register for call */
644 if (hasmultret(args.k)) 854 if (hasmultret(args.k))
645 nparams = LUA_MULTRET; /* open call */ 855 nparams = LUA_MULTRET; /* open call */
646 else { 856 else {
@@ -664,8 +874,8 @@ static void funcargs (LexState *ls, expdesc *f) {
664*/ 874*/
665 875
666 876
667static void prefixexp (LexState *ls, expdesc *v) { 877static void primaryexp (LexState *ls, expdesc *v) {
668 /* prefixexp -> NAME | '(' expr ')' */ 878 /* primaryexp -> NAME | '(' expr ')' */
669 switch (ls->t.token) { 879 switch (ls->t.token) {
670 case '(': { 880 case '(': {
671 int line = ls->linenumber; 881 int line = ls->linenumber;
@@ -681,26 +891,26 @@ static void prefixexp (LexState *ls, expdesc *v) {
681 } 891 }
682 default: { 892 default: {
683 luaX_syntaxerror(ls, "unexpected symbol"); 893 luaX_syntaxerror(ls, "unexpected symbol");
684 return;
685 } 894 }
686 } 895 }
687} 896}
688 897
689 898
690static void primaryexp (LexState *ls, expdesc *v) { 899static void suffixedexp (LexState *ls, expdesc *v) {
691 /* primaryexp -> 900 /* suffixedexp ->
692 prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ 901 primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */
693 FuncState *fs = ls->fs; 902 FuncState *fs = ls->fs;
694 prefixexp(ls, v); 903 int line = ls->linenumber;
904 primaryexp(ls, v);
695 for (;;) { 905 for (;;) {
696 switch (ls->t.token) { 906 switch (ls->t.token) {
697 case '.': { /* field */ 907 case '.': { /* fieldsel */
698 field(ls, v); 908 fieldsel(ls, v);
699 break; 909 break;
700 } 910 }
701 case '[': { /* `[' exp1 `]' */ 911 case '[': { /* `[' exp1 `]' */
702 expdesc key; 912 expdesc key;
703 luaK_exp2anyreg(fs, v); 913 luaK_exp2anyregup(fs, v);
704 yindex(ls, &key); 914 yindex(ls, &key);
705 luaK_indexed(fs, v, &key); 915 luaK_indexed(fs, v, &key);
706 break; 916 break;
@@ -710,12 +920,12 @@ static void primaryexp (LexState *ls, expdesc *v) {
710 luaX_next(ls); 920 luaX_next(ls);
711 checkname(ls, &key); 921 checkname(ls, &key);
712 luaK_self(fs, v, &key); 922 luaK_self(fs, v, &key);
713 funcargs(ls, v); 923 funcargs(ls, v, line);
714 break; 924 break;
715 } 925 }
716 case '(': case TK_STRING: case '{': { /* funcargs */ 926 case '(': case TK_STRING: case '{': { /* funcargs */
717 luaK_exp2nextreg(fs, v); 927 luaK_exp2nextreg(fs, v);
718 funcargs(ls, v); 928 funcargs(ls, v, line);
719 break; 929 break;
720 } 930 }
721 default: return; 931 default: return;
@@ -725,8 +935,8 @@ static void primaryexp (LexState *ls, expdesc *v) {
725 935
726 936
727static void simpleexp (LexState *ls, expdesc *v) { 937static void simpleexp (LexState *ls, expdesc *v) {
728 /* simpleexp -> NUMBER | STRING | NIL | true | false | ... | 938 /* simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... |
729 constructor | FUNCTION body | primaryexp */ 939 constructor | FUNCTION body | suffixedexp */
730 switch (ls->t.token) { 940 switch (ls->t.token) {
731 case TK_NUMBER: { 941 case TK_NUMBER: {
732 init_exp(v, VKNUM, 0); 942 init_exp(v, VKNUM, 0);
@@ -753,7 +963,6 @@ static void simpleexp (LexState *ls, expdesc *v) {
753 FuncState *fs = ls->fs; 963 FuncState *fs = ls->fs;
754 check_condition(ls, fs->f->is_vararg, 964 check_condition(ls, fs->f->is_vararg,
755 "cannot use " LUA_QL("...") " outside a vararg function"); 965 "cannot use " LUA_QL("...") " outside a vararg function");
756 fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */
757 init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); 966 init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
758 break; 967 break;
759 } 968 }
@@ -767,7 +976,7 @@ static void simpleexp (LexState *ls, expdesc *v) {
767 return; 976 return;
768 } 977 }
769 default: { 978 default: {
770 primaryexp(ls, v); 979 suffixedexp(ls, v);
771 return; 980 return;
772 } 981 }
773 } 982 }
@@ -811,11 +1020,11 @@ static const struct {
811 lu_byte left; /* left priority for each binary operator */ 1020 lu_byte left; /* left priority for each binary operator */
812 lu_byte right; /* right priority */ 1021 lu_byte right; /* right priority */
813} priority[] = { /* ORDER OPR */ 1022} priority[] = { /* ORDER OPR */
814 {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */ 1023 {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `*' `/' `%' */
815 {10, 9}, {5, 4}, /* power and concat (right associative) */ 1024 {10, 9}, {5, 4}, /* ^, .. (right associative) */
816 {3, 3}, {3, 3}, /* equality and inequality */ 1025 {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */
817 {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ 1026 {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */
818 {2, 2}, {1, 1} /* logical (and/or) */ 1027 {2, 2}, {1, 1} /* and, or */
819}; 1028};
820 1029
821#define UNARY_PRIORITY 8 /* priority for unary operators */ 1030#define UNARY_PRIORITY 8 /* priority for unary operators */
@@ -825,15 +1034,16 @@ static const struct {
825** subexpr -> (simpleexp | unop subexpr) { binop subexpr } 1034** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
826** where `binop' is any binary operator with a priority higher than `limit' 1035** where `binop' is any binary operator with a priority higher than `limit'
827*/ 1036*/
828static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) { 1037static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
829 BinOpr op; 1038 BinOpr op;
830 UnOpr uop; 1039 UnOpr uop;
831 enterlevel(ls); 1040 enterlevel(ls);
832 uop = getunopr(ls->t.token); 1041 uop = getunopr(ls->t.token);
833 if (uop != OPR_NOUNOPR) { 1042 if (uop != OPR_NOUNOPR) {
1043 int line = ls->linenumber;
834 luaX_next(ls); 1044 luaX_next(ls);
835 subexpr(ls, v, UNARY_PRIORITY); 1045 subexpr(ls, v, UNARY_PRIORITY);
836 luaK_prefix(ls->fs, uop, v); 1046 luaK_prefix(ls->fs, uop, v, line);
837 } 1047 }
838 else simpleexp(ls, v); 1048 else simpleexp(ls, v);
839 /* expand while operators have priorities higher than `limit' */ 1049 /* expand while operators have priorities higher than `limit' */
@@ -841,11 +1051,12 @@ static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) {
841 while (op != OPR_NOBINOPR && priority[op].left > limit) { 1051 while (op != OPR_NOBINOPR && priority[op].left > limit) {
842 expdesc v2; 1052 expdesc v2;
843 BinOpr nextop; 1053 BinOpr nextop;
1054 int line = ls->linenumber;
844 luaX_next(ls); 1055 luaX_next(ls);
845 luaK_infix(ls->fs, op, v); 1056 luaK_infix(ls->fs, op, v);
846 /* read sub-expression with higher priority */ 1057 /* read sub-expression with higher priority */
847 nextop = subexpr(ls, &v2, priority[op].right); 1058 nextop = subexpr(ls, &v2, priority[op].right);
848 luaK_posfix(ls->fs, op, v, &v2); 1059 luaK_posfix(ls->fs, op, v, &v2, line);
849 op = nextop; 1060 op = nextop;
850 } 1061 }
851 leavelevel(ls); 1062 leavelevel(ls);
@@ -868,23 +1079,12 @@ static void expr (LexState *ls, expdesc *v) {
868*/ 1079*/
869 1080
870 1081
871static int block_follow (int token) {
872 switch (token) {
873 case TK_ELSE: case TK_ELSEIF: case TK_END:
874 case TK_UNTIL: case TK_EOS:
875 return 1;
876 default: return 0;
877 }
878}
879
880
881static void block (LexState *ls) { 1082static void block (LexState *ls) {
882 /* block -> chunk */ 1083 /* block -> statlist */
883 FuncState *fs = ls->fs; 1084 FuncState *fs = ls->fs;
884 BlockCnt bl; 1085 BlockCnt bl;
885 enterblock(fs, &bl, 0); 1086 enterblock(fs, &bl, 0);
886 chunk(ls); 1087 statlist(ls);
887 lua_assert(bl.breaklist == NO_JUMP);
888 leaveblock(fs); 1088 leaveblock(fs);
889} 1089}
890 1090
@@ -900,29 +1100,34 @@ struct LHS_assign {
900 1100
901 1101
902/* 1102/*
903** check whether, in an assignment to a local variable, the local variable 1103** check whether, in an assignment to an upvalue/local variable, the
904** is needed in a previous assignment (to a table). If so, save original 1104** upvalue/local variable is begin used in a previous assignment to a
905** local value in a safe place and use this safe copy in the previous 1105** table. If so, save original upvalue/local value in a safe place and
906** assignment. 1106** use this safe copy in the previous assignment.
907*/ 1107*/
908static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { 1108static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
909 FuncState *fs = ls->fs; 1109 FuncState *fs = ls->fs;
910 int extra = fs->freereg; /* eventual position to save local variable */ 1110 int extra = fs->freereg; /* eventual position to save local variable */
911 int conflict = 0; 1111 int conflict = 0;
912 for (; lh; lh = lh->prev) { 1112 for (; lh; lh = lh->prev) { /* check all previous assignments */
913 if (lh->v.k == VINDEXED) { 1113 if (lh->v.k == VINDEXED) { /* assigning to a table? */
914 if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ 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) {
915 conflict = 1; 1116 conflict = 1;
916 lh->v.u.s.info = extra; /* previous assignment will use safe copy */ 1117 lh->v.u.ind.vt = VLOCAL;
1118 lh->v.u.ind.t = extra; /* previous assignment will use safe copy */
917 } 1119 }
918 if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */ 1120 /* index is the local being assigned? (index cannot be upvalue) */
1121 if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) {
919 conflict = 1; 1122 conflict = 1;
920 lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ 1123 lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */
921 } 1124 }
922 } 1125 }
923 } 1126 }
924 if (conflict) { 1127 if (conflict) {
925 luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */ 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);
926 luaK_reserveregs(fs, 1); 1131 luaK_reserveregs(fs, 1);
927 } 1132 }
928} 1133}
@@ -930,22 +1135,21 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
930 1135
931static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { 1136static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
932 expdesc e; 1137 expdesc e;
933 check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, 1138 check_condition(ls, vkisvar(lh->v.k), "syntax error");
934 "syntax error"); 1139 if (testnext(ls, ',')) { /* assignment -> ',' suffixedexp assignment */
935 if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */
936 struct LHS_assign nv; 1140 struct LHS_assign nv;
937 nv.prev = lh; 1141 nv.prev = lh;
938 primaryexp(ls, &nv.v); 1142 suffixedexp(ls, &nv.v);
939 if (nv.v.k == VLOCAL) 1143 if (nv.v.k != VINDEXED)
940 check_conflict(ls, lh, &nv.v); 1144 check_conflict(ls, lh, &nv.v);
941 luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, 1145 checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS,
942 "variables in assignment"); 1146 "C levels");
943 assignment(ls, &nv, nvars+1); 1147 assignment(ls, &nv, nvars+1);
944 } 1148 }
945 else { /* assignment -> `=' explist1 */ 1149 else { /* assignment -> `=' explist */
946 int nexps; 1150 int nexps;
947 checknext(ls, '='); 1151 checknext(ls, '=');
948 nexps = explist1(ls, &e); 1152 nexps = explist(ls, &e);
949 if (nexps != nvars) { 1153 if (nexps != nvars) {
950 adjust_assign(ls, nvars, nexps, &e); 1154 adjust_assign(ls, nvars, nexps, &e);
951 if (nexps > nvars) 1155 if (nexps > nvars)
@@ -972,19 +1176,57 @@ static int cond (LexState *ls) {
972} 1176}
973 1177
974 1178
975static void breakstat (LexState *ls) { 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 '::' */
976 FuncState *fs = ls->fs; 1217 FuncState *fs = ls->fs;
977 BlockCnt *bl = fs->bl; 1218 Labellist *ll = &ls->dyd->label;
978 int upval = 0; 1219 int l; /* index of new label being created */
979 while (bl && !bl->isbreakable) { 1220 checkrepeated(fs, ll, label); /* check for repeated labels */
980 upval |= bl->upval; 1221 checknext(ls, TK_DBCOLON); /* skip double colon */
981 bl = bl->previous; 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;
982 } 1228 }
983 if (!bl) 1229 findgotos(ls, &ll->arr[l]);
984 luaX_syntaxerror(ls, "no loop to break");
985 if (upval)
986 luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
987 luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
988} 1230}
989 1231
990 1232
@@ -1000,7 +1242,7 @@ static void whilestat (LexState *ls, int line) {
1000 enterblock(fs, &bl, 1); 1242 enterblock(fs, &bl, 1);
1001 checknext(ls, TK_DO); 1243 checknext(ls, TK_DO);
1002 block(ls); 1244 block(ls);
1003 luaK_patchlist(fs, luaK_jump(fs), whileinit); 1245 luaK_jumpto(fs, whileinit);
1004 check_match(ls, TK_END, TK_WHILE, line); 1246 check_match(ls, TK_END, TK_WHILE, line);
1005 leaveblock(fs); 1247 leaveblock(fs);
1006 luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ 1248 luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
@@ -1016,30 +1258,25 @@ static void repeatstat (LexState *ls, int line) {
1016 enterblock(fs, &bl1, 1); /* loop block */ 1258 enterblock(fs, &bl1, 1); /* loop block */
1017 enterblock(fs, &bl2, 0); /* scope block */ 1259 enterblock(fs, &bl2, 0); /* scope block */
1018 luaX_next(ls); /* skip REPEAT */ 1260 luaX_next(ls); /* skip REPEAT */
1019 chunk(ls); 1261 statlist(ls);
1020 check_match(ls, TK_UNTIL, TK_REPEAT, line); 1262 check_match(ls, TK_UNTIL, TK_REPEAT, line);
1021 condexit = cond(ls); /* read condition (inside scope block) */ 1263 condexit = cond(ls); /* read condition (inside scope block) */
1022 if (!bl2.upval) { /* no upvalues? */ 1264 if (bl2.upval) /* upvalues? */
1023 leaveblock(fs); /* finish scope */ 1265 luaK_patchclose(fs, condexit, bl2.nactvar);
1024 luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */ 1266 leaveblock(fs); /* finish scope */
1025 } 1267 luaK_patchlist(fs, condexit, repeat_init); /* close the loop */
1026 else { /* complete semantics when there are upvalues */
1027 breakstat(ls); /* if condition then break */
1028 luaK_patchtohere(ls->fs, condexit); /* else... */
1029 leaveblock(fs); /* finish scope... */
1030 luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */
1031 }
1032 leaveblock(fs); /* finish loop */ 1268 leaveblock(fs); /* finish loop */
1033} 1269}
1034 1270
1035 1271
1036static int exp1 (LexState *ls) { 1272static int exp1 (LexState *ls) {
1037 expdesc e; 1273 expdesc e;
1038 int k; 1274 int reg;
1039 expr(ls, &e); 1275 expr(ls, &e);
1040 k = e.k;
1041 luaK_exp2nextreg(ls->fs, &e); 1276 luaK_exp2nextreg(ls->fs, &e);
1042 return k; 1277 lua_assert(e.k == VNONRELOC);
1278 reg = e.u.info;
1279 return reg;
1043} 1280}
1044 1281
1045 1282
@@ -1057,10 +1294,15 @@ static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
1057 block(ls); 1294 block(ls);
1058 leaveblock(fs); /* end of scope for declared variables */ 1295 leaveblock(fs); /* end of scope for declared variables */
1059 luaK_patchtohere(fs, prep); 1296 luaK_patchtohere(fs, prep);
1060 endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : 1297 if (isnum) /* numeric for? */
1061 luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars); 1298 endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP);
1062 luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ 1299 else { /* generic for */
1063 luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1); 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);
1064} 1306}
1065 1307
1066 1308
@@ -1068,10 +1310,10 @@ static void fornum (LexState *ls, TString *varname, int line) {
1068 /* fornum -> NAME = exp1,exp1[,exp1] forbody */ 1310 /* fornum -> NAME = exp1,exp1[,exp1] forbody */
1069 FuncState *fs = ls->fs; 1311 FuncState *fs = ls->fs;
1070 int base = fs->freereg; 1312 int base = fs->freereg;
1071 new_localvarliteral(ls, "(for index)", 0); 1313 new_localvarliteral(ls, "(for index)");
1072 new_localvarliteral(ls, "(for limit)", 1); 1314 new_localvarliteral(ls, "(for limit)");
1073 new_localvarliteral(ls, "(for step)", 2); 1315 new_localvarliteral(ls, "(for step)");
1074 new_localvar(ls, varname, 3); 1316 new_localvar(ls, varname);
1075 checknext(ls, '='); 1317 checknext(ls, '=');
1076 exp1(ls); /* initial value */ 1318 exp1(ls); /* initial value */
1077 checknext(ls, ','); 1319 checknext(ls, ',');
@@ -1079,7 +1321,7 @@ static void fornum (LexState *ls, TString *varname, int line) {
1079 if (testnext(ls, ',')) 1321 if (testnext(ls, ','))
1080 exp1(ls); /* optional step */ 1322 exp1(ls); /* optional step */
1081 else { /* default step = 1 */ 1323 else { /* default step = 1 */
1082 luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); 1324 luaK_codek(fs, fs->freereg, luaK_numberK(fs, 1));
1083 luaK_reserveregs(fs, 1); 1325 luaK_reserveregs(fs, 1);
1084 } 1326 }
1085 forbody(ls, base, line, 1, 1); 1327 forbody(ls, base, line, 1, 1);
@@ -1087,23 +1329,25 @@ static void fornum (LexState *ls, TString *varname, int line) {
1087 1329
1088 1330
1089static void forlist (LexState *ls, TString *indexname) { 1331static void forlist (LexState *ls, TString *indexname) {
1090 /* forlist -> NAME {,NAME} IN explist1 forbody */ 1332 /* forlist -> NAME {,NAME} IN explist forbody */
1091 FuncState *fs = ls->fs; 1333 FuncState *fs = ls->fs;
1092 expdesc e; 1334 expdesc e;
1093 int nvars = 0; 1335 int nvars = 4; /* gen, state, control, plus at least one declared var */
1094 int line; 1336 int line;
1095 int base = fs->freereg; 1337 int base = fs->freereg;
1096 /* create control variables */ 1338 /* create control variables */
1097 new_localvarliteral(ls, "(for generator)", nvars++); 1339 new_localvarliteral(ls, "(for generator)");
1098 new_localvarliteral(ls, "(for state)", nvars++); 1340 new_localvarliteral(ls, "(for state)");
1099 new_localvarliteral(ls, "(for control)", nvars++); 1341 new_localvarliteral(ls, "(for control)");
1100 /* create declared variables */ 1342 /* create declared variables */
1101 new_localvar(ls, indexname, nvars++); 1343 new_localvar(ls, indexname);
1102 while (testnext(ls, ',')) 1344 while (testnext(ls, ',')) {
1103 new_localvar(ls, str_checkname(ls), nvars++); 1345 new_localvar(ls, str_checkname(ls));
1346 nvars++;
1347 }
1104 checknext(ls, TK_IN); 1348 checknext(ls, TK_IN);
1105 line = ls->linenumber; 1349 line = ls->linenumber;
1106 adjust_assign(ls, 3, explist1(ls, &e), &e); 1350 adjust_assign(ls, 3, explist(ls, &e), &e);
1107 luaK_checkstack(fs, 3); /* extra space to call generator */ 1351 luaK_checkstack(fs, 3); /* extra space to call generator */
1108 forbody(ls, base, line, nvars - 3, 0); 1352 forbody(ls, base, line, nvars - 3, 0);
1109} 1353}
@@ -1127,65 +1371,77 @@ static void forstat (LexState *ls, int line) {
1127} 1371}
1128 1372
1129 1373
1130static int test_then_block (LexState *ls) { 1374static void test_then_block (LexState *ls, int *escapelist) {
1131 /* test_then_block -> [IF | ELSEIF] cond THEN block */ 1375 /* test_then_block -> [IF | ELSEIF] cond THEN block */
1132 int condexit; 1376 BlockCnt bl;
1377 FuncState *fs = ls->fs;
1378 expdesc v;
1379 int jf; /* instruction to skip 'then' code (if condition is false) */
1133 luaX_next(ls); /* skip IF or ELSEIF */ 1380 luaX_next(ls); /* skip IF or ELSEIF */
1134 condexit = cond(ls); 1381 expr(ls, &v); /* read condition */
1135 checknext(ls, TK_THEN); 1382 checknext(ls, TK_THEN);
1136 block(ls); /* `then' part */ 1383 if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) {
1137 return condexit; 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);
1138} 1406}
1139 1407
1140 1408
1141static void ifstat (LexState *ls, int line) { 1409static void ifstat (LexState *ls, int line) {
1142 /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ 1410 /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
1143 FuncState *fs = ls->fs; 1411 FuncState *fs = ls->fs;
1144 int flist; 1412 int escapelist = NO_JUMP; /* exit list for finished parts */
1145 int escapelist = NO_JUMP; 1413 test_then_block(ls, &escapelist); /* IF cond THEN block */
1146 flist = test_then_block(ls); /* IF cond THEN block */ 1414 while (ls->t.token == TK_ELSEIF)
1147 while (ls->t.token == TK_ELSEIF) { 1415 test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */
1148 luaK_concat(fs, &escapelist, luaK_jump(fs)); 1416 if (testnext(ls, TK_ELSE))
1149 luaK_patchtohere(fs, flist);
1150 flist = test_then_block(ls); /* ELSEIF cond THEN block */
1151 }
1152 if (ls->t.token == TK_ELSE) {
1153 luaK_concat(fs, &escapelist, luaK_jump(fs));
1154 luaK_patchtohere(fs, flist);
1155 luaX_next(ls); /* skip ELSE (after patch, for correct line info) */
1156 block(ls); /* `else' part */ 1417 block(ls); /* `else' part */
1157 }
1158 else
1159 luaK_concat(fs, &escapelist, flist);
1160 luaK_patchtohere(fs, escapelist);
1161 check_match(ls, TK_END, TK_IF, line); 1418 check_match(ls, TK_END, TK_IF, line);
1419 luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */
1162} 1420}
1163 1421
1164 1422
1165static void localfunc (LexState *ls) { 1423static void localfunc (LexState *ls) {
1166 expdesc v, b; 1424 expdesc b;
1167 FuncState *fs = ls->fs; 1425 FuncState *fs = ls->fs;
1168 new_localvar(ls, str_checkname(ls), 0); 1426 new_localvar(ls, str_checkname(ls)); /* new local variable */
1169 init_exp(&v, VLOCAL, fs->freereg); 1427 adjustlocalvars(ls, 1); /* enter its scope */
1170 luaK_reserveregs(fs, 1); 1428 body(ls, &b, 0, ls->linenumber); /* function created in next register */
1171 adjustlocalvars(ls, 1);
1172 body(ls, &b, 0, ls->linenumber);
1173 luaK_storevar(fs, &v, &b);
1174 /* debug information will only see the variable after this point! */ 1429 /* debug information will only see the variable after this point! */
1175 getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; 1430 getlocvar(fs, b.u.info)->startpc = fs->pc;
1176} 1431}
1177 1432
1178 1433
1179static void localstat (LexState *ls) { 1434static void localstat (LexState *ls) {
1180 /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ 1435 /* stat -> LOCAL NAME {`,' NAME} [`=' explist] */
1181 int nvars = 0; 1436 int nvars = 0;
1182 int nexps; 1437 int nexps;
1183 expdesc e; 1438 expdesc e;
1184 do { 1439 do {
1185 new_localvar(ls, str_checkname(ls), nvars++); 1440 new_localvar(ls, str_checkname(ls));
1441 nvars++;
1186 } while (testnext(ls, ',')); 1442 } while (testnext(ls, ','));
1187 if (testnext(ls, '=')) 1443 if (testnext(ls, '='))
1188 nexps = explist1(ls, &e); 1444 nexps = explist(ls, &e);
1189 else { 1445 else {
1190 e.k = VVOID; 1446 e.k = VVOID;
1191 nexps = 0; 1447 nexps = 0;
@@ -1196,26 +1452,26 @@ static void localstat (LexState *ls) {
1196 1452
1197 1453
1198static int funcname (LexState *ls, expdesc *v) { 1454static int funcname (LexState *ls, expdesc *v) {
1199 /* funcname -> NAME {field} [`:' NAME] */ 1455 /* funcname -> NAME {fieldsel} [`:' NAME] */
1200 int needself = 0; 1456 int ismethod = 0;
1201 singlevar(ls, v); 1457 singlevar(ls, v);
1202 while (ls->t.token == '.') 1458 while (ls->t.token == '.')
1203 field(ls, v); 1459 fieldsel(ls, v);
1204 if (ls->t.token == ':') { 1460 if (ls->t.token == ':') {
1205 needself = 1; 1461 ismethod = 1;
1206 field(ls, v); 1462 fieldsel(ls, v);
1207 } 1463 }
1208 return needself; 1464 return ismethod;
1209} 1465}
1210 1466
1211 1467
1212static void funcstat (LexState *ls, int line) { 1468static void funcstat (LexState *ls, int line) {
1213 /* funcstat -> FUNCTION funcname body */ 1469 /* funcstat -> FUNCTION funcname body */
1214 int needself; 1470 int ismethod;
1215 expdesc v, b; 1471 expdesc v, b;
1216 luaX_next(ls); /* skip FUNCTION */ 1472 luaX_next(ls); /* skip FUNCTION */
1217 needself = funcname(ls, &v); 1473 ismethod = funcname(ls, &v);
1218 body(ls, &b, needself, line); 1474 body(ls, &b, ismethod, line);
1219 luaK_storevar(ls->fs, &v, &b); 1475 luaK_storevar(ls->fs, &v, &b);
1220 luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ 1476 luaK_fixline(ls->fs, line); /* definition `happens' in the first line */
1221} 1477}
@@ -1225,26 +1481,27 @@ static void exprstat (LexState *ls) {
1225 /* stat -> func | assignment */ 1481 /* stat -> func | assignment */
1226 FuncState *fs = ls->fs; 1482 FuncState *fs = ls->fs;
1227 struct LHS_assign v; 1483 struct LHS_assign v;
1228 primaryexp(ls, &v.v); 1484 suffixedexp(ls, &v.v);
1229 if (v.v.k == VCALL) /* stat -> func */ 1485 if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */
1230 SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */
1231 else { /* stat -> assignment */
1232 v.prev = NULL; 1486 v.prev = NULL;
1233 assignment(ls, &v, 1); 1487 assignment(ls, &v, 1);
1234 } 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 }
1235} 1493}
1236 1494
1237 1495
1238static void retstat (LexState *ls) { 1496static void retstat (LexState *ls) {
1239 /* stat -> RETURN explist */ 1497 /* stat -> RETURN [explist] [';'] */
1240 FuncState *fs = ls->fs; 1498 FuncState *fs = ls->fs;
1241 expdesc e; 1499 expdesc e;
1242 int first, nret; /* registers with returned values */ 1500 int first, nret; /* registers with returned values */
1243 luaX_next(ls); /* skip RETURN */ 1501 if (block_follow(ls, 1) || ls->t.token == ';')
1244 if (block_follow(ls->t.token) || ls->t.token == ';')
1245 first = nret = 0; /* return no values */ 1502 first = nret = 0; /* return no values */
1246 else { 1503 else {
1247 nret = explist1(ls, &e); /* optional return values */ 1504 nret = explist(ls, &e); /* optional return values */
1248 if (hasmultret(e.k)) { 1505 if (hasmultret(e.k)) {
1249 luaK_setmultret(fs, &e); 1506 luaK_setmultret(fs, &e);
1250 if (e.k == VCALL && nret == 1) { /* tail call? */ 1507 if (e.k == VCALL && nret == 1) { /* tail call? */
@@ -1265,37 +1522,43 @@ static void retstat (LexState *ls) {
1265 } 1522 }
1266 } 1523 }
1267 luaK_ret(fs, first, nret); 1524 luaK_ret(fs, first, nret);
1525 testnext(ls, ';'); /* skip optional semicolon */
1268} 1526}
1269 1527
1270 1528
1271static int statement (LexState *ls) { 1529static void statement (LexState *ls) {
1272 int line = ls->linenumber; /* may be needed for error messages */ 1530 int line = ls->linenumber; /* may be needed for error messages */
1531 enterlevel(ls);
1273 switch (ls->t.token) { 1532 switch (ls->t.token) {
1533 case ';': { /* stat -> ';' (empty statement) */
1534 luaX_next(ls); /* skip ';' */
1535 break;
1536 }
1274 case TK_IF: { /* stat -> ifstat */ 1537 case TK_IF: { /* stat -> ifstat */
1275 ifstat(ls, line); 1538 ifstat(ls, line);
1276 return 0; 1539 break;
1277 } 1540 }
1278 case TK_WHILE: { /* stat -> whilestat */ 1541 case TK_WHILE: { /* stat -> whilestat */
1279 whilestat(ls, line); 1542 whilestat(ls, line);
1280 return 0; 1543 break;
1281 } 1544 }
1282 case TK_DO: { /* stat -> DO block END */ 1545 case TK_DO: { /* stat -> DO block END */
1283 luaX_next(ls); /* skip DO */ 1546 luaX_next(ls); /* skip DO */
1284 block(ls); 1547 block(ls);
1285 check_match(ls, TK_END, TK_DO, line); 1548 check_match(ls, TK_END, TK_DO, line);
1286 return 0; 1549 break;
1287 } 1550 }
1288 case TK_FOR: { /* stat -> forstat */ 1551 case TK_FOR: { /* stat -> forstat */
1289 forstat(ls, line); 1552 forstat(ls, line);
1290 return 0; 1553 break;
1291 } 1554 }
1292 case TK_REPEAT: { /* stat -> repeatstat */ 1555 case TK_REPEAT: { /* stat -> repeatstat */
1293 repeatstat(ls, line); 1556 repeatstat(ls, line);
1294 return 0; 1557 break;
1295 } 1558 }
1296 case TK_FUNCTION: { 1559 case TK_FUNCTION: { /* stat -> funcstat */
1297 funcstat(ls, line); /* stat -> funcstat */ 1560 funcstat(ls, line);
1298 return 0; 1561 break;
1299 } 1562 }
1300 case TK_LOCAL: { /* stat -> localstat */ 1563 case TK_LOCAL: { /* stat -> localstat */
1301 luaX_next(ls); /* skip LOCAL */ 1564 luaX_next(ls); /* skip LOCAL */
@@ -1303,37 +1566,73 @@ static int statement (LexState *ls) {
1303 localfunc(ls); 1566 localfunc(ls);
1304 else 1567 else
1305 localstat(ls); 1568 localstat(ls);
1306 return 0; 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;
1307 } 1575 }
1308 case TK_RETURN: { /* stat -> retstat */ 1576 case TK_RETURN: { /* stat -> retstat */
1577 luaX_next(ls); /* skip RETURN */
1309 retstat(ls); 1578 retstat(ls);
1310 return 1; /* must be last statement */ 1579 break;
1311 } 1580 }
1312 case TK_BREAK: { /* stat -> breakstat */ 1581 case TK_BREAK: /* stat -> breakstat */
1313 luaX_next(ls); /* skip BREAK */ 1582 case TK_GOTO: { /* stat -> 'goto' NAME */
1314 breakstat(ls); 1583 gotostat(ls, luaK_jump(ls->fs));
1315 return 1; /* must be last statement */ 1584 break;
1316 } 1585 }
1317 default: { 1586 default: { /* stat -> func | assignment */
1318 exprstat(ls); 1587 exprstat(ls);
1319 return 0; /* to avoid warnings */ 1588 break;
1320 } 1589 }
1321 } 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);
1322} 1595}
1323 1596
1597/* }====================================================================== */
1324 1598
1325static void chunk (LexState *ls) { 1599
1326 /* chunk -> { stat [`;'] } */ 1600/*
1327 int islast = 0; 1601** compiles the main function, which is a regular vararg function with an
1328 enterlevel(ls); 1602** upvalue named LUA_ENV
1329 while (!islast && !block_follow(ls->t.token)) { 1603*/
1330 islast = statement(ls); 1604static void mainfunc (LexState *ls, FuncState *fs) {
1331 testnext(ls, ';'); 1605 BlockCnt bl;
1332 lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && 1606 expdesc v;
1333 ls->fs->freereg >= ls->fs->nactvar); 1607 open_func(ls, fs, &bl);
1334 ls->fs->freereg = ls->fs->nactvar; /* free registers */ 1608 fs->f->is_vararg = 1; /* main function is always vararg */
1335 } 1609 init_exp(&v, VLOCAL, 0); /* create and... */
1336 leavelevel(ls); 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 */
1337} 1637}
1338 1638
1339/* }====================================================================== */
diff --git a/apps/plugins/lua/lparser.h b/apps/plugins/lua/lparser.h
index f9b8e24913..0346e3c41a 100644
--- a/apps/plugins/lua/lparser.h
+++ b/apps/plugins/lua/lparser.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: lparser.h,v 1.70.1.1 2013/04/12 18:48:47 roberto Exp $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -23,34 +23,72 @@ typedef enum {
23 VFALSE, 23 VFALSE,
24 VK, /* info = index of constant in `k' */ 24 VK, /* info = index of constant in `k' */
25 VKNUM, /* nval = numerical value */ 25 VKNUM, /* nval = numerical value */
26 VNONRELOC, /* info = result register */
26 VLOCAL, /* info = local register */ 27 VLOCAL, /* info = local register */
27 VUPVAL, /* info = index of upvalue in `upvalues' */ 28 VUPVAL, /* info = index of upvalue in 'upvalues' */
28 VGLOBAL, /* info = index of table; aux = index of global name in `k' */ 29 VINDEXED, /* t = table register/upvalue; idx = index R/K */
29 VINDEXED, /* info = table register; aux = index register (or `k') */
30 VJMP, /* info = instruction pc */ 30 VJMP, /* info = instruction pc */
31 VRELOCABLE, /* info = instruction pc */ 31 VRELOCABLE, /* info = instruction pc */
32 VNONRELOC, /* info = result register */
33 VCALL, /* info = instruction pc */ 32 VCALL, /* info = instruction pc */
34 VVARARG /* info = instruction pc */ 33 VVARARG /* info = instruction pc */
35} expkind; 34} expkind;
36 35
36
37#define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED)
38#define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL)
39
37typedef struct expdesc { 40typedef struct expdesc {
38 expkind k; 41 expkind k;
39 union { 42 union {
40 struct { int info, aux; } s; 43 struct { /* for indexed variables (VINDEXED) */
41 lua_Number nval; 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 */
42 } u; 50 } u;
43 int t; /* patch list of `exit when true' */ 51 int t; /* patch list of `exit when true' */
44 int f; /* patch list of `exit when false' */ 52 int f; /* patch list of `exit when false' */
45} expdesc; 53} expdesc;
46 54
47 55
48typedef struct upvaldesc { 56/* description of active local variable */
49 lu_byte k; 57typedef struct Vardesc {
50 lu_byte info; 58 short idx; /* variable index in stack */
51} upvaldesc; 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;
52 89
53 90
91/* control of blocks */
54struct BlockCnt; /* defined in lparser.c */ 92struct BlockCnt; /* defined in lparser.c */
55 93
56 94
@@ -60,23 +98,22 @@ typedef struct FuncState {
60 Table *h; /* table to find (and reuse) elements in `k' */ 98 Table *h; /* table to find (and reuse) elements in `k' */
61 struct FuncState *prev; /* enclosing function */ 99 struct FuncState *prev; /* enclosing function */
62 struct LexState *ls; /* lexical state */ 100 struct LexState *ls; /* lexical state */
63 struct lua_State *L; /* copy of the Lua state */
64 struct BlockCnt *bl; /* chain of current blocks */ 101 struct BlockCnt *bl; /* chain of current blocks */
65 int pc; /* next position to code (equivalent to `ncode') */ 102 int pc; /* next position to code (equivalent to `ncode') */
66 int lasttarget; /* `pc' of last `jump target' */ 103 int lasttarget; /* 'label' of last 'jump label' */
67 int jpc; /* list of pending jumps to `pc' */ 104 int jpc; /* list of pending jumps to `pc' */
68 int freereg; /* first free register */
69 int nk; /* number of elements in `k' */ 105 int nk; /* number of elements in `k' */
70 int np; /* number of elements in `p' */ 106 int np; /* number of elements in `p' */
71 short nlocvars; /* number of elements in `locvars' */ 107 int firstlocal; /* index of first local var (in Dyndata array) */
108 short nlocvars; /* number of elements in 'f->locvars' */
72 lu_byte nactvar; /* number of active local variables */ 109 lu_byte nactvar; /* number of active local variables */
73 upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */ 110 lu_byte nups; /* number of upvalues */
74 unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */ 111 lu_byte freereg; /* first free register */
75} FuncState; 112} FuncState;
76 113
77 114
78LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 115LUAI_FUNC Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
79 const char *name); 116 Dyndata *dyd, const char *name, int firstchar);
80 117
81 118
82#endif 119#endif
diff --git a/apps/plugins/lua/lstate.c b/apps/plugins/lua/lstate.c
index 4313b83a0c..c7f2672be7 100644
--- a/apps/plugins/lua/lstate.c
+++ b/apps/plugins/lua/lstate.c
@@ -1,17 +1,19 @@
1/* 1/*
2** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $ 2** $Id: lstate.c,v 2.99.1.2 2013/11/08 17:45:31 roberto Exp $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
6 6
7 7
8#include <stddef.h> 8#include <stddef.h>
9#include <string.h>
9 10
10#define lstate_c 11#define lstate_c
11#define LUA_CORE 12#define LUA_CORE
12 13
13#include "lua.h" 14#include "lua.h"
14 15
16#include "lapi.h"
15#include "ldebug.h" 17#include "ldebug.h"
16#include "ldo.h" 18#include "ldo.h"
17#include "lfunc.h" 19#include "lfunc.h"
@@ -24,119 +26,240 @@
24#include "ltm.h" 26#include "ltm.h"
25 27
26 28
27#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE) 29#if !defined(LUAI_GCPAUSE)
28#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE) 30#define LUAI_GCPAUSE 200 /* 200% */
29#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE)) 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;
30 65
31 66
32/* 67/*
33** Main thread combines a thread state and the global state 68** Main thread combines a thread state and the global state
34*/ 69*/
35typedef struct LG { 70typedef struct LG {
36 lua_State l; 71 LX l;
37 global_State g; 72 global_State g;
38} LG; 73} LG;
39 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}
40 131
41 132
42static void stack_init (lua_State *L1, lua_State *L) { 133static void stack_init (lua_State *L1, lua_State *L) {
43 /* initialize CallInfo array */ 134 int i; CallInfo *ci;
44 L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
45 L1->ci = L1->base_ci;
46 L1->size_ci = BASIC_CI_SIZE;
47 L1->end_ci = L1->base_ci + L1->size_ci - 1;
48 /* initialize stack array */ 135 /* initialize stack array */
49 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); 136 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue);
50 L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; 137 L1->stacksize = BASIC_STACK_SIZE;
138 for (i = 0; i < BASIC_STACK_SIZE; i++)
139 setnilvalue(L1->stack + i); /* erase new stack */
51 L1->top = L1->stack; 140 L1->top = L1->stack;
52 L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; 141 L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
53 /* initialize first ci */ 142 /* initialize first ci */
54 L1->ci->func = L1->top; 143 ci = &L1->base_ci;
55 setnilvalue(L1->top++); /* `function' entry for this `ci' */ 144 ci->next = ci->previous = NULL;
56 L1->base = L1->ci->base = L1->top; 145 ci->callstatus = 0;
57 L1->ci->top = L1->top + LUA_MINSTACK; 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 */
58} 159}
59 160
60 161
61static void freestack (lua_State *L, lua_State *L1) { 162/*
62 luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); 163** Create registry table and its predefined values
63 luaM_freearray(L, L1->stack, L1->stacksize, TValue); 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);
64} 177}
65 178
66 179
67/* 180/*
68** open parts that may cause memory-allocation errors 181** open parts of the state that may cause memory-allocation errors
69*/ 182*/
70static void f_luaopen (lua_State *L, void *ud) { 183static void f_luaopen (lua_State *L, void *ud) {
71 global_State *g = G(L); 184 global_State *g = G(L);
72 UNUSED(ud); 185 UNUSED(ud);
73 stack_init(L, L); /* init stack */ 186 stack_init(L, L); /* init stack */
74 sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ 187 init_registry(L, g);
75 sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */
76 luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ 188 luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
77 luaT_init(L); 189 luaT_init(L);
78 luaX_init(L); 190 luaX_init(L);
79 luaS_fix(luaS_newliteral(L, MEMERRMSG)); 191 /* pre-create memory-error message */
80 g->GCthreshold = 4*g->totalbytes; 192 g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
193 luaS_fix(g->memerrmsg); /* it should never be collected */
194 g->gcrunning = 1; /* allow gc */
195 g->version = lua_version(NULL);
196 luai_userstateopen(L);
81} 197}
82 198
83 199
200/*
201** preinitialize a state with consistent values without allocating
202** any memory (to avoid errors)
203*/
84static void preinit_state (lua_State *L, global_State *g) { 204static void preinit_state (lua_State *L, global_State *g) {
85 G(L) = g; 205 G(L) = g;
86 L->stack = NULL; 206 L->stack = NULL;
207 L->ci = NULL;
87 L->stacksize = 0; 208 L->stacksize = 0;
88 L->errorJmp = NULL; 209 L->errorJmp = NULL;
210 L->nCcalls = 0;
89 L->hook = NULL; 211 L->hook = NULL;
90 L->hookmask = 0; 212 L->hookmask = 0;
91 L->basehookcount = 0; 213 L->basehookcount = 0;
92 L->allowhook = 1; 214 L->allowhook = 1;
93 resethookcount(L); 215 resethookcount(L);
94 L->openupval = NULL; 216 L->openupval = NULL;
95 L->size_ci = 0; 217 L->nny = 1;
96 L->nCcalls = L->baseCcalls = 0; 218 L->status = LUA_OK;
97 L->status = 0;
98 L->base_ci = L->ci = NULL;
99 L->savedpc = NULL;
100 L->errfunc = 0; 219 L->errfunc = 0;
101 setnilvalue(gt(L));
102} 220}
103 221
104 222
105static void close_state (lua_State *L) { 223static void close_state (lua_State *L) {
106 global_State *g = G(L); 224 global_State *g = G(L);
107 luaF_close(L, L->stack); /* close all upvalues for this thread */ 225 luaF_close(L, L->stack); /* close all upvalues for this thread */
108 luaC_freeall(L); /* collect all objects */ 226 luaC_freeallobjects(L); /* collect all objects */
109 lua_assert(g->rootgc == obj2gco(L)); 227 if (g->version) /* closing a fully built state? */
110 lua_assert(g->strt.nuse == 0); 228 luai_userstateclose(L);
111 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); 229 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
112 luaZ_freebuffer(L, &g->buff); 230 luaZ_freebuffer(L, &g->buff);
113 freestack(L, L); 231 freestack(L);
114 lua_assert(g->totalbytes == sizeof(LG)); 232 lua_assert(gettotalbytes(g) == sizeof(LG));
115 (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); 233 (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
116} 234}
117 235
118 236
119lua_State *luaE_newthread (lua_State *L) { 237LUA_API lua_State *lua_newthread (lua_State *L) {
120 lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); 238 lua_State *L1;
121 luaC_link(L, obj2gco(L1), LUA_TTHREAD); 239 lua_lock(L);
240 luaC_checkGC(L);
241 L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th;
242 setthvalue(L, L->top, L1);
243 api_incr_top(L);
122 preinit_state(L1, G(L)); 244 preinit_state(L1, G(L));
123 stack_init(L1, L); /* init stack */
124 setobj2n(L, gt(L1), gt(L)); /* share table of globals */
125 L1->hookmask = L->hookmask; 245 L1->hookmask = L->hookmask;
126 L1->basehookcount = L->basehookcount; 246 L1->basehookcount = L->basehookcount;
127 L1->hook = L->hook; 247 L1->hook = L->hook;
128 resethookcount(L1); 248 resethookcount(L1);
129 lua_assert(iswhite(obj2gco(L1))); 249 luai_userstatethread(L, L1);
250 stack_init(L1, L); /* init stack */
251 lua_unlock(L);
130 return L1; 252 return L1;
131} 253}
132 254
133 255
134void luaE_freethread (lua_State *L, lua_State *L1) { 256void luaE_freethread (lua_State *L, lua_State *L1) {
257 LX *l = fromstate(L1);
135 luaF_close(L1, L1->stack); /* close all upvalues for this thread */ 258 luaF_close(L1, L1->stack); /* close all upvalues for this thread */
136 lua_assert(L1->openupval == NULL); 259 lua_assert(L1->openupval == NULL);
137 luai_userstatefree(L1); 260 luai_userstatefree(L, L1);
138 freestack(L, L1); 261 freestack(L1);
139 luaM_freemem(L, fromstate(L1), state_size(lua_State)); 262 luaM_free(L, l);
140} 263}
141 264
142 265
@@ -144,71 +267,57 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
144 int i; 267 int i;
145 lua_State *L; 268 lua_State *L;
146 global_State *g; 269 global_State *g;
147 void *l = (*f)(ud, NULL, 0, state_size(LG)); 270 LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG)));
148 if (l == NULL) return NULL; 271 if (l == NULL) return NULL;
149 L = tostate(l); 272 L = &l->l.l;
150 g = &((LG *)L)->g; 273 g = &l->g;
151 L->next = NULL; 274 L->next = NULL;
152 L->tt = LUA_TTHREAD; 275 L->tt = LUA_TTHREAD;
153 g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); 276 g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
154 L->marked = luaC_white(g); 277 L->marked = luaC_white(g);
155 set2bits(L->marked, FIXEDBIT, SFIXEDBIT); 278 g->gckind = KGC_NORMAL;
156 preinit_state(L, g); 279 preinit_state(L, g);
157 g->frealloc = f; 280 g->frealloc = f;
158 g->ud = ud; 281 g->ud = ud;
159 g->mainthread = L; 282 g->mainthread = L;
283 g->seed = makeseed(L);
160 g->uvhead.u.l.prev = &g->uvhead; 284 g->uvhead.u.l.prev = &g->uvhead;
161 g->uvhead.u.l.next = &g->uvhead; 285 g->uvhead.u.l.next = &g->uvhead;
162 g->GCthreshold = 0; /* mark it as unfinished state */ 286 g->gcrunning = 0; /* no GC while building state */
287 g->GCestimate = 0;
163 g->strt.size = 0; 288 g->strt.size = 0;
164 g->strt.nuse = 0; 289 g->strt.nuse = 0;
165 g->strt.hash = NULL; 290 g->strt.hash = NULL;
166 setnilvalue(registry(L)); 291 setnilvalue(&g->l_registry);
167 luaZ_initbuffer(L, &g->buff); 292 luaZ_initbuffer(L, &g->buff);
168 g->panic = NULL; 293 g->panic = NULL;
294 g->version = NULL;
169 g->gcstate = GCSpause; 295 g->gcstate = GCSpause;
170 g->rootgc = obj2gco(L); 296 g->allgc = NULL;
171 g->sweepstrgc = 0; 297 g->finobj = NULL;
172 g->sweepgc = &g->rootgc; 298 g->tobefnz = NULL;
173 g->gray = NULL; 299 g->sweepgc = g->sweepfin = NULL;
174 g->grayagain = NULL; 300 g->gray = g->grayagain = NULL;
175 g->weak = NULL; 301 g->weak = g->ephemeron = g->allweak = NULL;
176 g->tmudata = NULL;
177 g->totalbytes = sizeof(LG); 302 g->totalbytes = sizeof(LG);
303 g->GCdebt = 0;
178 g->gcpause = LUAI_GCPAUSE; 304 g->gcpause = LUAI_GCPAUSE;
305 g->gcmajorinc = LUAI_GCMAJOR;
179 g->gcstepmul = LUAI_GCMUL; 306 g->gcstepmul = LUAI_GCMUL;
180 g->gcdept = 0; 307 for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
181 for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL; 308 if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
182 if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
183 /* memory allocation error: free partial state */ 309 /* memory allocation error: free partial state */
184 close_state(L); 310 close_state(L);
185 L = NULL; 311 L = NULL;
186 } 312 }
187 else
188 luai_userstateopen(L);
189 return L; 313 return L;
190} 314}
191 315
192 316
193static void callallgcTM (lua_State *L, void *ud) {
194 UNUSED(ud);
195 luaC_callGCTM(L); /* call GC metamethods for all udata */
196}
197
198
199LUA_API void lua_close (lua_State *L) { 317LUA_API void lua_close (lua_State *L) {
200 L = G(L)->mainthread; /* only the main thread can be closed */ 318 L = G(L)->mainthread; /* only the main thread can be closed */
201 lua_lock(L); 319 lua_lock(L);
202 luaF_close(L, L->stack); /* close all upvalues for this thread */
203 luaC_separateudata(L, 1); /* separate udata that have GC metamethods */
204 L->errfunc = 0; /* no error function during GC metamethods */
205 do { /* repeat until no more errors */
206 L->ci = L->base_ci;
207 L->base = L->top = L->ci->base;
208 L->nCcalls = L->baseCcalls = 0;
209 } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
210 lua_assert(G(L)->tmudata == NULL);
211 luai_userstateclose(L);
212 close_state(L); 320 close_state(L);
213} 321}
214 322
323
diff --git a/apps/plugins/lua/lstate.h b/apps/plugins/lua/lstate.h
index 94a6249461..daffd9aacf 100644
--- a/apps/plugins/lua/lstate.h
+++ b/apps/plugins/lua/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: lstate.h,v 2.82.1.1 2013/04/12 18:48:47 roberto Exp $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -14,26 +14,47 @@
14#include "lzio.h" 14#include "lzio.h"
15 15
16 16
17/*
17 18
18struct lua_longjmp; /* defined in ldo.c */ 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.
19 38
39*/
20 40
21/* table of globals */
22#define gt(L) (&L->l_gt)
23 41
24/* registry */ 42struct lua_longjmp; /* defined in ldo.c */
25#define registry(L) (&G(L)->l_registry) 43
26 44
27 45
28/* extra stack space to handle TM calls and some other extras */ 46/* extra stack space to handle TM calls and some other extras */
29#define EXTRA_STACK 5 47#define EXTRA_STACK 5
30 48
31 49
32#define BASIC_CI_SIZE 8
33
34#define BASIC_STACK_SIZE (2*LUA_MINSTACK) 50#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
35 51
36 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
37 58
38typedef struct stringtable { 59typedef struct stringtable {
39 GCObject **hash; 60 GCObject **hash;
@@ -43,54 +64,87 @@ typedef struct stringtable {
43 64
44 65
45/* 66/*
46** informations about a call 67** information about a call
47*/ 68*/
48typedef struct CallInfo { 69typedef struct CallInfo {
49 StkId base; /* base for this function */
50 StkId func; /* function index in the stack */ 70 StkId func; /* function index in the stack */
51 StkId top; /* top for this function */ 71 StkId top; /* top for this function */
52 const Instruction *savedpc; 72 struct CallInfo *previous, *next; /* dynamic call link */
53 int nresults; /* expected number of results from this function */ 73 short nresults; /* expected number of results from this function */
54 int tailcalls; /* number of tail calls lost under this entry */ 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;
55} CallInfo; 89} CallInfo;
56 90
57 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
58 105
59#define curr_func(L) (clvalue(L->ci->func)) 106#define isLua(ci) ((ci)->callstatus & CIST_LUA)
60#define ci_func(ci) (clvalue((ci)->func))
61#define f_isLua(ci) (!ci_func(ci)->c.isC)
62#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
63 107
64 108
65/* 109/*
66** `global state', shared by all threads of this state 110** `global state', shared by all threads of this state
67*/ 111*/
68typedef struct global_State { 112typedef struct global_State {
69 stringtable strt; /* hash table for strings */
70 lua_Alloc frealloc; /* function to reallocate memory */ 113 lua_Alloc frealloc; /* function to reallocate memory */
71 void *ud; /* auxiliary data to `frealloc' */ 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 */
72 lu_byte currentwhite; 122 lu_byte currentwhite;
73 lu_byte gcstate; /* state of garbage collector */ 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 */
74 int sweepstrgc; /* position of sweep in `strt' */ 126 int sweepstrgc; /* position of sweep in `strt' */
75 GCObject *rootgc; /* list of all collectable objects */ 127 GCObject *allgc; /* list of all collectable objects */
76 GCObject **sweepgc; /* position of sweep in `rootgc' */ 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' */
77 GCObject *gray; /* list of gray objects */ 131 GCObject *gray; /* list of gray objects */
78 GCObject *grayagain; /* list of objects to be traversed atomically */ 132 GCObject *grayagain; /* list of objects to be traversed atomically */
79 GCObject *weak; /* list of weak tables (to be cleared) */ 133 GCObject *weak; /* list of tables with weak values */
80 GCObject *tmudata; /* last element of list of userdata to be GC */ 134 GCObject *ephemeron; /* list of ephemeron tables (weak keys) */
81 Mbuffer buff; /* temporary buffer for string concatentation */ 135 GCObject *allweak; /* list of all-weak tables */
82 lu_mem GCthreshold; 136 GCObject *tobefnz; /* list of userdata to be GC */
83 lu_mem totalbytes; /* number of bytes currently allocated */ 137 UpVal uvhead; /* head of double-linked list of all open upvalues */
84 lu_mem estimate; /* an estimate of number of bytes actually in use */ 138 Mbuffer buff; /* temporary buffer for string concatenation */
85 lu_mem gcdept; /* how much GC is `behind schedule' */
86 int gcpause; /* size of pause between successive GCs */ 139 int gcpause; /* size of pause between successive GCs */
140 int gcmajorinc; /* pause between major collections (only in gen. mode) */
87 int gcstepmul; /* GC `granularity' */ 141 int gcstepmul; /* GC `granularity' */
88 lua_CFunction panic; /* to be called in unprotected errors */ 142 lua_CFunction panic; /* to be called in unprotected errors */
89 TValue l_registry;
90 struct lua_State *mainthread; 143 struct lua_State *mainthread;
91 UpVal uvhead; /* head of double-linked list of all open upvalues */ 144 const lua_Number *version; /* pointer to version number */
92 struct Table *mt[NUM_TAGS]; /* metatables for basic types */ 145 TString *memerrmsg; /* memory-error message */
93 TString *tmname[TM_N]; /* array with tag-method names */ 146 TString *tmname[TM_N]; /* array with tag-method names */
147 struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
94} global_State; 148} global_State;
95 149
96 150
@@ -101,29 +155,24 @@ struct lua_State {
101 CommonHeader; 155 CommonHeader;
102 lu_byte status; 156 lu_byte status;
103 StkId top; /* first free slot in the stack */ 157 StkId top; /* first free slot in the stack */
104 StkId base; /* base of current function */
105 global_State *l_G; 158 global_State *l_G;
106 CallInfo *ci; /* call info for current function */ 159 CallInfo *ci; /* call info for current function */
107 const Instruction *savedpc; /* `savedpc' of current function */ 160 const Instruction *oldpc; /* last pc traced */
108 StkId stack_last; /* last free slot in the stack */ 161 StkId stack_last; /* last free slot in the stack */
109 StkId stack; /* stack base */ 162 StkId stack; /* stack base */
110 CallInfo *end_ci; /* points after end of ci array*/
111 CallInfo *base_ci; /* array of CallInfo's */
112 int stacksize; 163 int stacksize;
113 int size_ci; /* size of array `base_ci' */ 164 unsigned short nny; /* number of non-yieldable calls in stack */
114 unsigned short nCcalls; /* number of nested C calls */ 165 unsigned short nCcalls; /* number of nested C calls */
115 unsigned short baseCcalls; /* nested C calls when resuming coroutine */
116 lu_byte hookmask; 166 lu_byte hookmask;
117 lu_byte allowhook; 167 lu_byte allowhook;
118 int basehookcount; 168 int basehookcount;
119 int hookcount; 169 int hookcount;
120 lua_Hook hook; 170 lua_Hook hook;
121 TValue l_gt; /* table of globals */
122 TValue env; /* temporary place for environments */
123 GCObject *openupval; /* list of open upvalues in this stack */ 171 GCObject *openupval; /* list of open upvalues in this stack */
124 GCObject *gclist; 172 GCObject *gclist;
125 struct lua_longjmp *errorJmp; /* current error recover point */ 173 struct lua_longjmp *errorJmp; /* current error recover point */
126 ptrdiff_t errfunc; /* current error handling function (stack index) */ 174 ptrdiff_t errfunc; /* current error handling function (stack index) */
175 CallInfo base_ci; /* CallInfo for first level (C calling Lua) */
127}; 176};
128 177
129 178
@@ -134,7 +183,7 @@ struct lua_State {
134** Union of all collectable objects 183** Union of all collectable objects
135*/ 184*/
136union GCObject { 185union GCObject {
137 GCheader gch; 186 GCheader gch; /* common header */
138 union TString ts; 187 union TString ts;
139 union Udata u; 188 union Udata u;
140 union Closure cl; 189 union Closure cl;
@@ -145,25 +194,35 @@ union GCObject {
145}; 194};
146 195
147 196
197#define gch(o) (&(o)->gch)
198
148/* macros to convert a GCObject into a specific value */ 199/* macros to convert a GCObject into a specific value */
149#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) 200#define rawgco2ts(o) \
201 check_exp(novariant((o)->gch.tt) == LUA_TSTRING, &((o)->ts))
150#define gco2ts(o) (&rawgco2ts(o)->tsv) 202#define gco2ts(o) (&rawgco2ts(o)->tsv)
151#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) 203#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
152#define gco2u(o) (&rawgco2u(o)->uv) 204#define gco2u(o) (&rawgco2u(o)->uv)
153#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) 205#define gco2lcl(o) check_exp((o)->gch.tt == LUA_TLCL, &((o)->cl.l))
154#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) 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))
155#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) 210#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
156#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) 211#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
157#define ngcotouv(o) \
158 check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv))
159#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) 212#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
160 213
161/* macro to convert any Lua object into a GCObject */ 214/* macro to convert any Lua object into a GCObject */
162#define obj2gco(v) (cast(GCObject *, (v))) 215#define obj2gco(v) (cast(GCObject *, (v)))
163 216
164 217
165LUAI_FUNC lua_State *luaE_newthread (lua_State *L); 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);
166LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); 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
167 226
168#endif 227#endif
169 228
diff --git a/apps/plugins/lua/lstring.c b/apps/plugins/lua/lstring.c
index 49113151cc..af96c89c18 100644
--- a/apps/plugins/lua/lstring.c
+++ b/apps/plugins/lua/lstring.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ 2** $Id: lstring.c,v 2.26.1.1 2013/04/12 18:48:47 roberto Exp $
3** String table (keeps all strings handled by Lua) 3** String table (keeps all strings handled by Lua)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -18,78 +18,157 @@
18#include "lstring.h" 18#include "lstring.h"
19 19
20 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
21 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*/
22void luaS_resize (lua_State *L, int newsize) { 64void luaS_resize (lua_State *L, int newsize) {
23 GCObject **newhash;
24 stringtable *tb;
25 int i; 65 int i;
26 if (G(L)->gcstate == GCSsweepstring) 66 stringtable *tb = &G(L)->strt;
27 return; /* cannot resize during GC traverse */ 67 /* cannot resize while GC is traversing strings */
28 newhash = luaM_newvector(L, newsize, GCObject *); 68 luaC_runtilstate(L, ~bitmask(GCSsweepstring));
29 tb = &G(L)->strt; 69 if (newsize > tb->size) {
30 for (i=0; i<newsize; i++) newhash[i] = NULL; 70 luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);
71 for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL;
72 }
31 /* rehash */ 73 /* rehash */
32 for (i=0; i<tb->size; i++) { 74 for (i=0; i<tb->size; i++) {
33 GCObject *p = tb->hash[i]; 75 GCObject *p = tb->hash[i];
76 tb->hash[i] = NULL;
34 while (p) { /* for each node in the list */ 77 while (p) { /* for each node in the list */
35 GCObject *next = p->gch.next; /* save next */ 78 GCObject *next = gch(p)->next; /* save next */
36 unsigned int h = gco2ts(p)->hash; 79 unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */
37 int h1 = lmod(h, newsize); /* new position */ 80 gch(p)->next = tb->hash[h]; /* chain it */
38 lua_assert(cast_int(h%newsize) == lmod(h, newsize)); 81 tb->hash[h] = p;
39 p->gch.next = newhash[h1]; /* chain it */ 82 resetoldbit(p); /* see MOVE OLD rule */
40 newhash[h1] = p;
41 p = next; 83 p = next;
42 } 84 }
43 } 85 }
44 luaM_freearray(L, tb->hash, tb->size, TString *); 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 }
45 tb->size = newsize; 91 tb->size = newsize;
46 tb->hash = newhash;
47} 92}
48 93
49 94
50static TString *newlstr (lua_State *L, const char *str, size_t l, 95/*
51 unsigned int h) { 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) {
52 TString *ts; 100 TString *ts;
53 stringtable *tb; 101 size_t totalsize; /* total size of TString object */
54 if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) 102 totalsize = sizeof(TString) + ((l + 1) * sizeof(char));
55 luaM_toobig(L); 103 ts = &luaC_newobj(L, tag, totalsize, list, 0)->ts;
56 ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
57 ts->tsv.len = l; 104 ts->tsv.len = l;
58 ts->tsv.hash = h; 105 ts->tsv.hash = h;
59 ts->tsv.marked = luaC_white(G(L)); 106 ts->tsv.extra = 0;
60 ts->tsv.tt = LUA_TSTRING;
61 ts->tsv.reserved = 0;
62 memcpy(ts+1, str, l*sizeof(char)); 107 memcpy(ts+1, str, l*sizeof(char));
63 ((char *)(ts+1))[l] = '\0'; /* ending 0 */ 108 ((char *)(ts+1))[l] = '\0'; /* ending 0 */
64 tb = &G(L)->strt;
65 h = lmod(h, tb->size);
66 ts->tsv.next = tb->hash[h]; /* chain new entry */
67 tb->hash[h] = obj2gco(ts);
68 tb->nuse++;
69 if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
70 luaS_resize(L, tb->size*2); /* too crowded */
71 return ts; 109 return ts;
72} 110}
73 111
74 112
75TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { 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) {
76 GCObject *o; 134 GCObject *o;
77 unsigned int h = cast(unsigned int, l); /* seed */ 135 global_State *g = G(L);
78 size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ 136 unsigned int h = luaS_hash(str, l, g->seed);
79 size_t l1; 137 for (o = g->strt.hash[lmod(h, g->strt.size)];
80 for (l1=l; l1>=step; l1-=step) /* compute hash */
81 h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
82 for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
83 o != NULL; 138 o != NULL;
84 o = o->gch.next) { 139 o = gch(o)->next) {
85 TString *ts = rawgco2ts(o); 140 TString *ts = rawgco2ts(o);
86 if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) { 141 if (h == ts->tsv.hash &&
87 /* string may be dead */ 142 l == ts->tsv.len &&
88 if (isdead(G(L), o)) changewhite(o); 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 */
89 return ts; 146 return ts;
90 } 147 }
91 } 148 }
92 return newlstr(L, str, l, h); /* not found */ 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));
93} 172}
94 173
95 174
@@ -97,15 +176,10 @@ Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
97 Udata *u; 176 Udata *u;
98 if (s > MAX_SIZET - sizeof(Udata)) 177 if (s > MAX_SIZET - sizeof(Udata))
99 luaM_toobig(L); 178 luaM_toobig(L);
100 u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata))); 179 u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s, NULL, 0)->u;
101 u->uv.marked = luaC_white(G(L)); /* is not finalized */
102 u->uv.tt = LUA_TUSERDATA;
103 u->uv.len = s; 180 u->uv.len = s;
104 u->uv.metatable = NULL; 181 u->uv.metatable = NULL;
105 u->uv.env = e; 182 u->uv.env = e;
106 /* chain it on udata list (after main thread) */
107 u->uv.next = G(L)->mainthread->next;
108 G(L)->mainthread->next = obj2gco(u);
109 return u; 183 return u;
110} 184}
111 185
diff --git a/apps/plugins/lua/lstring.h b/apps/plugins/lua/lstring.h
index c88e4c12a9..260e7f169b 100644
--- a/apps/plugins/lua/lstring.h
+++ b/apps/plugins/lua/lstring.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: lstring.h,v 1.49.1.1 2013/04/12 18:48:47 roberto Exp $
3** String table (keep all strings handled by Lua) 3** String table (keep all strings handled by Lua)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -7,7 +7,6 @@
7#ifndef lstring_h 7#ifndef lstring_h
8#define lstring_h 8#define lstring_h
9 9
10
11#include "lgc.h" 10#include "lgc.h"
12#include "lobject.h" 11#include "lobject.h"
13#include "lstate.h" 12#include "lstate.h"
@@ -17,15 +16,31 @@
17 16
18#define sizeudata(u) (sizeof(union Udata)+(u)->len) 17#define sizeudata(u) (sizeof(union Udata)+(u)->len)
19 18
20#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
21#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 19#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
22 (sizeof(s)/sizeof(char))-1)) 20 (sizeof(s)/sizeof(char))-1))
23 21
24#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) 22#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
25 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);
26LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 40LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
27LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); 41LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
28LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 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);
29 44
30 45
31#endif 46#endif
diff --git a/apps/plugins/lua/lstrlib.c b/apps/plugins/lua/lstrlib.c
index 3d6103692f..04cc2f60d6 100644
--- a/apps/plugins/lua/lstrlib.c
+++ b/apps/plugins/lua/lstrlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstrlib.c,v 1.132.1.4 2008/07/11 17:27:21 roberto Exp $ 2** $Id: lstrlib.c,v 1.178.1.1 2013/04/12 18:48:47 roberto Exp $
3** Standard library for string operations and pattern-matching 3** Standard library for string operations and pattern-matching
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -20,47 +20,58 @@
20#include "lualib.h" 20#include "lualib.h"
21 21
22 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
23/* macro to `unsign' a character */ 32/* macro to `unsign' a character */
24#define uchar(c) ((unsigned char)(c)) 33#define uchar(c) ((unsigned char)(c))
25 34
26 35
27 36
28static int str_len (lua_State *L) { 37static int str_len (lua_State *L) {
29 size_t l; 38 size_t l;
30 luaL_checklstring(L, 1, &l); 39 luaL_checklstring(L, 1, &l);
31 lua_pushinteger(L, l); 40 lua_pushinteger(L, (lua_Integer)l);
32 return 1; 41 return 1;
33} 42}
34 43
35 44
36static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) { 45/* translate a relative string position: negative means back from end */
37 /* relative string position: negative means back from end */ 46static size_t posrelat (ptrdiff_t pos, size_t len) {
38 if (pos < 0) pos += (ptrdiff_t)len + 1; 47 if (pos >= 0) return (size_t)pos;
39 return (pos >= 0) ? pos : 0; 48 else if (0u - (size_t)pos > len) return 0;
49 else return len - ((size_t)-pos) + 1;
40} 50}
41 51
42 52
43static int str_sub (lua_State *L) { 53static int str_sub (lua_State *L) {
44 size_t l; 54 size_t l;
45 const char *s = luaL_checklstring(L, 1, &l); 55 const char *s = luaL_checklstring(L, 1, &l);
46 ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l); 56 size_t start = posrelat(luaL_checkinteger(L, 2), l);
47 ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l); 57 size_t end = posrelat(luaL_optinteger(L, 3, -1), l);
48 if (start < 1) start = 1; 58 if (start < 1) start = 1;
49 if (end > (ptrdiff_t)l) end = (ptrdiff_t)l; 59 if (end > l) end = l;
50 if (start <= end) 60 if (start <= end)
51 lua_pushlstring(L, s+start-1, end-start+1); 61 lua_pushlstring(L, s + start - 1, end - start + 1);
52 else lua_pushliteral(L, ""); 62 else lua_pushliteral(L, "");
53 return 1; 63 return 1;
54} 64}
55 65
56 66
57static int str_reverse (lua_State *L) { 67static int str_reverse (lua_State *L) {
58 size_t l; 68 size_t l, i;
59 luaL_Buffer b; 69 luaL_Buffer b;
60 const char *s = luaL_checklstring(L, 1, &l); 70 const char *s = luaL_checklstring(L, 1, &l);
61 luaL_buffinit(L, &b); 71 char *p = luaL_buffinitsize(L, &b, l);
62 while (l--) luaL_addchar(&b, s[l]); 72 for (i = 0; i < l; i++)
63 luaL_pushresult(&b); 73 p[i] = s[l - i - 1];
74 luaL_pushresultsize(&b, l);
64 return 1; 75 return 1;
65} 76}
66 77
@@ -70,10 +81,10 @@ static int str_lower (lua_State *L) {
70 size_t i; 81 size_t i;
71 luaL_Buffer b; 82 luaL_Buffer b;
72 const char *s = luaL_checklstring(L, 1, &l); 83 const char *s = luaL_checklstring(L, 1, &l);
73 luaL_buffinit(L, &b); 84 char *p = luaL_buffinitsize(L, &b, l);
74 for (i=0; i<l; i++) 85 for (i=0; i<l; i++)
75 luaL_addchar(&b, tolower(uchar(s[i]))); 86 p[i] = tolower(uchar(s[i]));
76 luaL_pushresult(&b); 87 luaL_pushresultsize(&b, l);
77 return 1; 88 return 1;
78} 89}
79 90
@@ -83,22 +94,38 @@ static int str_upper (lua_State *L) {
83 size_t i; 94 size_t i;
84 luaL_Buffer b; 95 luaL_Buffer b;
85 const char *s = luaL_checklstring(L, 1, &l); 96 const char *s = luaL_checklstring(L, 1, &l);
86 luaL_buffinit(L, &b); 97 char *p = luaL_buffinitsize(L, &b, l);
87 for (i=0; i<l; i++) 98 for (i=0; i<l; i++)
88 luaL_addchar(&b, toupper(uchar(s[i]))); 99 p[i] = toupper(uchar(s[i]));
89 luaL_pushresult(&b); 100 luaL_pushresultsize(&b, l);
90 return 1; 101 return 1;
91} 102}
92 103
104
105/* reasonable limit to avoid arithmetic overflow */
106#define MAXSIZE ((~(size_t)0) >> 1)
107
93static int str_rep (lua_State *L) { 108static int str_rep (lua_State *L) {
94 size_t l; 109 size_t l, lsep;
95 luaL_Buffer b;
96 const char *s = luaL_checklstring(L, 1, &l); 110 const char *s = luaL_checklstring(L, 1, &l);
97 int n = luaL_checkint(L, 2); 111 int n = luaL_checkint(L, 2);
98 luaL_buffinit(L, &b); 112 const char *sep = luaL_optlstring(L, 3, "", &lsep);
99 while (n-- > 0) 113 if (n <= 0) lua_pushliteral(L, "");
100 luaL_addlstring(&b, s, l); 114 else if (l + lsep < l || l + lsep >= MAXSIZE / n) /* may overflow? */
101 luaL_pushresult(&b); 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 }
102 return 1; 129 return 1;
103} 130}
104 131
@@ -106,15 +133,15 @@ static int str_rep (lua_State *L) {
106static int str_byte (lua_State *L) { 133static int str_byte (lua_State *L) {
107 size_t l; 134 size_t l;
108 const char *s = luaL_checklstring(L, 1, &l); 135 const char *s = luaL_checklstring(L, 1, &l);
109 ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l); 136 size_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
110 ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l); 137 size_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
111 int n, i; 138 int n, i;
112 if (posi <= 0) posi = 1; 139 if (posi < 1) posi = 1;
113 if ((size_t)pose > l) pose = l; 140 if (pose > l) pose = l;
114 if (posi > pose) return 0; /* empty interval; return no values */ 141 if (posi > pose) return 0; /* empty interval; return no values */
115 n = (int)(pose - posi + 1); 142 n = (int)(pose - posi + 1);
116 if (posi + n <= pose) /* overflow? */ 143 if (posi + n <= pose) /* (size_t -> int) overflow? */
117 luaL_error(L, "string slice too long"); 144 return luaL_error(L, "string slice too long");
118 luaL_checkstack(L, n, "string slice too long"); 145 luaL_checkstack(L, n, "string slice too long");
119 for (i=0; i<n; i++) 146 for (i=0; i<n; i++)
120 lua_pushinteger(L, uchar(s[posi+i-1])); 147 lua_pushinteger(L, uchar(s[posi+i-1]));
@@ -126,13 +153,13 @@ static int str_char (lua_State *L) {
126 int n = lua_gettop(L); /* number of arguments */ 153 int n = lua_gettop(L); /* number of arguments */
127 int i; 154 int i;
128 luaL_Buffer b; 155 luaL_Buffer b;
129 luaL_buffinit(L, &b); 156 char *p = luaL_buffinitsize(L, &b, n);
130 for (i=1; i<=n; i++) { 157 for (i=1; i<=n; i++) {
131 int c = luaL_checkint(L, i); 158 int c = luaL_checkint(L, i);
132 luaL_argcheck(L, uchar(c) == c, i, "invalid value"); 159 luaL_argcheck(L, uchar(c) == c, i, "value out of range");
133 luaL_addchar(&b, uchar(c)); 160 p[i - 1] = uchar(c);
134 } 161 }
135 luaL_pushresult(&b); 162 luaL_pushresultsize(&b, n);
136 return 1; 163 return 1;
137} 164}
138 165
@@ -150,7 +177,7 @@ static int str_dump (lua_State *L) {
150 lua_settop(L, 1); 177 lua_settop(L, 1);
151 luaL_buffinit(L,&b); 178 luaL_buffinit(L,&b);
152 if (lua_dump(L, writer, &b) != 0) 179 if (lua_dump(L, writer, &b) != 0)
153 luaL_error(L, "unable to dump given function"); 180 return luaL_error(L, "unable to dump given function");
154 luaL_pushresult(&b); 181 luaL_pushresult(&b);
155 return 1; 182 return 1;
156} 183}
@@ -167,9 +194,12 @@ static int str_dump (lua_State *L) {
167#define CAP_UNFINISHED (-1) 194#define CAP_UNFINISHED (-1)
168#define CAP_POSITION (-2) 195#define CAP_POSITION (-2)
169 196
197
170typedef struct MatchState { 198typedef struct MatchState {
199 int matchdepth; /* control for recursive depth (to avoid C stack overflow) */
171 const char *src_init; /* init of source string */ 200 const char *src_init; /* init of source string */
172 const char *src_end; /* end (`\0') of source string */ 201 const char *src_end; /* end ('\0') of source string */
202 const char *p_end; /* end ('\0') of pattern */
173 lua_State *L; 203 lua_State *L;
174 int level; /* total number of captures (finished or unfinished) */ 204 int level; /* total number of captures (finished or unfinished) */
175 struct { 205 struct {
@@ -179,6 +209,16 @@ typedef struct MatchState {
179} MatchState; 209} MatchState;
180 210
181 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
182#define L_ESC '%' 222#define L_ESC '%'
183#define SPECIALS "^$*+?.([%-" 223#define SPECIALS "^$*+?.([%-"
184 224
@@ -186,7 +226,7 @@ typedef struct MatchState {
186static int check_capture (MatchState *ms, int l) { 226static int check_capture (MatchState *ms, int l) {
187 l -= '1'; 227 l -= '1';
188 if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED) 228 if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
189 return luaL_error(ms->L, "invalid capture index"); 229 return luaL_error(ms->L, "invalid capture index %%%d", l + 1);
190 return l; 230 return l;
191} 231}
192 232
@@ -202,16 +242,16 @@ static int capture_to_close (MatchState *ms) {
202static const char *classend (MatchState *ms, const char *p) { 242static const char *classend (MatchState *ms, const char *p) {
203 switch (*p++) { 243 switch (*p++) {
204 case L_ESC: { 244 case L_ESC: {
205 if (*p == '\0') 245 if (p == ms->p_end)
206 luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); 246 luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")");
207 return p+1; 247 return p+1;
208 } 248 }
209 case '[': { 249 case '[': {
210 if (*p == '^') p++; 250 if (*p == '^') p++;
211 do { /* look for a `]' */ 251 do { /* look for a `]' */
212 if (*p == '\0') 252 if (p == ms->p_end)
213 luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); 253 luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")");
214 if (*(p++) == L_ESC && *p != '\0') 254 if (*(p++) == L_ESC && p < ms->p_end)
215 p++; /* skip escapes (e.g. `%]') */ 255 p++; /* skip escapes (e.g. `%]') */
216 } while (*p != ']'); 256 } while (*p != ']');
217 return p+1; 257 return p+1;
@@ -229,13 +269,14 @@ static int match_class (int c, int cl) {
229 case 'a' : res = isalpha(c); break; 269 case 'a' : res = isalpha(c); break;
230 case 'c' : res = iscntrl(c); break; 270 case 'c' : res = iscntrl(c); break;
231 case 'd' : res = isdigit(c); break; 271 case 'd' : res = isdigit(c); break;
272 case 'g' : res = isgraph(c); break;
232 case 'l' : res = islower(c); break; 273 case 'l' : res = islower(c); break;
233 case 'p' : res = ispunct(c); break; 274 case 'p' : res = ispunct(c); break;
234 case 's' : res = isspace(c); break; 275 case 's' : res = isspace(c); break;
235 case 'u' : res = isupper(c); break; 276 case 'u' : res = isupper(c); break;
236 case 'w' : res = isalnum(c); break; 277 case 'w' : res = isalnum(c); break;
237 case 'x' : res = isxdigit(c); break; 278 case 'x' : res = isxdigit(c); break;
238 case 'z' : res = (c == 0); break; 279 case 'z' : res = (c == 0); break; /* deprecated option */
239 default: return (cl == c); 280 default: return (cl == c);
240 } 281 }
241 return (islower(cl) ? res : !res); 282 return (islower(cl) ? res : !res);
@@ -265,23 +306,27 @@ static int matchbracketclass (int c, const char *p, const char *ec) {
265} 306}
266 307
267 308
268static int singlematch (int c, const char *p, const char *ep) { 309static int singlematch (MatchState *ms, const char *s, const char *p,
269 switch (*p) { 310 const char *ep) {
270 case '.': return 1; /* matches any char */ 311 if (s >= ms->src_end)
271 case L_ESC: return match_class(c, uchar(*(p+1))); 312 return 0;
272 case '[': return matchbracketclass(c, p, ep-1); 313 else {
273 default: return (uchar(*p) == c); 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 }
274 } 321 }
275} 322}
276 323
277 324
278static const char *match (MatchState *ms, const char *s, const char *p);
279
280
281static const char *matchbalance (MatchState *ms, const char *s, 325static const char *matchbalance (MatchState *ms, const char *s,
282 const char *p) { 326 const char *p) {
283 if (*p == 0 || *(p+1) == 0) 327 if (p >= ms->p_end - 1)
284 luaL_error(ms->L, "unbalanced pattern"); 328 luaL_error(ms->L, "malformed pattern "
329 "(missing arguments to " LUA_QL("%%b") ")");
285 if (*s != *p) return NULL; 330 if (*s != *p) return NULL;
286 else { 331 else {
287 int b = *p; 332 int b = *p;
@@ -301,7 +346,7 @@ static const char *matchbalance (MatchState *ms, const char *s,
301static const char *max_expand (MatchState *ms, const char *s, 346static const char *max_expand (MatchState *ms, const char *s,
302 const char *p, const char *ep) { 347 const char *p, const char *ep) {
303 ptrdiff_t i = 0; /* counts maximum expand for item */ 348 ptrdiff_t i = 0; /* counts maximum expand for item */
304 while ((s+i)<ms->src_end && singlematch(uchar(*(s+i)), p, ep)) 349 while (singlematch(ms, s + i, p, ep))
305 i++; 350 i++;
306 /* keeps trying to match with the maximum repetitions */ 351 /* keeps trying to match with the maximum repetitions */
307 while (i>=0) { 352 while (i>=0) {
@@ -319,7 +364,7 @@ static const char *min_expand (MatchState *ms, const char *s,
319 const char *res = match(ms, s, ep+1); 364 const char *res = match(ms, s, ep+1);
320 if (res != NULL) 365 if (res != NULL)
321 return res; 366 return res;
322 else if (s<ms->src_end && singlematch(uchar(*s), p, ep)) 367 else if (singlematch(ms, s, p, ep))
323 s++; /* try with one more repetition */ 368 s++; /* try with one more repetition */
324 else return NULL; 369 else return NULL;
325 } 370 }
@@ -363,80 +408,105 @@ static const char *match_capture (MatchState *ms, const char *s, int l) {
363 408
364 409
365static const char *match (MatchState *ms, const char *s, const char *p) { 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");
366 init: /* using goto's to optimize tail recursion */ 413 init: /* using goto's to optimize tail recursion */
367 switch (*p) { 414 if (p != ms->p_end) { /* end of pattern? */
368 case '(': { /* start capture */ 415 switch (*p) {
369 if (*(p+1) == ')') /* position capture? */ 416 case '(': { /* start capture */
370 return start_capture(ms, s, p+2, CAP_POSITION); 417 if (*(p + 1) == ')') /* position capture? */
371 else 418 s = start_capture(ms, s, p + 2, CAP_POSITION);
372 return start_capture(ms, s, p+1, CAP_UNFINISHED); 419 else
373 } 420 s = start_capture(ms, s, p + 1, CAP_UNFINISHED);
374 case ')': { /* end capture */ 421 break;
375 return end_capture(ms, s, p+1); 422 }
376 } 423 case ')': { /* end capture */
377 case L_ESC: { 424 s = end_capture(ms, s, p + 1);
378 switch (*(p+1)) { 425 break;
379 case 'b': { /* balanced string? */ 426 }
380 s = matchbalance(ms, s, p+2); 427 case '$': {
381 if (s == NULL) return NULL; 428 if ((p + 1) != ms->p_end) /* is the `$' the last char in pattern? */
382 p+=4; goto init; /* else return match(ms, s, p+4); */ 429 goto dflt; /* no; go to default */
383 } 430 s = (s == ms->src_end) ? s : NULL; /* check end of string */
384 case 'f': { /* frontier? */ 431 break;
385 const char *ep; char previous; 432 }
386 p += 2; 433 case L_ESC: { /* escaped sequences not in the format class[*+?-]? */
387 if (*p != '[') 434 switch (*(p + 1)) {
388 luaL_error(ms->L, "missing " LUA_QL("[") " after " 435 case 'b': { /* balanced string? */
389 LUA_QL("%%f") " in pattern"); 436 s = matchbalance(ms, s, p + 2);
390 ep = classend(ms, p); /* points to what is next */ 437 if (s != NULL) {
391 previous = (s == ms->src_init) ? '\0' : *(s-1); 438 p += 4; goto init; /* return match(ms, s, p + 4); */
392 if (matchbracketclass(uchar(previous), p, ep-1) || 439 } /* else fail (s == NULL) */
393 !matchbracketclass(uchar(*s), p, ep-1)) return NULL; 440 break;
394 p=ep; goto init; /* else return match(ms, s, ep); */ 441 }
395 } 442 case 'f': { /* frontier? */
396 default: { 443 const char *ep; char previous;
397 if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */ 444 p += 2;
398 s = match_capture(ms, s, uchar(*(p+1))); 445 if (*p != '[')
399 if (s == NULL) return NULL; 446 luaL_error(ms->L, "missing " LUA_QL("[") " after "
400 p+=2; goto init; /* else return match(ms, s, p+2) */ 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;
401 } 456 }
402 goto dflt; /* case default */ 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;
403 } 467 }
468 break;
404 } 469 }
405 } 470 default: dflt: { /* pattern class plus optional suffix */
406 case '\0': { /* end of pattern */ 471 const char *ep = classend(ms, p); /* points to optional suffix */
407 return s; /* match succeeded */ 472 /* does not match at least once? */
408 } 473 if (!singlematch(ms, s, p, ep)) {
409 case '$': { 474 if (*ep == '*' || *ep == '?' || *ep == '-') { /* accept empty? */
410 if (*(p+1) == '\0') /* is the `$' the last char in pattern? */ 475 p = ep + 1; goto init; /* return match(ms, s, ep + 1); */
411 return (s == ms->src_end) ? s : NULL; /* check end of string */ 476 }
412 else goto dflt; 477 else /* '+' or no suffix */
413 } 478 s = NULL; /* fail */
414 default: dflt: { /* it is a pattern item */
415 const char *ep = classend(ms, p); /* points to what is next */
416 int m = s<ms->src_end && singlematch(uchar(*s), p, ep);
417 switch (*ep) {
418 case '?': { /* optional */
419 const char *res;
420 if (m && ((res=match(ms, s+1, ep+1)) != NULL))
421 return res;
422 p=ep+1; goto init; /* else return match(ms, s, ep+1); */
423 }
424 case '*': { /* 0 or more repetitions */
425 return max_expand(ms, s, p, ep);
426 }
427 case '+': { /* 1 or more repetitions */
428 return (m ? max_expand(ms, s+1, p, ep) : NULL);
429 }
430 case '-': { /* 0 or more repetitions (minimum) */
431 return min_expand(ms, s, p, ep);
432 } 479 }
433 default: { 480 else { /* matched once */
434 if (!m) return NULL; 481 switch (*ep) { /* handle optional suffix */
435 s++; p=ep; goto init; /* else return match(ms, s+1, ep); */ 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 }
436 } 503 }
504 break;
437 } 505 }
438 } 506 }
439 } 507 }
508 ms->matchdepth++;
509 return s;
440} 510}
441 511
442 512
@@ -492,37 +562,58 @@ static int push_captures (MatchState *ms, const char *s, const char *e) {
492} 562}
493 563
494 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
495static int str_find_aux (lua_State *L, int find) { 577static int str_find_aux (lua_State *L, int find) {
496 size_t l1, l2; 578 size_t ls, lp;
497 const char *s = luaL_checklstring(L, 1, &l1); 579 const char *s = luaL_checklstring(L, 1, &ls);
498 const char *p = luaL_checklstring(L, 2, &l2); 580 const char *p = luaL_checklstring(L, 2, &lp);
499 ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1; 581 size_t init = posrelat(luaL_optinteger(L, 3, 1), ls);
500 if (init < 0) init = 0; 582 if (init < 1) init = 1;
501 else if ((size_t)(init) > l1) init = (ptrdiff_t)l1; 583 else if (init > ls + 1) { /* start after string's end? */
502 if (find && (lua_toboolean(L, 4) || /* explicit request? */ 584 lua_pushnil(L); /* cannot find anything */
503 strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */ 585 return 1;
586 }
587 /* explicit request or no special characters? */
588 if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) {
504 /* do a plain search */ 589 /* do a plain search */
505 const char *s2 = lmemfind(s+init, l1-init, p, l2); 590 const char *s2 = lmemfind(s + init - 1, ls - init + 1, p, lp);
506 if (s2) { 591 if (s2) {
507 lua_pushinteger(L, s2-s+1); 592 lua_pushinteger(L, s2 - s + 1);
508 lua_pushinteger(L, s2-s+l2); 593 lua_pushinteger(L, s2 - s + lp);
509 return 2; 594 return 2;
510 } 595 }
511 } 596 }
512 else { 597 else {
513 MatchState ms; 598 MatchState ms;
514 int anchor = (*p == '^') ? (p++, 1) : 0; 599 const char *s1 = s + init - 1;
515 const char *s1=s+init; 600 int anchor = (*p == '^');
601 if (anchor) {
602 p++; lp--; /* skip anchor character */
603 }
516 ms.L = L; 604 ms.L = L;
605 ms.matchdepth = MAXCCALLS;
517 ms.src_init = s; 606 ms.src_init = s;
518 ms.src_end = s+l1; 607 ms.src_end = s + ls;
608 ms.p_end = p + lp;
519 do { 609 do {
520 const char *res; 610 const char *res;
521 ms.level = 0; 611 ms.level = 0;
612 lua_assert(ms.matchdepth == MAXCCALLS);
522 if ((res=match(&ms, s1, p)) != NULL) { 613 if ((res=match(&ms, s1, p)) != NULL) {
523 if (find) { 614 if (find) {
524 lua_pushinteger(L, s1-s+1); /* start */ 615 lua_pushinteger(L, s1 - s + 1); /* start */
525 lua_pushinteger(L, res-s); /* end */ 616 lua_pushinteger(L, res - s); /* end */
526 return push_captures(&ms, NULL, 0) + 2; 617 return push_captures(&ms, NULL, 0) + 2;
527 } 618 }
528 else 619 else
@@ -547,18 +638,21 @@ static int str_match (lua_State *L) {
547 638
548static int gmatch_aux (lua_State *L) { 639static int gmatch_aux (lua_State *L) {
549 MatchState ms; 640 MatchState ms;
550 size_t ls; 641 size_t ls, lp;
551 const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); 642 const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
552 const char *p = lua_tostring(L, lua_upvalueindex(2)); 643 const char *p = lua_tolstring(L, lua_upvalueindex(2), &lp);
553 const char *src; 644 const char *src;
554 ms.L = L; 645 ms.L = L;
646 ms.matchdepth = MAXCCALLS;
555 ms.src_init = s; 647 ms.src_init = s;
556 ms.src_end = s+ls; 648 ms.src_end = s+ls;
649 ms.p_end = p + lp;
557 for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); 650 for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3));
558 src <= ms.src_end; 651 src <= ms.src_end;
559 src++) { 652 src++) {
560 const char *e; 653 const char *e;
561 ms.level = 0; 654 ms.level = 0;
655 lua_assert(ms.matchdepth == MAXCCALLS);
562 if ((e = match(&ms, src, p)) != NULL) { 656 if ((e = match(&ms, src, p)) != NULL) {
563 lua_Integer newstart = e-s; 657 lua_Integer newstart = e-s;
564 if (e == src) newstart++; /* empty match? go at least one position */ 658 if (e == src) newstart++; /* empty match? go at least one position */
@@ -581,12 +675,6 @@ static int gmatch (lua_State *L) {
581} 675}
582 676
583 677
584static int gfind_nodef (lua_State *L) {
585 return luaL_error(L, LUA_QL("string.gfind") " was renamed to "
586 LUA_QL("string.gmatch"));
587}
588
589
590static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, 678static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
591 const char *e) { 679 const char *e) {
592 size_t l, i; 680 size_t l, i;
@@ -596,8 +684,12 @@ static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
596 luaL_addchar(b, news[i]); 684 luaL_addchar(b, news[i]);
597 else { 685 else {
598 i++; /* skip ESC */ 686 i++; /* skip ESC */
599 if (!isdigit(uchar(news[i]))) 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);
600 luaL_addchar(b, news[i]); 691 luaL_addchar(b, news[i]);
692 }
601 else if (news[i] == '0') 693 else if (news[i] == '0')
602 luaL_addlstring(b, s, e - s); 694 luaL_addlstring(b, s, e - s);
603 else { 695 else {
@@ -610,14 +702,9 @@ static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
610 702
611 703
612static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, 704static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
613 const char *e) { 705 const char *e, int tr) {
614 lua_State *L = ms->L; 706 lua_State *L = ms->L;
615 switch (lua_type(L, 3)) { 707 switch (tr) {
616 case LUA_TNUMBER:
617 case LUA_TSTRING: {
618 add_s(ms, b, s, e);
619 return;
620 }
621 case LUA_TFUNCTION: { 708 case LUA_TFUNCTION: {
622 int n; 709 int n;
623 lua_pushvalue(L, 3); 710 lua_pushvalue(L, 3);
@@ -630,41 +717,51 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
630 lua_gettable(L, 3); 717 lua_gettable(L, 3);
631 break; 718 break;
632 } 719 }
720 default: { /* LUA_TNUMBER or LUA_TSTRING */
721 add_s(ms, b, s, e);
722 return;
723 }
633 } 724 }
634 if (!lua_toboolean(L, -1)) { /* nil or false? */ 725 if (!lua_toboolean(L, -1)) { /* nil or false? */
635 lua_pop(L, 1); 726 lua_pop(L, 1);
636 lua_pushlstring(L, s, e - s); /* keep original text */ 727 lua_pushlstring(L, s, e - s); /* keep original text */
637 } 728 }
638 else if (!lua_isstring(L, -1)) 729 else if (!lua_isstring(L, -1))
639 luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); 730 luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
640 luaL_addvalue(b); /* add result to accumulator */ 731 luaL_addvalue(b); /* add result to accumulator */
641} 732}
642 733
643 734
644static int str_gsub (lua_State *L) { 735static int str_gsub (lua_State *L) {
645 size_t srcl; 736 size_t srcl, lp;
646 const char *src = luaL_checklstring(L, 1, &srcl); 737 const char *src = luaL_checklstring(L, 1, &srcl);
647 const char *p = luaL_checkstring(L, 2); 738 const char *p = luaL_checklstring(L, 2, &lp);
648 int tr = lua_type(L, 3); 739 int tr = lua_type(L, 3);
649 int max_s = luaL_optint(L, 4, srcl+1); 740 size_t max_s = luaL_optinteger(L, 4, srcl+1);
650 int anchor = (*p == '^') ? (p++, 1) : 0; 741 int anchor = (*p == '^');
651 int n = 0; 742 size_t n = 0;
652 MatchState ms; 743 MatchState ms;
653 luaL_Buffer b; 744 luaL_Buffer b;
654 luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || 745 luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
655 tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, 746 tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
656 "string/function/table expected"); 747 "string/function/table expected");
657 luaL_buffinit(L, &b); 748 luaL_buffinit(L, &b);
749 if (anchor) {
750 p++; lp--; /* skip anchor character */
751 }
658 ms.L = L; 752 ms.L = L;
753 ms.matchdepth = MAXCCALLS;
659 ms.src_init = src; 754 ms.src_init = src;
660 ms.src_end = src+srcl; 755 ms.src_end = src+srcl;
756 ms.p_end = p + lp;
661 while (n < max_s) { 757 while (n < max_s) {
662 const char *e; 758 const char *e;
663 ms.level = 0; 759 ms.level = 0;
760 lua_assert(ms.matchdepth == MAXCCALLS);
664 e = match(&ms, src, p); 761 e = match(&ms, src, p);
665 if (e) { 762 if (e) {
666 n++; 763 n++;
667 add_value(&ms, &b, src, e); 764 add_value(&ms, &b, src, e, tr);
668 } 765 }
669 if (e && e>src) /* non empty match? */ 766 if (e && e>src) /* non empty match? */
670 src = e; /* skip it */ 767 src = e; /* skip it */
@@ -682,6 +779,46 @@ static int str_gsub (lua_State *L) {
682/* }====================================================== */ 779/* }====================================================== */
683 780
684 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
685/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ 822/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
686#define MAX_ITEM 512 823#define MAX_ITEM 512
687/* valid flags in a format specification */ 824/* valid flags in a format specification */
@@ -698,25 +835,20 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
698 const char *s = luaL_checklstring(L, arg, &l); 835 const char *s = luaL_checklstring(L, arg, &l);
699 luaL_addchar(b, '"'); 836 luaL_addchar(b, '"');
700 while (l--) { 837 while (l--) {
701 switch (*s) { 838 if (*s == '"' || *s == '\\' || *s == '\n') {
702 case '"': case '\\': case '\n': { 839 luaL_addchar(b, '\\');
703 luaL_addchar(b, '\\'); 840 luaL_addchar(b, *s);
704 luaL_addchar(b, *s);
705 break;
706 }
707 case '\r': {
708 luaL_addlstring(b, "\\r", 2);
709 break;
710 }
711 case '\0': {
712 luaL_addlstring(b, "\\000", 4);
713 break;
714 }
715 default: {
716 luaL_addchar(b, *s);
717 break;
718 }
719 } 841 }
842 else if (*s == '\0' || iscntrl(uchar(*s))) {
843 char buff[10];
844 if (!isdigit(uchar(*(s+1))))
845 snprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s));
846 else
847 snprintf(buff, sizeof(buff), "\\%03d", (int)uchar(*s));
848 luaL_addstring(b, buff);
849 }
850 else
851 luaL_addchar(b, *s);
720 s++; 852 s++;
721 } 853 }
722 luaL_addchar(b, '"'); 854 luaL_addchar(b, '"');
@@ -725,7 +857,7 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
725static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { 857static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
726 const char *p = strfrmt; 858 const char *p = strfrmt;
727 while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ 859 while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */
728 if ((size_t)(p - strfrmt) >= sizeof(FLAGS)) 860 if ((size_t)(p - strfrmt) >= sizeof(FLAGS)/sizeof(char))
729 luaL_error(L, "invalid format (repeated flags)"); 861 luaL_error(L, "invalid format (repeated flags)");
730 if (isdigit(uchar(*p))) p++; /* skip width */ 862 if (isdigit(uchar(*p))) p++; /* skip width */
731 if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ 863 if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
@@ -737,23 +869,28 @@ static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
737 if (isdigit(uchar(*p))) 869 if (isdigit(uchar(*p)))
738 luaL_error(L, "invalid format (width or precision too long)"); 870 luaL_error(L, "invalid format (width or precision too long)");
739 *(form++) = '%'; 871 *(form++) = '%';
740 strncpy(form, strfrmt, p - strfrmt + 1); 872 memcpy(form, strfrmt, (p - strfrmt + 1) * sizeof(char));
741 form += p - strfrmt + 1; 873 form += p - strfrmt + 1;
742 *form = '\0'; 874 *form = '\0';
743 return p; 875 return p;
744} 876}
745 877
746 878
747static void addintlen (char *form) { 879/*
880** add length modifier into formats
881*/
882static void addlenmod (char *form, const char *lenmod) {
748 size_t l = strlen(form); 883 size_t l = strlen(form);
884 size_t lm = strlen(lenmod);
749 char spec = form[l - 1]; 885 char spec = form[l - 1];
750 strcpy(form + l - 1, LUA_INTFRMLEN); 886 strcpy(form + l - 1, lenmod);
751 form[l + sizeof(LUA_INTFRMLEN) - 2] = spec; 887 form[l + lm - 1] = spec;
752 form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0'; 888 form[l + lm] = '\0';
753} 889}
754 890
755 891
756static int str_format (lua_State *L) { 892static int str_format (lua_State *L) {
893 int top = lua_gettop(L);
757 int arg = 1; 894 int arg = 1;
758 size_t sfl; 895 size_t sfl;
759 const char *strfrmt = luaL_checklstring(L, arg, &sfl); 896 const char *strfrmt = luaL_checklstring(L, arg, &sfl);
@@ -767,45 +904,61 @@ static int str_format (lua_State *L) {
767 luaL_addchar(&b, *strfrmt++); /* %% */ 904 luaL_addchar(&b, *strfrmt++); /* %% */
768 else { /* format item */ 905 else { /* format item */
769 char form[MAX_FORMAT]; /* to store the format (`%...') */ 906 char form[MAX_FORMAT]; /* to store the format (`%...') */
770 char buff[MAX_ITEM]; /* to store the formatted item */ 907 char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */
771 arg++; 908 int nb = 0; /* number of bytes in added item */
909 if (++arg > top)
910 luaL_argerror(L, arg, "no value");
772 strfrmt = scanformat(L, strfrmt, form); 911 strfrmt = scanformat(L, strfrmt, form);
773 switch (*strfrmt++) { 912 switch (*strfrmt++) {
774 case 'c': { 913 case 'c': {
775 snprintf(buff, MAX_ITEM, form, (int)luaL_checknumber(L, arg)); 914 nb = snprintf(buff, MAX_ITEM, form, luaL_checkint(L, arg));
776 break; 915 break;
777 } 916 }
778 case 'd': case 'i': { 917 case 'd': case 'i': {
779 addintlen(form); 918 lua_Number n = luaL_checknumber(L, arg);
780 snprintf(buff, MAX_ITEM, form, (LUA_INTFRM_T)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 = snprintf(buff, MAX_ITEM, form, ni);
781 break; 925 break;
782 } 926 }
783 case 'o': case 'u': case 'x': case 'X': { 927 case 'o': case 'u': case 'x': case 'X': {
784 addintlen(form); 928 lua_Number n = luaL_checknumber(L, arg);
785 snprintf(buff, MAX_ITEM, form, (unsigned LUA_INTFRM_T)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 = snprintf(buff, MAX_ITEM, form, ni);
786 break; 935 break;
787 } 936 }
788 case 'e': case 'E': case 'f': 937 case 'e': case 'E': case 'f':
938#if defined(LUA_USE_AFORMAT)
939 case 'a': case 'A':
940#endif
789 case 'g': case 'G': { 941 case 'g': case 'G': {
790 snprintf(buff, MAX_ITEM, form, (double)luaL_checknumber(L, arg)); 942 addlenmod(form, LUA_FLTFRMLEN);
943 nb = snprintf(buff, MAX_ITEM, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg));
791 break; 944 break;
792 } 945 }
793 case 'q': { 946 case 'q': {
794 addquoted(L, &b, arg); 947 addquoted(L, &b, arg);
795 continue; /* skip the 'addsize' at the end */ 948 break;
796 } 949 }
797 case 's': { 950 case 's': {
798 size_t l; 951 size_t l;
799 const char *s = luaL_checklstring(L, arg, &l); 952 const char *s = luaL_tolstring(L, arg, &l);
800 if (!strchr(form, '.') && l >= 100) { 953 if (!strchr(form, '.') && l >= 100) {
801 /* no precision and string is too long to be formatted; 954 /* no precision and string is too long to be formatted;
802 keep original string */ 955 keep original string */
803 lua_pushvalue(L, arg);
804 luaL_addvalue(&b); 956 luaL_addvalue(&b);
805 continue; /* skip the `addsize' at the end */ 957 break;
806 } 958 }
807 else { 959 else {
808 snprintf(buff, MAX_ITEM, form, s); 960 nb = snprintf(buff, MAX_ITEM, form, s);
961 lua_pop(L, 1); /* remove result from 'luaL_tolstring' */
809 break; 962 break;
810 } 963 }
811 } 964 }
@@ -814,13 +967,15 @@ static int str_format (lua_State *L) {
814 LUA_QL("format"), *(strfrmt - 1)); 967 LUA_QL("format"), *(strfrmt - 1));
815 } 968 }
816 } 969 }
817 luaL_addlstring(&b, buff, strlen(buff)); 970 luaL_addsize(&b, nb);
818 } 971 }
819 } 972 }
820 luaL_pushresult(&b); 973 luaL_pushresult(&b);
821 return 1; 974 return 1;
822} 975}
823 976
977/* }====================================================== */
978
824 979
825static const luaL_Reg strlib[] = { 980static const luaL_Reg strlib[] = {
826 {"byte", str_byte}, 981 {"byte", str_byte},
@@ -828,7 +983,6 @@ static const luaL_Reg strlib[] = {
828 {"dump", str_dump}, 983 {"dump", str_dump},
829 {"find", str_find}, 984 {"find", str_find},
830 {"format", str_format}, 985 {"format", str_format},
831 {"gfind", gfind_nodef},
832 {"gmatch", gmatch}, 986 {"gmatch", gmatch},
833 {"gsub", str_gsub}, 987 {"gsub", str_gsub},
834 {"len", str_len}, 988 {"len", str_len},
@@ -843,13 +997,13 @@ static const luaL_Reg strlib[] = {
843 997
844 998
845static void createmetatable (lua_State *L) { 999static void createmetatable (lua_State *L) {
846 lua_createtable(L, 0, 1); /* create metatable for strings */ 1000 lua_createtable(L, 0, 1); /* table to be metatable for strings */
847 lua_pushliteral(L, ""); /* dummy string */ 1001 lua_pushliteral(L, ""); /* dummy string */
848 lua_pushvalue(L, -2); 1002 lua_pushvalue(L, -2); /* copy table */
849 lua_setmetatable(L, -2); /* set string metatable */ 1003 lua_setmetatable(L, -2); /* set table as metatable for strings */
850 lua_pop(L, 1); /* pop dummy string */ 1004 lua_pop(L, 1); /* pop dummy string */
851 lua_pushvalue(L, -2); /* string library... */ 1005 lua_pushvalue(L, -2); /* get string library */
852 lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */ 1006 lua_setfield(L, -2, "__index"); /* metatable.__index = string */
853 lua_pop(L, 1); /* pop metatable */ 1007 lua_pop(L, 1); /* pop metatable */
854} 1008}
855 1009
@@ -857,12 +1011,8 @@ static void createmetatable (lua_State *L) {
857/* 1011/*
858** Open string library 1012** Open string library
859*/ 1013*/
860LUALIB_API int luaopen_string (lua_State *L) { 1014LUAMOD_API int luaopen_string (lua_State *L) {
861 luaL_register(L, LUA_STRLIBNAME, strlib); 1015 luaL_newlib(L, strlib);
862#if defined(LUA_COMPAT_GFIND)
863 lua_getfield(L, -1, "gmatch");
864 lua_setfield(L, -2, "gfind");
865#endif
866 createmetatable(L); 1016 createmetatable(L);
867 return 1; 1017 return 1;
868} 1018}
diff --git a/apps/plugins/lua/ltable.c b/apps/plugins/lua/ltable.c
index ec84f4fabc..e0fe98ce3e 100644
--- a/apps/plugins/lua/ltable.c
+++ b/apps/plugins/lua/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 roberto Exp $ 2** $Id: ltable.c,v 2.72.1.1 2013/04/12 18:48:47 roberto Exp $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -18,7 +18,6 @@
18** Hence even when the load factor reaches 100%, performance remains good. 18** Hence even when the load factor reaches 100%, performance remains good.
19*/ 19*/
20 20
21#include <math.h>
22#include <string.h> 21#include <string.h>
23 22
24#define ltable_c 23#define ltable_c
@@ -32,14 +31,16 @@
32#include "lmem.h" 31#include "lmem.h"
33#include "lobject.h" 32#include "lobject.h"
34#include "lstate.h" 33#include "lstate.h"
34#include "lstring.h"
35#include "ltable.h" 35#include "ltable.h"
36#include "lvm.h"
36 37
37 38
38/* 39/*
39** max size of array part is 2^MAXBITS 40** max size of array part is 2^MAXBITS
40*/ 41*/
41#if LUAI_BITSINT > 26 42#if LUAI_BITSINT >= 32
42#define MAXBITS 26 43#define MAXBITS 30
43#else 44#else
44#define MAXBITS (LUAI_BITSINT-2) 45#define MAXBITS (LUAI_BITSINT-2)
45#endif 46#endif
@@ -47,10 +48,10 @@
47#define MAXASIZE (1 << MAXBITS) 48#define MAXASIZE (1 << MAXBITS)
48 49
49 50
50#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) 51#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
51 52
52#define hashstr(t,str) hashpow2(t, (str)->tsv.hash) 53#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
53#define hashboolean(t,p) hashpow2(t, p) 54#define hashboolean(t,p) hashpow2(t, p)
54 55
55 56
56/* 57/*
@@ -72,9 +73,11 @@
72 73
73#define dummynode (&dummynode_) 74#define dummynode (&dummynode_)
74 75
76#define isdummy(n) ((n) == dummynode)
77
75static const Node dummynode_ = { 78static const Node dummynode_ = {
76 {{NULL}, LUA_TNIL}, /* value */ 79 {NILCONSTANT}, /* value */
77 {{{NULL}, LUA_TNIL, NULL}} /* key */ 80 {{NILCONSTANT, NULL}} /* key */
78}; 81};
79 82
80 83
@@ -101,12 +104,22 @@ static Node *mainposition (const Table *t, const TValue *key) {
101 switch (ttype(key)) { 104 switch (ttype(key)) {
102 case LUA_TNUMBER: 105 case LUA_TNUMBER:
103 return hashnum(t, nvalue(key)); 106 return hashnum(t, nvalue(key));
104 case LUA_TSTRING: 107 case LUA_TLNGSTR: {
108 TString *s = rawtsvalue(key);
109 if (s->tsv.extra == 0) { /* no hash? */
110 s->tsv.hash = luaS_hash(getstr(s), s->tsv.len, s->tsv.hash);
111 s->tsv.extra = 1; /* now it has its hash */
112 }
113 return hashstr(t, rawtsvalue(key));
114 }
115 case LUA_TSHRSTR:
105 return hashstr(t, rawtsvalue(key)); 116 return hashstr(t, rawtsvalue(key));
106 case LUA_TBOOLEAN: 117 case LUA_TBOOLEAN:
107 return hashboolean(t, bvalue(key)); 118 return hashboolean(t, bvalue(key));
108 case LUA_TLIGHTUSERDATA: 119 case LUA_TLIGHTUSERDATA:
109 return hashpointer(t, pvalue(key)); 120 return hashpointer(t, pvalue(key));
121 case LUA_TLCF:
122 return hashpointer(t, fvalue(key));
110 default: 123 default:
111 return hashpointer(t, gcvalue(key)); 124 return hashpointer(t, gcvalue(key));
112 } 125 }
@@ -132,7 +145,7 @@ static int arrayindex (const TValue *key) {
132/* 145/*
133** returns the index of a `key' for table traversals. First goes all 146** returns the index of a `key' for table traversals. First goes all
134** elements in the array part, then elements in the hash part. The 147** elements in the array part, then elements in the hash part. The
135** beginning of a traversal is signalled by -1. 148** beginning of a traversal is signaled by -1.
136*/ 149*/
137static int findindex (lua_State *L, Table *t, StkId key) { 150static int findindex (lua_State *L, Table *t, StkId key) {
138 int i; 151 int i;
@@ -142,19 +155,19 @@ static int findindex (lua_State *L, Table *t, StkId key) {
142 return i-1; /* yes; that's the index (corrected to C) */ 155 return i-1; /* yes; that's the index (corrected to C) */
143 else { 156 else {
144 Node *n = mainposition(t, key); 157 Node *n = mainposition(t, key);
145 do { /* check whether `key' is somewhere in the chain */ 158 for (;;) { /* check whether `key' is somewhere in the chain */
146 /* key may be dead already, but it is ok to use it in `next' */ 159 /* key may be dead already, but it is ok to use it in `next' */
147 if (luaO_rawequalObj(key2tval(n), key) || 160 if (luaV_rawequalobj(gkey(n), key) ||
148 (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) && 161 (ttisdeadkey(gkey(n)) && iscollectable(key) &&
149 gcvalue(gkey(n)) == gcvalue(key))) { 162 deadvalue(gkey(n)) == gcvalue(key))) {
150 i = cast_int(n - gnode(t, 0)); /* key index in hash table */ 163 i = cast_int(n - gnode(t, 0)); /* key index in hash table */
151 /* hash elements are numbered after array ones */ 164 /* hash elements are numbered after array ones */
152 return i + t->sizearray; 165 return i + t->sizearray;
153 } 166 }
154 else n = gnext(n); 167 else n = gnext(n);
155 } while (n); 168 if (n == NULL)
156 luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ 169 luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */
157 return 0; /* to avoid warnings */ 170 }
158 } 171 }
159} 172}
160 173
@@ -170,7 +183,7 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
170 } 183 }
171 for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ 184 for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
172 if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ 185 if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
173 setobj2s(L, key, key2tval(gnode(t, i))); 186 setobj2s(L, key, gkey(gnode(t, i)));
174 setobj2s(L, key+1, gval(gnode(t, i))); 187 setobj2s(L, key+1, gval(gnode(t, i)));
175 return 1; 188 return 1;
176 } 189 }
@@ -211,7 +224,7 @@ static int computesizes (int nums[], int *narray) {
211static int countint (const TValue *key, int *nums) { 224static int countint (const TValue *key, int *nums) {
212 int k = arrayindex(key); 225 int k = arrayindex(key);
213 if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ 226 if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */
214 nums[ceillog2(k)]++; /* count as such */ 227 nums[luaO_ceillog2(k)]++; /* count as such */
215 return 1; 228 return 1;
216 } 229 }
217 else 230 else
@@ -251,7 +264,7 @@ static int numusehash (const Table *t, int *nums, int *pnasize) {
251 while (i--) { 264 while (i--) {
252 Node *n = &t->node[i]; 265 Node *n = &t->node[i];
253 if (!ttisnil(gval(n))) { 266 if (!ttisnil(gval(n))) {
254 ause += countint(key2tval(n), nums); 267 ause += countint(gkey(n), nums);
255 totaluse++; 268 totaluse++;
256 } 269 }
257 } 270 }
@@ -277,7 +290,7 @@ static void setnodevector (lua_State *L, Table *t, int size) {
277 } 290 }
278 else { 291 else {
279 int i; 292 int i;
280 lsize = ceillog2(size); 293 lsize = luaO_ceillog2(size);
281 if (lsize > MAXBITS) 294 if (lsize > MAXBITS)
282 luaG_runerror(L, "table overflow"); 295 luaG_runerror(L, "table overflow");
283 size = twoto(lsize); 296 size = twoto(lsize);
@@ -294,7 +307,7 @@ static void setnodevector (lua_State *L, Table *t, int size) {
294} 307}
295 308
296 309
297static void resize (lua_State *L, Table *t, int nasize, int nhsize) { 310void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
298 int i; 311 int i;
299 int oldasize = t->sizearray; 312 int oldasize = t->sizearray;
300 int oldhsize = t->lsizenode; 313 int oldhsize = t->lsizenode;
@@ -302,13 +315,13 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
302 if (nasize > oldasize) /* array part must grow? */ 315 if (nasize > oldasize) /* array part must grow? */
303 setarrayvector(L, t, nasize); 316 setarrayvector(L, t, nasize);
304 /* create new hash part with appropriate size */ 317 /* create new hash part with appropriate size */
305 setnodevector(L, t, nhsize); 318 setnodevector(L, t, nhsize);
306 if (nasize < oldasize) { /* array part must shrink? */ 319 if (nasize < oldasize) { /* array part must shrink? */
307 t->sizearray = nasize; 320 t->sizearray = nasize;
308 /* re-insert elements from vanishing slice */ 321 /* re-insert elements from vanishing slice */
309 for (i=nasize; i<oldasize; i++) { 322 for (i=nasize; i<oldasize; i++) {
310 if (!ttisnil(&t->array[i])) 323 if (!ttisnil(&t->array[i]))
311 setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]); 324 luaH_setint(L, t, i + 1, &t->array[i]);
312 } 325 }
313 /* shrink array */ 326 /* shrink array */
314 luaM_reallocvector(L, t->array, oldasize, nasize, TValue); 327 luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
@@ -316,23 +329,26 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
316 /* re-insert elements from hash part */ 329 /* re-insert elements from hash part */
317 for (i = twoto(oldhsize) - 1; i >= 0; i--) { 330 for (i = twoto(oldhsize) - 1; i >= 0; i--) {
318 Node *old = nold+i; 331 Node *old = nold+i;
319 if (!ttisnil(gval(old))) 332 if (!ttisnil(gval(old))) {
320 setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old)); 333 /* doesn't need barrier/invalidate cache, as entry was
334 already present in the table */
335 setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old));
336 }
321 } 337 }
322 if (nold != dummynode) 338 if (!isdummy(nold))
323 luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */ 339 luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old array */
324} 340}
325 341
326 342
327void luaH_resizearray (lua_State *L, Table *t, int nasize) { 343void luaH_resizearray (lua_State *L, Table *t, int nasize) {
328 int nsize = (t->node == dummynode) ? 0 : sizenode(t); 344 int nsize = isdummy(t->node) ? 0 : sizenode(t);
329 resize(L, t, nasize, nsize); 345 luaH_resize(L, t, nasize, nsize);
330} 346}
331 347
332 348
333static void rehash (lua_State *L, Table *t, const TValue *ek) { 349static void rehash (lua_State *L, Table *t, const TValue *ek) {
334 int nasize, na; 350 int nasize, na;
335 int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */ 351 int nums[MAXBITS+1]; /* nums[i] = number of keys with 2^(i-1) < k <= 2^i */
336 int i; 352 int i;
337 int totaluse; 353 int totaluse;
338 for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */ 354 for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */
@@ -345,7 +361,7 @@ static void rehash (lua_State *L, Table *t, const TValue *ek) {
345 /* compute new size for array part */ 361 /* compute new size for array part */
346 na = computesizes(nums, &nasize); 362 na = computesizes(nums, &nasize);
347 /* resize the table to new computed sizes */ 363 /* resize the table to new computed sizes */
348 resize(L, t, nasize, totaluse - na); 364 luaH_resize(L, t, nasize, totaluse - na);
349} 365}
350 366
351 367
@@ -355,32 +371,28 @@ static void rehash (lua_State *L, Table *t, const TValue *ek) {
355*/ 371*/
356 372
357 373
358Table *luaH_new (lua_State *L, int narray, int nhash) { 374Table *luaH_new (lua_State *L) {
359 Table *t = luaM_new(L, Table); 375 Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h;
360 luaC_link(L, obj2gco(t), LUA_TTABLE);
361 t->metatable = NULL; 376 t->metatable = NULL;
362 t->flags = cast_byte(~0); 377 t->flags = cast_byte(~0);
363 /* temporary values (kept only if some malloc fails) */
364 t->array = NULL; 378 t->array = NULL;
365 t->sizearray = 0; 379 t->sizearray = 0;
366 t->lsizenode = 0; 380 setnodevector(L, t, 0);
367 t->node = cast(Node *, dummynode);
368 setarrayvector(L, t, narray);
369 setnodevector(L, t, nhash);
370 return t; 381 return t;
371} 382}
372 383
373 384
374void luaH_free (lua_State *L, Table *t) { 385void luaH_free (lua_State *L, Table *t) {
375 if (t->node != dummynode) 386 if (!isdummy(t->node))
376 luaM_freearray(L, t->node, sizenode(t), Node); 387 luaM_freearray(L, t->node, cast(size_t, sizenode(t)));
377 luaM_freearray(L, t->array, t->sizearray, TValue); 388 luaM_freearray(L, t->array, t->sizearray);
378 luaM_free(L, t); 389 luaM_free(L, t);
379} 390}
380 391
381 392
382static Node *getfreepos (Table *t) { 393static Node *getfreepos (Table *t) {
383 while (t->lastfree-- > t->node) { 394 while (t->lastfree > t->node) {
395 t->lastfree--;
384 if (ttisnil(gkey(t->lastfree))) 396 if (ttisnil(gkey(t->lastfree)))
385 return t->lastfree; 397 return t->lastfree;
386 } 398 }
@@ -390,23 +402,28 @@ static Node *getfreepos (Table *t) {
390 402
391 403
392/* 404/*
393** inserts a new key into a hash table; first, check whether key's main 405** inserts a new key into a hash table; first, check whether key's main
394** position is free. If not, check whether colliding node is in its main 406** position is free. If not, check whether colliding node is in its main
395** position or not: if it is not, move colliding node to an empty place and 407** position or not: if it is not, move colliding node to an empty place and
396** put new key in its main position; otherwise (colliding node is in its main 408** put new key in its main position; otherwise (colliding node is in its main
397** position), new key goes to an empty position. 409** position), new key goes to an empty position.
398*/ 410*/
399static TValue *newkey (lua_State *L, Table *t, const TValue *key) { 411TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
400 Node *mp = mainposition(t, key); 412 Node *mp;
401 if (!ttisnil(gval(mp)) || mp == dummynode) { 413 if (ttisnil(key)) luaG_runerror(L, "table index is nil");
414 else if (ttisnumber(key) && luai_numisnan(L, nvalue(key)))
415 luaG_runerror(L, "table index is NaN");
416 mp = mainposition(t, key);
417 if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */
402 Node *othern; 418 Node *othern;
403 Node *n = getfreepos(t); /* get a free place */ 419 Node *n = getfreepos(t); /* get a free place */
404 if (n == NULL) { /* cannot find a free place? */ 420 if (n == NULL) { /* cannot find a free place? */
405 rehash(L, t, key); /* grow table */ 421 rehash(L, t, key); /* grow table */
406 return luaH_set(L, t, key); /* re-insert key into grown table */ 422 /* whatever called 'newkey' take care of TM cache and GC barrier */
423 return luaH_set(L, t, key); /* insert key into grown table */
407 } 424 }
408 lua_assert(n != dummynode); 425 lua_assert(!isdummy(n));
409 othern = mainposition(t, key2tval(mp)); 426 othern = mainposition(t, gkey(mp));
410 if (othern != mp) { /* is colliding node out of its main position? */ 427 if (othern != mp) { /* is colliding node out of its main position? */
411 /* yes; move colliding node into free position */ 428 /* yes; move colliding node into free position */
412 while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ 429 while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
@@ -422,8 +439,8 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
422 mp = n; 439 mp = n;
423 } 440 }
424 } 441 }
425 gkey(mp)->value = key->value; gkey(mp)->tt = key->tt; 442 setobj2t(L, gkey(mp), key);
426 luaC_barriert(L, t, key); 443 luaC_barrierback(L, obj2gco(t), key);
427 lua_assert(ttisnil(gval(mp))); 444 lua_assert(ttisnil(gval(mp)));
428 return gval(mp); 445 return gval(mp);
429} 446}
@@ -432,7 +449,7 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
432/* 449/*
433** search function for integers 450** search function for integers
434*/ 451*/
435const TValue *luaH_getnum (Table *t, int key) { 452const TValue *luaH_getint (Table *t, int key) {
436 /* (1 <= key && key <= t->sizearray) */ 453 /* (1 <= key && key <= t->sizearray) */
437 if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) 454 if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
438 return &t->array[key-1]; 455 return &t->array[key-1];
@@ -450,12 +467,13 @@ const TValue *luaH_getnum (Table *t, int key) {
450 467
451 468
452/* 469/*
453** search function for strings 470** search function for short strings
454*/ 471*/
455const TValue *luaH_getstr (Table *t, TString *key) { 472const TValue *luaH_getstr (Table *t, TString *key) {
456 Node *n = hashstr(t, key); 473 Node *n = hashstr(t, key);
474 lua_assert(key->tsv.tt == LUA_TSHRSTR);
457 do { /* check whether `key' is somewhere in the chain */ 475 do { /* check whether `key' is somewhere in the chain */
458 if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key) 476 if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key))
459 return gval(n); /* that's it */ 477 return gval(n); /* that's it */
460 else n = gnext(n); 478 else n = gnext(n);
461 } while (n); 479 } while (n);
@@ -468,20 +486,20 @@ const TValue *luaH_getstr (Table *t, TString *key) {
468*/ 486*/
469const TValue *luaH_get (Table *t, const TValue *key) { 487const TValue *luaH_get (Table *t, const TValue *key) {
470 switch (ttype(key)) { 488 switch (ttype(key)) {
489 case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key));
471 case LUA_TNIL: return luaO_nilobject; 490 case LUA_TNIL: return luaO_nilobject;
472 case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
473 case LUA_TNUMBER: { 491 case LUA_TNUMBER: {
474 int k; 492 int k;
475 lua_Number n = nvalue(key); 493 lua_Number n = nvalue(key);
476 lua_number2int(k, n); 494 lua_number2int(k, n);
477 if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */ 495 if (luai_numeq(cast_num(k), n)) /* index is int? */
478 return luaH_getnum(t, k); /* use specialized version */ 496 return luaH_getint(t, k); /* use specialized version */
479 /* else go through */ 497 /* else go through */
480 } 498 }
481 default: { 499 default: {
482 Node *n = mainposition(t, key); 500 Node *n = mainposition(t, key);
483 do { /* check whether `key' is somewhere in the chain */ 501 do { /* check whether `key' is somewhere in the chain */
484 if (luaO_rawequalObj(key2tval(n), key)) 502 if (luaV_rawequalobj(gkey(n), key))
485 return gval(n); /* that's it */ 503 return gval(n); /* that's it */
486 else n = gnext(n); 504 else n = gnext(n);
487 } while (n); 505 } while (n);
@@ -491,41 +509,29 @@ const TValue *luaH_get (Table *t, const TValue *key) {
491} 509}
492 510
493 511
512/*
513** beware: when using this function you probably need to check a GC
514** barrier and invalidate the TM cache.
515*/
494TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { 516TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
495 const TValue *p = luaH_get(t, key); 517 const TValue *p = luaH_get(t, key);
496 t->flags = 0;
497 if (p != luaO_nilobject) 518 if (p != luaO_nilobject)
498 return cast(TValue *, p); 519 return cast(TValue *, p);
499 else { 520 else return luaH_newkey(L, t, key);
500 if (ttisnil(key)) luaG_runerror(L, "table index is nil");
501 else if (ttisnumber(key) && luai_numisnan(nvalue(key)))
502 luaG_runerror(L, "table index is NaN");
503 return newkey(L, t, key);
504 }
505} 521}
506 522
507 523
508TValue *luaH_setnum (lua_State *L, Table *t, int key) { 524void luaH_setint (lua_State *L, Table *t, int key, TValue *value) {
509 const TValue *p = luaH_getnum(t, key); 525 const TValue *p = luaH_getint(t, key);
526 TValue *cell;
510 if (p != luaO_nilobject) 527 if (p != luaO_nilobject)
511 return cast(TValue *, p); 528 cell = cast(TValue *, p);
512 else { 529 else {
513 TValue k; 530 TValue k;
514 setnvalue(&k, cast_num(key)); 531 setnvalue(&k, cast_num(key));
515 return newkey(L, t, &k); 532 cell = luaH_newkey(L, t, &k);
516 }
517}
518
519
520TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
521 const TValue *p = luaH_getstr(t, key);
522 if (p != luaO_nilobject)
523 return cast(TValue *, p);
524 else {
525 TValue k;
526 setsvalue(L, &k, key);
527 return newkey(L, t, &k);
528 } 533 }
534 setobj2t(L, cell, value);
529} 535}
530 536
531 537
@@ -533,20 +539,20 @@ static int unbound_search (Table *t, unsigned int j) {
533 unsigned int i = j; /* i is zero or a present index */ 539 unsigned int i = j; /* i is zero or a present index */
534 j++; 540 j++;
535 /* find `i' and `j' such that i is present and j is not */ 541 /* find `i' and `j' such that i is present and j is not */
536 while (!ttisnil(luaH_getnum(t, j))) { 542 while (!ttisnil(luaH_getint(t, j))) {
537 i = j; 543 i = j;
538 j *= 2; 544 j *= 2;
539 if (j > cast(unsigned int, MAX_INT)) { /* overflow? */ 545 if (j > cast(unsigned int, MAX_INT)) { /* overflow? */
540 /* table was built with bad purposes: resort to linear search */ 546 /* table was built with bad purposes: resort to linear search */
541 i = 1; 547 i = 1;
542 while (!ttisnil(luaH_getnum(t, i))) i++; 548 while (!ttisnil(luaH_getint(t, i))) i++;
543 return i - 1; 549 return i - 1;
544 } 550 }
545 } 551 }
546 /* now do a binary search between them */ 552 /* now do a binary search between them */
547 while (j - i > 1) { 553 while (j - i > 1) {
548 unsigned int m = (i+j)/2; 554 unsigned int m = (i+j)/2;
549 if (ttisnil(luaH_getnum(t, m))) j = m; 555 if (ttisnil(luaH_getint(t, m))) j = m;
550 else i = m; 556 else i = m;
551 } 557 }
552 return i; 558 return i;
@@ -570,7 +576,7 @@ int luaH_getn (Table *t) {
570 return i; 576 return i;
571 } 577 }
572 /* else must find a boundary in hash part */ 578 /* else must find a boundary in hash part */
573 else if (t->node == dummynode) /* hash part is empty? */ 579 else if (isdummy(t->node)) /* hash part is empty? */
574 return j; /* that is easy... */ 580 return j; /* that is easy... */
575 else return unbound_search(t, j); 581 else return unbound_search(t, j);
576} 582}
@@ -583,6 +589,6 @@ Node *luaH_mainposition (const Table *t, const TValue *key) {
583 return mainposition(t, key); 589 return mainposition(t, key);
584} 590}
585 591
586int luaH_isdummy (Node *n) { return n == dummynode; } 592int luaH_isdummy (Node *n) { return isdummy(n); }
587 593
588#endif 594#endif
diff --git a/apps/plugins/lua/ltable.h b/apps/plugins/lua/ltable.h
index aa28914871..d69449b2b8 100644
--- a/apps/plugins/lua/ltable.h
+++ b/apps/plugins/lua/ltable.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: ltable.h,v 2.16.1.2 2013/08/30 15:49:41 roberto Exp $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -11,20 +11,25 @@
11 11
12 12
13#define gnode(t,i) (&(t)->node[i]) 13#define gnode(t,i) (&(t)->node[i])
14#define gkey(n) (&(n)->i_key.nk) 14#define gkey(n) (&(n)->i_key.tvk)
15#define gval(n) (&(n)->i_val) 15#define gval(n) (&(n)->i_val)
16#define gnext(n) ((n)->i_key.nk.next) 16#define gnext(n) ((n)->i_key.nk.next)
17 17
18#define key2tval(n) (&(n)->i_key.tvk) 18#define invalidateTMcache(t) ((t)->flags = 0)
19 19
20/* returns the key, given the value of a table entry */
21#define keyfromval(v) \
22 (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val))))
20 23
21LUAI_FUNC const TValue *luaH_getnum (Table *t, int key); 24
22LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key); 25LUAI_FUNC const TValue *luaH_getint (Table *t, int key);
26LUAI_FUNC void luaH_setint (lua_State *L, Table *t, int key, TValue *value);
23LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 27LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
24LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
25LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 28LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
29LUAI_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); 30LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
27LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash); 31LUAI_FUNC Table *luaH_new (lua_State *L);
32LUAI_FUNC void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize);
28LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); 33LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
29LUAI_FUNC void luaH_free (lua_State *L, Table *t); 34LUAI_FUNC void luaH_free (lua_State *L, Table *t);
30LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 35LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
diff --git a/apps/plugins/lua/ltablib.c b/apps/plugins/lua/ltablib.c
index b6d9cb4ac7..6001224e39 100644
--- a/apps/plugins/lua/ltablib.c
+++ b/apps/plugins/lua/ltablib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $ 2** $Id: ltablib.c,v 1.65.1.1 2013/04/12 18:48:47 roberto Exp $
3** Library for Table Manipulation 3** Library for Table Manipulation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -16,43 +16,11 @@
16#include "lualib.h" 16#include "lualib.h"
17 17
18 18
19#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) 19#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_len(L, n))
20 20
21 21
22static int foreachi (lua_State *L) {
23 int i;
24 int n = aux_getn(L, 1);
25 luaL_checktype(L, 2, LUA_TFUNCTION);
26 for (i=1; i <= n; i++) {
27 lua_pushvalue(L, 2); /* function */
28 lua_pushinteger(L, i); /* 1st argument */
29 lua_rawgeti(L, 1, i); /* 2nd argument */
30 lua_call(L, 2, 1);
31 if (!lua_isnil(L, -1))
32 return 1;
33 lua_pop(L, 1); /* remove nil result */
34 }
35 return 0;
36}
37
38
39static int foreach (lua_State *L) {
40 luaL_checktype(L, 1, LUA_TTABLE);
41 luaL_checktype(L, 2, LUA_TFUNCTION);
42 lua_pushnil(L); /* first key */
43 while (lua_next(L, 1)) {
44 lua_pushvalue(L, 2); /* function */
45 lua_pushvalue(L, -3); /* key */
46 lua_pushvalue(L, -3); /* value */
47 lua_call(L, 2, 1);
48 if (!lua_isnil(L, -1))
49 return 1;
50 lua_pop(L, 2); /* remove value and result */
51 }
52 return 0;
53}
54
55 22
23#if defined(LUA_COMPAT_MAXN)
56static int maxn (lua_State *L) { 24static int maxn (lua_State *L) {
57 lua_Number max = 0; 25 lua_Number max = 0;
58 luaL_checktype(L, 1, LUA_TTABLE); 26 luaL_checktype(L, 1, LUA_TTABLE);
@@ -67,24 +35,7 @@ static int maxn (lua_State *L) {
67 lua_pushnumber(L, max); 35 lua_pushnumber(L, max);
68 return 1; 36 return 1;
69} 37}
70
71
72static int getn (lua_State *L) {
73 lua_pushinteger(L, aux_getn(L, 1));
74 return 1;
75}
76
77
78static int setn (lua_State *L) {
79 luaL_checktype(L, 1, LUA_TTABLE);
80#ifndef luaL_setn
81 luaL_setn(L, 1, luaL_checkint(L, 2));
82#else
83 luaL_error(L, LUA_QL("setn") " is obsolete");
84#endif 38#endif
85 lua_pushvalue(L, 1);
86 return 1;
87}
88 39
89 40
90static int tinsert (lua_State *L) { 41static int tinsert (lua_State *L) {
@@ -98,7 +49,7 @@ static int tinsert (lua_State *L) {
98 case 3: { 49 case 3: {
99 int i; 50 int i;
100 pos = luaL_checkint(L, 2); /* 2nd argument is the position */ 51 pos = luaL_checkint(L, 2); /* 2nd argument is the position */
101 if (pos > e) e = pos; /* `grow' array if necessary */ 52 luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds");
102 for (i = e; i > pos; i--) { /* move up elements */ 53 for (i = e; i > pos; i--) { /* move up elements */
103 lua_rawgeti(L, 1, i-1); 54 lua_rawgeti(L, 1, i-1);
104 lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ 55 lua_rawseti(L, 1, i); /* t[i] = t[i-1] */
@@ -109,25 +60,23 @@ static int tinsert (lua_State *L) {
109 return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); 60 return luaL_error(L, "wrong number of arguments to " LUA_QL("insert"));
110 } 61 }
111 } 62 }
112 luaL_setn(L, 1, e); /* new size */
113 lua_rawseti(L, 1, pos); /* t[pos] = v */ 63 lua_rawseti(L, 1, pos); /* t[pos] = v */
114 return 0; 64 return 0;
115} 65}
116 66
117 67
118static int tremove (lua_State *L) { 68static int tremove (lua_State *L) {
119 int e = aux_getn(L, 1); 69 int size = aux_getn(L, 1);
120 int pos = luaL_optint(L, 2, e); 70 int pos = luaL_optint(L, 2, size);
121 if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ 71 if (pos != size) /* validate 'pos' if given */
122 return 0; /* nothing to remove */ 72 luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds");
123 luaL_setn(L, 1, e - 1); /* t.n = n-1 */
124 lua_rawgeti(L, 1, pos); /* result = t[pos] */ 73 lua_rawgeti(L, 1, pos); /* result = t[pos] */
125 for ( ;pos<e; pos++) { 74 for ( ; pos < size; pos++) {
126 lua_rawgeti(L, 1, pos+1); 75 lua_rawgeti(L, 1, pos+1);
127 lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */ 76 lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */
128 } 77 }
129 lua_pushnil(L); 78 lua_pushnil(L);
130 lua_rawseti(L, 1, e); /* t[e] = nil */ 79 lua_rawseti(L, 1, pos); /* t[pos] = nil */
131 return 1; 80 return 1;
132} 81}
133 82
@@ -137,7 +86,7 @@ static void addfield (lua_State *L, luaL_Buffer *b, int i) {
137 if (!lua_isstring(L, -1)) 86 if (!lua_isstring(L, -1))
138 luaL_error(L, "invalid value (%s) at index %d in table for " 87 luaL_error(L, "invalid value (%s) at index %d in table for "
139 LUA_QL("concat"), luaL_typename(L, -1), i); 88 LUA_QL("concat"), luaL_typename(L, -1), i);
140 luaL_addvalue(b); 89 luaL_addvalue(b);
141} 90}
142 91
143 92
@@ -148,7 +97,7 @@ static int tconcat (lua_State *L) {
148 const char *sep = luaL_optlstring(L, 2, "", &lsep); 97 const char *sep = luaL_optlstring(L, 2, "", &lsep);
149 luaL_checktype(L, 1, LUA_TTABLE); 98 luaL_checktype(L, 1, LUA_TTABLE);
150 i = luaL_optint(L, 3, 1); 99 i = luaL_optint(L, 3, 1);
151 last = luaL_opt(L, luaL_checkint, 4, luaL_getn(L, 1)); 100 last = luaL_opt(L, luaL_checkint, 4, luaL_len(L, 1));
152 luaL_buffinit(L, &b); 101 luaL_buffinit(L, &b);
153 for (; i < last; i++) { 102 for (; i < last; i++) {
154 addfield(L, &b, i); 103 addfield(L, &b, i);
@@ -161,12 +110,54 @@ static int tconcat (lua_State *L) {
161} 110}
162 111
163 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
164 154
165/* 155/*
166** {====================================================== 156** {======================================================
167** Quicksort 157** Quicksort
168** (based on `Algorithms in MODULA-3', Robert Sedgewick; 158** (based on `Algorithms in MODULA-3', Robert Sedgewick;
169** Addison-Wesley, 1993.) 159** Addison-Wesley, 1993.)
160** =======================================================
170*/ 161*/
171 162
172 163
@@ -187,7 +178,7 @@ static int sort_comp (lua_State *L, int a, int b) {
187 return res; 178 return res;
188 } 179 }
189 else /* a < b? */ 180 else /* a < b? */
190 return lua_lessthan(L, a, b); 181 return lua_compare(L, a, b, LUA_OPLT);
191} 182}
192 183
193static void auxsort (lua_State *L, int l, int u) { 184static void auxsort (lua_State *L, int l, int u) {
@@ -224,12 +215,12 @@ static void auxsort (lua_State *L, int l, int u) {
224 for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */ 215 for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
225 /* repeat ++i until a[i] >= P */ 216 /* repeat ++i until a[i] >= P */
226 while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { 217 while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
227 if (i>u) luaL_error(L, "invalid order function for sorting"); 218 if (i>=u) luaL_error(L, "invalid order function for sorting");
228 lua_pop(L, 1); /* remove a[i] */ 219 lua_pop(L, 1); /* remove a[i] */
229 } 220 }
230 /* repeat --j until a[j] <= P */ 221 /* repeat --j until a[j] <= P */
231 while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { 222 while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
232 if (j<l) luaL_error(L, "invalid order function for sorting"); 223 if (j<=l) luaL_error(L, "invalid order function for sorting");
233 lua_pop(L, 1); /* remove a[j] */ 224 lua_pop(L, 1); /* remove a[j] */
234 } 225 }
235 if (j<i) { 226 if (j<i) {
@@ -268,20 +259,25 @@ static int sort (lua_State *L) {
268 259
269static const luaL_Reg tab_funcs[] = { 260static const luaL_Reg tab_funcs[] = {
270 {"concat", tconcat}, 261 {"concat", tconcat},
271 {"foreach", foreach}, 262#if defined(LUA_COMPAT_MAXN)
272 {"foreachi", foreachi},
273 {"getn", getn},
274 {"maxn", maxn}, 263 {"maxn", maxn},
264#endif
275 {"insert", tinsert}, 265 {"insert", tinsert},
266 {"pack", pack},
267 {"unpack", unpack},
276 {"remove", tremove}, 268 {"remove", tremove},
277 {"setn", setn},
278 {"sort", sort}, 269 {"sort", sort},
279 {NULL, NULL} 270 {NULL, NULL}
280}; 271};
281 272
282 273
283LUALIB_API int luaopen_table (lua_State *L) { 274LUAMOD_API int luaopen_table (lua_State *L) {
284 luaL_register(L, LUA_TABLIBNAME, tab_funcs); 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
285 return 1; 281 return 1;
286} 282}
287 283
diff --git a/apps/plugins/lua/ltm.c b/apps/plugins/lua/ltm.c
index c27f0f6fab..69b4ed7727 100644
--- a/apps/plugins/lua/ltm.c
+++ b/apps/plugins/lua/ltm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ 2** $Id: ltm.c,v 2.14.1.1 2013/04/12 18:48:47 roberto Exp $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -19,20 +19,22 @@
19#include "ltm.h" 19#include "ltm.h"
20 20
21 21
22static const char udatatypename[] = "userdata";
22 23
23const char *const luaT_typenames[] = { 24LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = {
24 "nil", "boolean", "userdata", "number", 25 "no value",
25 "string", "table", "function", "userdata", "thread", 26 "nil", "boolean", udatatypename, "number",
26 "proto", "upval" 27 "string", "table", "function", udatatypename, "thread",
28 "proto", "upval" /* these last two cases are used for tests only */
27}; 29};
28 30
29 31
30void luaT_init (lua_State *L) { 32void luaT_init (lua_State *L) {
31 static const char *const luaT_eventname[] = { /* ORDER TM */ 33 static const char *const luaT_eventname[] = { /* ORDER TM */
32 "__index", "__newindex", 34 "__index", "__newindex",
33 "__gc", "__mode", "__eq", 35 "__gc", "__mode", "__len", "__eq",
34 "__add", "__sub", "__mul", "__div", "__mod", 36 "__add", "__sub", "__mul", "__div", "__mod",
35 "__pow", "__unm", "__len", "__lt", "__le", 37 "__pow", "__unm", "__lt", "__le",
36 "__concat", "__call" 38 "__concat", "__call"
37 }; 39 };
38 int i; 40 int i;
@@ -60,7 +62,7 @@ const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
60 62
61const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { 63const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
62 Table *mt; 64 Table *mt;
63 switch (ttype(o)) { 65 switch (ttypenv(o)) {
64 case LUA_TTABLE: 66 case LUA_TTABLE:
65 mt = hvalue(o)->metatable; 67 mt = hvalue(o)->metatable;
66 break; 68 break;
@@ -68,7 +70,7 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
68 mt = uvalue(o)->metatable; 70 mt = uvalue(o)->metatable;
69 break; 71 break;
70 default: 72 default:
71 mt = G(L)->mt[ttype(o)]; 73 mt = G(L)->mt[ttypenv(o)];
72 } 74 }
73 return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); 75 return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
74} 76}
diff --git a/apps/plugins/lua/ltm.h b/apps/plugins/lua/ltm.h
index 1b89683ef3..7f89c841f9 100644
--- a/apps/plugins/lua/ltm.h
+++ b/apps/plugins/lua/ltm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: ltm.h,v 2.11.1.1 2013/04/12 18:48:47 roberto Exp $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -20,6 +20,7 @@ typedef enum {
20 TM_NEWINDEX, 20 TM_NEWINDEX,
21 TM_GC, 21 TM_GC,
22 TM_MODE, 22 TM_MODE,
23 TM_LEN,
23 TM_EQ, /* last tag method with `fast' access */ 24 TM_EQ, /* last tag method with `fast' access */
24 TM_ADD, 25 TM_ADD,
25 TM_SUB, 26 TM_SUB,
@@ -28,7 +29,6 @@ typedef enum {
28 TM_MOD, 29 TM_MOD,
29 TM_POW, 30 TM_POW,
30 TM_UNM, 31 TM_UNM,
31 TM_LEN,
32 TM_LT, 32 TM_LT,
33 TM_LE, 33 TM_LE,
34 TM_CONCAT, 34 TM_CONCAT,
@@ -43,7 +43,10 @@ typedef enum {
43 43
44#define fasttm(l,et,e) gfasttm(G(l), et, e) 44#define fasttm(l,et,e) gfasttm(G(l), et, e)
45 45
46LUAI_DATA const char *const luaT_typenames[]; 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];
47 50
48 51
49LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); 52LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
diff --git a/apps/plugins/lua/lua.h b/apps/plugins/lua/lua.h
index a0c57dc60b..149a2c37bc 100644
--- a/apps/plugins/lua/lua.h
+++ b/apps/plugins/lua/lua.h
@@ -1,6 +1,6 @@
1/* 1/*
2** $Id$ 2** $Id: lua.h,v 1.285.1.2 2013/11/11 12:09:16 roberto Exp $
3** Lua - An Extensible Extension Language 3** Lua - A Scripting Language
4** Lua.org, PUC-Rio, Brazil (http://www.lua.org) 4** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
5** See Copyright Notice at the end of this file 5** See Copyright Notice at the end of this file
6*/ 6*/
@@ -16,35 +16,39 @@
16#include "luaconf.h" 16#include "luaconf.h"
17 17
18 18
19#define LUA_VERSION "Lua 5.1" 19#define LUA_VERSION_MAJOR "5"
20#define LUA_RELEASE "Lua 5.1.4" 20#define LUA_VERSION_MINOR "2"
21#define LUA_VERSION_NUM 501 21#define LUA_VERSION_NUM 502
22#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio" 22#define LUA_VERSION_RELEASE "3"
23#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
24 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"
25 28
26/* mark for precompiled code (`<esc>Lua') */
27#define LUA_SIGNATURE "\033Lua"
28 29
29/* option for multiple returns in `lua_pcall' and `lua_call' */ 30/* mark for precompiled code ('<esc>Lua') */
31#define LUA_SIGNATURE "\033Lua"
32
33/* option for multiple returns in 'lua_pcall' and 'lua_call' */
30#define LUA_MULTRET (-1) 34#define LUA_MULTRET (-1)
31 35
32 36
33/* 37/*
34** pseudo-indices 38** pseudo-indices
35*/ 39*/
36#define LUA_REGISTRYINDEX (-10000) 40#define LUA_REGISTRYINDEX LUAI_FIRSTPSEUDOIDX
37#define LUA_ENVIRONINDEX (-10001) 41#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i))
38#define LUA_GLOBALSINDEX (-10002)
39#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
40 42
41 43
42/* thread status; 0 is OK */ 44/* thread status */
45#define LUA_OK 0
43#define LUA_YIELD 1 46#define LUA_YIELD 1
44#define LUA_ERRRUN 2 47#define LUA_ERRRUN 2
45#define LUA_ERRSYNTAX 3 48#define LUA_ERRSYNTAX 3
46#define LUA_ERRMEM 4 49#define LUA_ERRMEM 4
47#define LUA_ERRERR 5 50#define LUA_ERRGCMM 5
51#define LUA_ERRERR 6
48 52
49 53
50typedef struct lua_State lua_State; 54typedef struct lua_State lua_State;
@@ -81,18 +85,18 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
81#define LUA_TUSERDATA 7 85#define LUA_TUSERDATA 7
82#define LUA_TTHREAD 8 86#define LUA_TTHREAD 8
83 87
88#define LUA_NUMTAGS 9
89
84 90
85 91
86/* minimum Lua stack available to a C function */ 92/* minimum Lua stack available to a C function */
87#define LUA_MINSTACK 20 93#define LUA_MINSTACK 20
88 94
89 95
90/* 96/* predefined values in the registry */
91** generic extra include file 97#define LUA_RIDX_MAINTHREAD 1
92*/ 98#define LUA_RIDX_GLOBALS 2
93#if defined(LUA_USER_H) 99#define LUA_RIDX_LAST LUA_RIDX_GLOBALS
94#include LUA_USER_H
95#endif
96 100
97 101
98/* type of numbers in Lua */ 102/* type of numbers in Lua */
@@ -102,6 +106,23 @@ typedef LUA_NUMBER lua_Number;
102/* type for integer functions */ 106/* type for integer functions */
103typedef LUA_INTEGER lua_Integer; 107typedef LUA_INTEGER lua_Integer;
104 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[];
105 126
106 127
107/* 128/*
@@ -114,15 +135,20 @@ LUA_API lua_State *(lua_newthread) (lua_State *L);
114LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); 135LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
115 136
116 137
138LUA_API const lua_Number *(lua_version) (lua_State *L);
139
140
117/* 141/*
118** basic stack manipulation 142** basic stack manipulation
119*/ 143*/
144LUA_API int (lua_absindex) (lua_State *L, int idx);
120LUA_API int (lua_gettop) (lua_State *L); 145LUA_API int (lua_gettop) (lua_State *L);
121LUA_API void (lua_settop) (lua_State *L, int idx); 146LUA_API void (lua_settop) (lua_State *L, int idx);
122LUA_API void (lua_pushvalue) (lua_State *L, int idx); 147LUA_API void (lua_pushvalue) (lua_State *L, int idx);
123LUA_API void (lua_remove) (lua_State *L, int idx); 148LUA_API void (lua_remove) (lua_State *L, int idx);
124LUA_API void (lua_insert) (lua_State *L, int idx); 149LUA_API void (lua_insert) (lua_State *L, int idx);
125LUA_API void (lua_replace) (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);
126LUA_API int (lua_checkstack) (lua_State *L, int sz); 152LUA_API int (lua_checkstack) (lua_State *L, int sz);
127 153
128LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); 154LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
@@ -139,15 +165,12 @@ LUA_API int (lua_isuserdata) (lua_State *L, int idx);
139LUA_API int (lua_type) (lua_State *L, int idx); 165LUA_API int (lua_type) (lua_State *L, int idx);
140LUA_API const char *(lua_typename) (lua_State *L, int tp); 166LUA_API const char *(lua_typename) (lua_State *L, int tp);
141 167
142LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2); 168LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum);
143LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); 169LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum);
144LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); 170LUA_API lua_Unsigned (lua_tounsignedx) (lua_State *L, int idx, int *isnum);
145
146LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
147LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
148LUA_API int (lua_toboolean) (lua_State *L, int idx); 171LUA_API int (lua_toboolean) (lua_State *L, int idx);
149LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); 172LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
150LUA_API size_t (lua_objlen) (lua_State *L, int idx); 173LUA_API size_t (lua_rawlen) (lua_State *L, int idx);
151LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); 174LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
152LUA_API void *(lua_touserdata) (lua_State *L, int idx); 175LUA_API void *(lua_touserdata) (lua_State *L, int idx);
153LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); 176LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
@@ -155,13 +178,36 @@ LUA_API const void *(lua_topointer) (lua_State *L, int idx);
155 178
156 179
157/* 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/*
158** push functions (C -> stack) 203** push functions (C -> stack)
159*/ 204*/
160LUA_API void (lua_pushnil) (lua_State *L); 205LUA_API void (lua_pushnil) (lua_State *L);
161LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); 206LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
162LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); 207LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
163LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); 208LUA_API void (lua_pushunsigned) (lua_State *L, lua_Unsigned n);
164LUA_API void (lua_pushstring) (lua_State *L, const char *s); 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);
165LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, 211LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
166 va_list argp); 212 va_list argp);
167LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); 213LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
@@ -174,35 +220,47 @@ LUA_API int (lua_pushthread) (lua_State *L);
174/* 220/*
175** get functions (Lua -> stack) 221** get functions (Lua -> stack)
176*/ 222*/
223LUA_API void (lua_getglobal) (lua_State *L, const char *var);
177LUA_API void (lua_gettable) (lua_State *L, int idx); 224LUA_API void (lua_gettable) (lua_State *L, int idx);
178LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); 225LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
179LUA_API void (lua_rawget) (lua_State *L, int idx); 226LUA_API void (lua_rawget) (lua_State *L, int idx);
180LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); 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);
181LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); 229LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
182LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); 230LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
183LUA_API int (lua_getmetatable) (lua_State *L, int objindex); 231LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
184LUA_API void (lua_getfenv) (lua_State *L, int idx); 232LUA_API void (lua_getuservalue) (lua_State *L, int idx);
185 233
186 234
187/* 235/*
188** set functions (stack -> Lua) 236** set functions (stack -> Lua)
189*/ 237*/
238LUA_API void (lua_setglobal) (lua_State *L, const char *var);
190LUA_API void (lua_settable) (lua_State *L, int idx); 239LUA_API void (lua_settable) (lua_State *L, int idx);
191LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); 240LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
192LUA_API void (lua_rawset) (lua_State *L, int idx); 241LUA_API void (lua_rawset) (lua_State *L, int idx);
193LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); 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);
194LUA_API int (lua_setmetatable) (lua_State *L, int objindex); 244LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
195LUA_API int (lua_setfenv) (lua_State *L, int idx); 245LUA_API void (lua_setuservalue) (lua_State *L, int idx);
196 246
197 247
198/* 248/*
199** `load' and `call' functions (load and run Lua code) 249** 'load' and 'call' functions (load and run Lua code)
200*/ 250*/
201LUA_API void (lua_call) (lua_State *L, int nargs, int nresults); 251LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, int ctx,
202LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); 252 lua_CFunction k);
203LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); 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
204LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, 261LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
205 const char *chunkname); 262 const char *chunkname,
263 const char *mode);
206 264
207LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); 265LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
208 266
@@ -210,8 +268,10 @@ LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
210/* 268/*
211** coroutine functions 269** coroutine functions
212*/ 270*/
213LUA_API int (lua_yield) (lua_State *L, int nresults); 271LUA_API int (lua_yieldk) (lua_State *L, int nresults, int ctx,
214LUA_API int (lua_resume) (lua_State *L, int narg); 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);
215LUA_API int (lua_status) (lua_State *L); 275LUA_API int (lua_status) (lua_State *L);
216 276
217/* 277/*
@@ -226,6 +286,10 @@ LUA_API int (lua_status) (lua_State *L);
226#define LUA_GCSTEP 5 286#define LUA_GCSTEP 5
227#define LUA_GCSETPAUSE 6 287#define LUA_GCSETPAUSE 6
228#define LUA_GCSETSTEPMUL 7 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
229 293
230LUA_API int (lua_gc) (lua_State *L, int what, int data); 294LUA_API int (lua_gc) (lua_State *L, int what, int data);
231 295
@@ -239,18 +303,23 @@ LUA_API int (lua_error) (lua_State *L);
239LUA_API int (lua_next) (lua_State *L, int idx); 303LUA_API int (lua_next) (lua_State *L, int idx);
240 304
241LUA_API void (lua_concat) (lua_State *L, int n); 305LUA_API void (lua_concat) (lua_State *L, int n);
306LUA_API void (lua_len) (lua_State *L, int idx);
242 307
243LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); 308LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
244LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); 309LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
245 310
246 311
247 312
248/* 313/*
249** =============================================================== 314** ===============================================================
250** some useful macros 315** some useful macros
251** =============================================================== 316** ===============================================================
252*/ 317*/
253 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
254#define lua_pop(L,n) lua_settop(L, -(n)-1) 323#define lua_pop(L,n) lua_settop(L, -(n)-1)
255 324
256#define lua_newtable(L) lua_createtable(L, 0, 0) 325#define lua_newtable(L) lua_createtable(L, 0, 0)
@@ -259,8 +328,6 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
259 328
260#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) 329#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
261 330
262#define lua_strlen(L,i) lua_objlen(L, (i))
263
264#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) 331#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
265#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) 332#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
266#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) 333#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
@@ -273,32 +340,14 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
273#define lua_pushliteral(L, s) \ 340#define lua_pushliteral(L, s) \
274 lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) 341 lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
275 342
276#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) 343#define lua_pushglobaltable(L) \
277#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) 344 lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)
278 345
279#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) 346#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
280 347
281 348
282 349
283/* 350/*
284** compatibility macros and functions
285*/
286
287#define lua_open() luaL_newstate()
288
289#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)
290
291#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0)
292
293#define lua_Chunkreader lua_Reader
294#define lua_Chunkwriter lua_Writer
295
296
297/* hack */
298LUA_API void lua_setlevel (lua_State *from, lua_State *to);
299
300
301/*
302** {====================================================================== 351** {======================================================================
303** Debug API 352** Debug API
304** ======================================================================= 353** =======================================================================
@@ -312,7 +361,7 @@ LUA_API void lua_setlevel (lua_State *from, lua_State *to);
312#define LUA_HOOKRET 1 361#define LUA_HOOKRET 1
313#define LUA_HOOKLINE 2 362#define LUA_HOOKLINE 2
314#define LUA_HOOKCOUNT 3 363#define LUA_HOOKCOUNT 3
315#define LUA_HOOKTAILRET 4 364#define LUA_HOOKTAILCALL 4
316 365
317 366
318/* 367/*
@@ -326,43 +375,50 @@ LUA_API void lua_setlevel (lua_State *from, lua_State *to);
326typedef struct lua_Debug lua_Debug; /* activation record */ 375typedef struct lua_Debug lua_Debug; /* activation record */
327 376
328 377
329/* Functions to be called by the debuger in specific events */ 378/* Functions to be called by the debugger in specific events */
330typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); 379typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
331 380
332 381
333LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); 382LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar);
334LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); 383LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar);
335LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); 384LUA_API const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n);
336LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); 385LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n);
337LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); 386LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n);
338LUA_API const char *lua_setupvalue (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);
339 392
340LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); 393LUA_API int (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count);
341LUA_API lua_Hook lua_gethook (lua_State *L); 394LUA_API lua_Hook (lua_gethook) (lua_State *L);
342LUA_API int lua_gethookmask (lua_State *L); 395LUA_API int (lua_gethookmask) (lua_State *L);
343LUA_API int lua_gethookcount (lua_State *L); 396LUA_API int (lua_gethookcount) (lua_State *L);
344 397
345 398
346struct lua_Debug { 399struct lua_Debug {
347 int event; 400 int event;
348 const char *name; /* (n) */ 401 const char *name; /* (n) */
349 const char *namewhat; /* (n) `global', `local', `field', `method' */ 402 const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */
350 const char *what; /* (S) `Lua', `C', `main', `tail' */ 403 const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */
351 const char *source; /* (S) */ 404 const char *source; /* (S) */
352 int currentline; /* (l) */ 405 int currentline; /* (l) */
353 int nups; /* (u) number of upvalues */
354 int linedefined; /* (S) */ 406 int linedefined; /* (S) */
355 int lastlinedefined; /* (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) */
356 char short_src[LUA_IDSIZE]; /* (S) */ 412 char short_src[LUA_IDSIZE]; /* (S) */
357 /* private part */ 413 /* private part */
358 int i_ci; /* active function */ 414 struct CallInfo *i_ci; /* active function */
359}; 415};
360 416
361/* }====================================================================== */ 417/* }====================================================================== */
362 418
363 419
364/****************************************************************************** 420/******************************************************************************
365* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved. 421* Copyright (C) 1994-2013 Lua.org, PUC-Rio.
366* 422*
367* Permission is hereby granted, free of charge, to any person obtaining 423* Permission is hereby granted, free of charge, to any person obtaining
368* a copy of this software and associated documentation files (the 424* a copy of this software and associated documentation files (the
diff --git a/apps/plugins/lua/luaconf.h b/apps/plugins/lua/luaconf.h
index 109e680a17..ed83e8f640 100644
--- a/apps/plugins/lua/luaconf.h
+++ b/apps/plugins/lua/luaconf.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: luaconf.h,v 1.176.1.1 2013/04/12 18:48:47 roberto Exp $
3** Configuration file for Lua 3** Configuration file for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -24,30 +24,44 @@
24** CHANGE it (define it) if you want Lua to avoid the use of any 24** CHANGE it (define it) if you want Lua to avoid the use of any
25** non-ansi feature or library. 25** non-ansi feature or library.
26*/ 26*/
27#if defined(__STRICT_ANSI__) 27#if !defined(LUA_ANSI) && defined(__STRICT_ANSI__)
28#define LUA_ANSI 28#define LUA_ANSI
29#endif 29#endif
30 30
31 31
32#if !defined(LUA_ANSI) && defined(_WIN32) 32#if !defined(LUA_ANSI) && defined(_WIN32) && !defined(_WIN32_WCE)
33#define LUA_WIN 33#define LUA_WIN /* enable goodies for regular Windows platforms */
34#endif 34#endif
35 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
36#if defined(LUA_USE_LINUX) 43#if defined(LUA_USE_LINUX)
37#define LUA_USE_POSIX 44#define LUA_USE_POSIX
38#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ 45#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
39#define LUA_USE_READLINE /* needs some extra libraries */ 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 */
40#endif 50#endif
41 51
42#if defined(LUA_USE_MACOSX) 52#if defined(LUA_USE_MACOSX)
43#define LUA_USE_POSIX 53#define LUA_USE_POSIX
44#define LUA_DL_DYLD /* does not need extra library */ 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 */
45#endif 59#endif
46 60
47 61
48 62
49/* 63/*
50@@ LUA_USE_POSIX includes all functionallity listed as X/Open System 64@@ LUA_USE_POSIX includes all functionality listed as X/Open System
51@* Interfaces Extension (XSI). 65@* Interfaces Extension (XSI).
52** CHANGE it (define it) if your system is XSI compatible. 66** CHANGE it (define it) if your system is XSI compatible.
53*/ 67*/
@@ -56,20 +70,10 @@
56#define LUA_USE_ISATTY 70#define LUA_USE_ISATTY
57#define LUA_USE_POPEN 71#define LUA_USE_POPEN
58#define LUA_USE_ULONGJMP 72#define LUA_USE_ULONGJMP
73#define LUA_USE_GMTIME_R
59#endif 74#endif
60 75
61 76
62/*
63@@ LUA_PATH and LUA_CPATH are the names of the environment variables that
64@* Lua check to set its paths.
65@@ LUA_INIT is the name of the environment variable that Lua
66@* checks for initialization code.
67** CHANGE them if you want different names.
68*/
69#define LUA_PATH "LUA_PATH"
70#define LUA_CPATH "LUA_CPATH"
71#define LUA_INIT "LUA_INIT"
72
73 77
74/* 78/*
75@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for 79@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
@@ -80,7 +84,7 @@
80** hierarchy or if you want to install your libraries in 84** hierarchy or if you want to install your libraries in
81** non-conventional directories. 85** non-conventional directories.
82*/ 86*/
83#if defined(_WIN32) 87#if defined(_WIN32) /* { */
84/* 88/*
85** In Windows, any exclamation mark ('!') in the path is replaced by the 89** In Windows, any exclamation mark ('!') in the path is replaced by the
86** path of the directory of the executable file of the current process. 90** path of the directory of the executable file of the current process.
@@ -88,21 +92,23 @@
88#define LUA_LDIR "!\\lua\\" 92#define LUA_LDIR "!\\lua\\"
89#define LUA_CDIR "!\\" 93#define LUA_CDIR "!\\"
90#define LUA_PATH_DEFAULT \ 94#define LUA_PATH_DEFAULT \
91 ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ 95 LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
92 LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" 96 LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" ".\\?.lua"
93#define LUA_CPATH_DEFAULT \ 97#define LUA_CPATH_DEFAULT \
94 ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" 98 LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll"
95 99
96#else 100#else /* }{ */
101
102#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR "/"
97#define LUA_ROOT "/usr/local/" 103#define LUA_ROOT "/usr/local/"
98#define LUA_LDIR LUA_ROOT "share/lua/5.1/" 104#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR
99#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" 105#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR
100#define LUA_PATH_DEFAULT \ 106#define LUA_PATH_DEFAULT \
101 "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ 107 LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
102 LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" 108 LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" "./?.lua"
103#define LUA_CPATH_DEFAULT \ 109#define LUA_CPATH_DEFAULT \
104 "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so" 110 LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so"
105#endif 111#endif /* } */
106 112
107 113
108/* 114/*
@@ -118,79 +124,67 @@
118 124
119 125
120/* 126/*
121@@ LUA_PATHSEP is the character that separates templates in a path. 127@@ LUA_ENV is the name of the variable that holds the current
122@@ LUA_PATH_MARK is the string that marks the substitution points in a 128@@ environment, used to access global names.
123@* template. 129** CHANGE it if you do not like this name.
124@@ LUA_EXECDIR in a Windows path is replaced by the executable's
125@* directory.
126@@ LUA_IGMARK is a mark to ignore all before it when bulding the
127@* luaopen_ function name.
128** CHANGE them if for some reason your system cannot use those
129** characters. (E.g., if one of those characters is a common character
130** in file/directory names.) Probably you do not need to change them.
131*/
132#define LUA_PATHSEP ";"
133#define LUA_PATH_MARK "?"
134#define LUA_EXECDIR "!"
135#define LUA_IGMARK "-"
136
137
138/*
139@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
140** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
141** machines, ptrdiff_t gives a good choice between int or long.)
142*/ 130*/
143#define LUA_INTEGER ptrdiff_t 131#define LUA_ENV "_ENV"
144 132
145 133
146/* 134/*
147@@ LUA_API is a mark for all core API functions. 135@@ LUA_API is a mark for all core API functions.
148@@ LUALIB_API is a mark for all standard library functions. 136@@ LUALIB_API is a mark for all auxiliary library functions.
137@@ LUAMOD_API is a mark for all standard library opening functions.
149** CHANGE them if you need to define those functions in some special way. 138** CHANGE them if you need to define those functions in some special way.
150** For instance, if you want to create one Windows DLL with the core and 139** For instance, if you want to create one Windows DLL with the core and
151** the libraries, you may want to use the following definition (define 140** the libraries, you may want to use the following definition (define
152** LUA_BUILD_AS_DLL to get it). 141** LUA_BUILD_AS_DLL to get it).
153*/ 142*/
154#if defined(LUA_BUILD_AS_DLL) 143#if defined(LUA_BUILD_AS_DLL) /* { */
155 144
156#if defined(LUA_CORE) || defined(LUA_LIB) 145#if defined(LUA_CORE) || defined(LUA_LIB) /* { */
157#define LUA_API __declspec(dllexport) 146#define LUA_API __declspec(dllexport)
158#else 147#else /* }{ */
159#define LUA_API __declspec(dllimport) 148#define LUA_API __declspec(dllimport)
160#endif 149#endif /* } */
161 150
162#else 151#else /* }{ */
163 152
164#define LUA_API extern 153#define LUA_API extern
165 154
166#endif 155#endif /* } */
156
167 157
168/* more often than not the libs go together with the core */ 158/* more often than not the libs go together with the core */
169#define LUALIB_API LUA_API 159#define LUALIB_API LUA_API
160#define LUAMOD_API LUALIB_API
170 161
171 162
172/* 163/*
173@@ LUAI_FUNC is a mark for all extern functions that are not to be 164@@ LUAI_FUNC is a mark for all extern functions that are not to be
174@* exported to outside modules. 165@* exported to outside modules.
175@@ LUAI_DATA is a mark for all extern (const) variables that are not to 166@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables
176@* be exported to outside modules. 167@* that are not to be exported to outside modules (LUAI_DDEF for
168@* definitions and LUAI_DDEC for declarations).
177** CHANGE them if you need to mark them in some special way. Elf/gcc 169** CHANGE them if you need to mark them in some special way. Elf/gcc
178** (versions 3.2 and later) mark them as "hidden" to optimize access 170** (versions 3.2 and later) mark them as "hidden" to optimize access
179** when Lua is compiled as a shared library. 171** when Lua is compiled as a shared library. Not all elf targets support
180*/ 172** this attribute. Unfortunately, gcc does not offer a way to check
181#if defined(luaall_c) 173** whether the target offers that support, and those without support
182#define LUAI_FUNC static 174** give a warning about it. To avoid these warnings, change to the
183#define LUAI_DATA /* empty */ 175** default definition.
184 176*/
185#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ 177#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
186 defined(__ELF__) 178 defined(__ELF__) /* { */
187#define LUAI_FUNC __attribute__((visibility("hidden"))) extern 179#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
188#define LUAI_DATA LUAI_FUNC 180#define LUAI_DDEC LUAI_FUNC
181#define LUAI_DDEF /* empty */
189 182
190#else 183#else /* }{ */
191#define LUAI_FUNC extern 184#define LUAI_FUNC extern
192#define LUAI_DATA extern 185#define LUAI_DDEC extern
193#endif 186#define LUAI_DDEF /* empty */
187#endif /* } */
194 188
195 189
196 190
@@ -211,175 +205,108 @@
211 205
212 206
213/* 207/*
214** {================================================================== 208@@ luai_writestring/luai_writeline define how 'print' prints its results.
215** Stand-alone configuration 209** They are only used in libraries and the stand-alone program. (The #if
216** =================================================================== 210** avoids including 'stdio.h' everywhere.)
217*/ 211*/
218 212#if defined(LUA_LIB) || defined(lua_c)
219#if defined(lua_c) || defined(luaall_c) 213#define luai_writestring(s,l) DEBUGF("%s", (s))
214#define luai_writeline() luai_writestring("\n", 1)
215#endif
220 216
221/* 217/*
222@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that 218@@ luai_writestringerror defines how to print error messages.
223@* is, whether we're running lua interactively). 219** (A format string with one argument is enough for Lua...)
224** CHANGE it if you have a better definition for non-POSIX/non-Windows
225** systems.
226*/ 220*/
227#if defined(LUA_USE_ISATTY) 221#define luai_writestringerror(s,p) \
228#include <unistd.h> 222 (fprintf(stderr, (s), (p)), fflush(stderr))
229#define lua_stdin_is_tty() isatty(0)
230#elif defined(LUA_WIN)
231#include <io.h>
232#include <stdio.h>
233#define lua_stdin_is_tty() _isatty(_fileno(stdin))
234#else
235#define lua_stdin_is_tty() 1 /* assume stdin is a tty */
236#endif
237 223
238 224
239/* 225/*
240@@ LUA_PROMPT is the default prompt used by stand-alone Lua. 226@@ LUAI_MAXSHORTLEN is the maximum length for short strings, that is,
241@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua. 227** strings that are internalized. (Cannot be smaller than reserved words
242** CHANGE them if you want different prompts. (You can also change the 228** or tags for metamethods, as these strings must be internalized;
243** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) 229** #("function") = 8, #("__newindex") = 10.)
244*/ 230*/
245#define LUA_PROMPT "> " 231#define LUAI_MAXSHORTLEN 40
246#define LUA_PROMPT2 ">> " 232
247 233
248 234
249/* 235/*
250@@ LUA_PROGNAME is the default name for the stand-alone Lua program. 236** {==================================================================
251** CHANGE it if your stand-alone interpreter has a different name and 237** Compatibility with previous versions
252** your system is not able to detect that name automatically. 238** ===================================================================
253*/ 239*/
254#define LUA_PROGNAME "lua"
255
256 240
257/* 241/*
258@@ LUA_MAXINPUT is the maximum length for an input line in the 242@@ LUA_COMPAT_ALL controls all compatibility options.
259@* stand-alone interpreter. 243** You can define it to get all options, or change specific options
260** CHANGE it if you need longer lines. 244** to fit your specific needs.
261*/ 245*/
262#define LUA_MAXINPUT 512 246#if defined(LUA_COMPAT_ALL) /* { */
263
264 247
265/* 248/*
266@@ lua_readline defines how to show a prompt and then read a line from 249@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.
267@* the standard input. 250** You can replace it with 'table.unpack'.
268@@ lua_saveline defines how to "save" a read line in a "history".
269@@ lua_freeline defines how to free a line read by lua_readline.
270** CHANGE them if you want to improve this functionality (e.g., by using
271** GNU readline and history facilities).
272*/ 251*/
273#if defined(LUA_USE_READLINE) 252#define LUA_COMPAT_UNPACK
274#include <stdio.h>
275#include <readline/readline.h>
276#include <readline/history.h>
277#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
278#define lua_saveline(L,idx) \
279 if (lua_strlen(L,idx) > 0) /* non-empty line? */ \
280 add_history(lua_tostring(L, idx)); /* add it to history */
281#define lua_freeline(L,b) ((void)L, free(b))
282#else
283#define lua_readline(L,b,p) \
284 ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
285 fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
286#define lua_saveline(L,idx) { (void)L; (void)idx; }
287#define lua_freeline(L,b) { (void)L; (void)b; }
288#endif
289
290#endif
291
292/* }================================================================== */
293
294 253
295/* 254/*
296@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles 255@@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'.
297@* as a percentage. 256** You can replace it with 'package.searchers'.
298** CHANGE it if you want the GC to run faster or slower (higher values
299** mean larger pauses which mean slower collection.) You can also change
300** this value dynamically.
301*/ 257*/
302#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ 258#define LUA_COMPAT_LOADERS
303
304 259
305/* 260/*
306@@ LUAI_GCMUL defines the default speed of garbage collection relative to 261@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall.
307@* memory allocation as a percentage. 262** You can call your C function directly (with light C functions).
308** CHANGE it if you want to change the granularity of the garbage
309** collection. (Higher values mean coarser collections. 0 represents
310** infinity, where each step performs a full collection.) You can also
311** change this value dynamically.
312*/ 263*/
313#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ 264#define lua_cpcall(L,f,u) \
314 265 (lua_pushcfunction(L, (f)), \
266 lua_pushlightuserdata(L,(u)), \
267 lua_pcall(L,1,0,0))
315 268
316 269
317/* 270/*
318@@ LUA_COMPAT_GETN controls compatibility with old getn behavior. 271@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library.
319** CHANGE it (define it) if you want exact compatibility with the 272** You can rewrite 'log10(x)' as 'log(x, 10)'.
320** behavior of setn/getn in Lua 5.0.
321*/ 273*/
322#undef LUA_COMPAT_GETN 274#define LUA_COMPAT_LOG10
323 275
324/* 276/*
325@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib. 277@@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base
326** CHANGE it to undefined as soon as you do not need a global 'loadlib' 278** library. You can rewrite 'loadstring(s)' as 'load(s)'.
327** function (the function is still available as 'package.loadlib').
328*/ 279*/
329#undef LUA_COMPAT_LOADLIB 280#define LUA_COMPAT_LOADSTRING
330 281
331/* 282/*
332@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature. 283@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library.
333** CHANGE it to undefined as soon as your programs use only '...' to
334** access vararg parameters (instead of the old 'arg' table).
335*/ 284*/
336#undef LUA_COMPAT_VARARG 285#define LUA_COMPAT_MAXN
337 286
338/* 287/*
339@@ LUA_COMPAT_MOD controls compatibility with old math.mod function. 288@@ The following macros supply trivial compatibility for some
340** CHANGE it to undefined as soon as your programs use 'math.fmod' or 289** changes in the API. The macros themselves document how to
341** the new '%' operator instead of 'math.mod'. 290** change your code to avoid using them.
342*/ 291*/
343#undef LUA_COMPAT_MOD 292#define lua_strlen(L,i) lua_rawlen(L, (i))
344 293
345/* 294#define lua_objlen(L,i) lua_rawlen(L, (i))
346@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting
347@* facility.
348** CHANGE it to 2 if you want the old behaviour, or undefine it to turn
349** off the advisory error when nesting [[...]].
350*/
351#undef LUA_COMPAT_LSTR
352 295
353/* 296#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ)
354@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name. 297#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT)
355** CHANGE it to undefined as soon as you rename 'string.gfind' to
356** 'string.gmatch'.
357*/
358#undef LUA_COMPAT_GFIND
359 298
360/* 299/*
361@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib' 300@@ LUA_COMPAT_MODULE controls compatibility with previous
362@* behavior. 301** module functions 'module' (Lua) and 'luaL_register' (C).
363** CHANGE it to undefined as soon as you replace to 'luaL_registry'
364** your uses of 'luaL_openlib'
365*/ 302*/
366#undef LUA_COMPAT_OPENLIB 303#define LUA_COMPAT_MODULE
367 304
305#endif /* } */
306#define LUA_COMPAT_MODULE
368 307
308/* }================================================================== */
369 309
370/*
371@@ luai_apicheck is the assert macro used by the Lua-C API.
372** CHANGE luai_apicheck if you want Lua to perform some checks in the
373** parameters it gets from API calls. This may slow down the interpreter
374** a bit, but may be quite useful when debugging C code that interfaces
375** with Lua. A useful redefinition is to use assert.h.
376*/
377#if defined(LUA_USE_APICHECK)
378#include <assert.h>
379#define luai_apicheck(L,o) { (void)L; assert(o); }
380#else
381#define luai_apicheck(L,o) { (void)L; }
382#endif
383 310
384 311
385/* 312/*
@@ -388,108 +315,65 @@
388** your machine. Probably you do not need to change this. 315** your machine. Probably you do not need to change this.
389*/ 316*/
390/* avoid overflows in comparison */ 317/* avoid overflows in comparison */
391#if INT_MAX-20 < 32760 318#if INT_MAX-20 < 32760 /* { */
392#define LUAI_BITSINT 16 319#define LUAI_BITSINT 16
393#elif INT_MAX > 2147483640L 320#elif INT_MAX > 2147483640L /* }{ */
394/* int has at least 32 bits */ 321/* int has at least 32 bits */
395#define LUAI_BITSINT 32 322#define LUAI_BITSINT 32
396#else 323#else /* }{ */
397#error "you must define LUA_BITSINT with number of bits in an integer" 324#error "you must define LUA_BITSINT with number of bits in an integer"
398#endif 325#endif /* } */
399 326
400 327
401/* 328/*
402@@ LUAI_UINT32 is an unsigned integer with at least 32 bits. 329@@ LUA_INT32 is an signed integer with exactly 32 bits.
403@@ LUAI_INT32 is an signed integer with at least 32 bits.
404@@ LUAI_UMEM is an unsigned integer big enough to count the total 330@@ LUAI_UMEM is an unsigned integer big enough to count the total
405@* memory used by Lua. 331@* memory used by Lua.
406@@ LUAI_MEM is a signed integer big enough to count the total memory 332@@ LUAI_MEM is a signed integer big enough to count the total memory
407@* used by Lua. 333@* used by Lua.
408** CHANGE here if for some weird reason the default definitions are not 334** CHANGE here if for some weird reason the default definitions are not
409** good enough for your machine. (The definitions in the 'else' 335** good enough for your machine. Probably you do not need to change
410** part always works, but may waste space on machines with 64-bit 336** this.
411** longs.) Probably you do not need to change this.
412*/ 337*/
413#if LUAI_BITSINT >= 32 338#if LUAI_BITSINT >= 32 /* { */
414#define LUAI_UINT32 unsigned int 339#define LUA_INT32 int
415#define LUAI_INT32 int
416#define LUAI_MAXINT32 INT_MAX
417#define LUAI_UMEM size_t 340#define LUAI_UMEM size_t
418#define LUAI_MEM ptrdiff_t 341#define LUAI_MEM ptrdiff_t
419#else 342#else /* }{ */
420/* 16-bit ints */ 343/* 16-bit ints */
421#define LUAI_UINT32 unsigned long 344#define LUA_INT32 long
422#define LUAI_INT32 long
423#define LUAI_MAXINT32 LONG_MAX
424#define LUAI_UMEM unsigned long 345#define LUAI_UMEM unsigned long
425#define LUAI_MEM long 346#define LUAI_MEM long
426#endif 347#endif /* } */
427
428
429/*
430@@ LUAI_MAXCALLS limits the number of nested calls.
431** CHANGE it if you need really deep recursive calls. This limit is
432** arbitrary; its only purpose is to stop infinite recursion before
433** exhausting memory.
434*/
435#define LUAI_MAXCALLS 20000
436
437
438/*
439@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function
440@* can use.
441** CHANGE it if you need lots of (Lua) stack space for your C
442** functions. This limit is arbitrary; its only purpose is to stop C
443** functions to consume unlimited stack space. (must be smaller than
444** -LUA_REGISTRYINDEX)
445*/
446#define LUAI_MAXCSTACK 8000
447
448
449
450/*
451** {==================================================================
452** CHANGE (to smaller values) the following definitions if your system
453** has a small C stack. (Or you may want to change them to larger
454** values if your system has a large C stack and these limits are
455** too rigid for you.) Some of these constants control the size of
456** stack-allocated arrays used by the compiler or the interpreter, while
457** others limit the maximum number of recursive calls that the compiler
458** or the interpreter can perform. Values too large may cause a C stack
459** overflow for some forms of deep constructs.
460** ===================================================================
461*/
462 348
463 349
464/* 350/*
465@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and 351@@ LUAI_MAXSTACK limits the size of the Lua stack.
466@* syntactical nested non-terminals in a program. 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).
467*/ 355*/
468#define LUAI_MAXCCALLS 200 356#if LUAI_BITSINT >= 32
357#define LUAI_MAXSTACK 1000000
358#else
359#define LUAI_MAXSTACK 15000
360#endif
469 361
362/* reserve some space for error handling */
363#define LUAI_FIRSTPSEUDOIDX (-LUAI_MAXSTACK - 1000)
470 364
471/*
472@@ LUAI_MAXVARS is the maximum number of local variables per function
473@* (must be smaller than 250).
474*/
475#define LUAI_MAXVARS 200
476 365
477 366
478/*
479@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function
480@* (must be smaller than 250).
481*/
482#define LUAI_MAXUPVALUES 60
483
484 367
485/* 368/*
486@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. 369@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
370** CHANGE it if it uses too much C-stack space.
487*/ 371*/
488#define LUAL_BUFFERSIZE 1024 372#define LUAL_BUFFERSIZE 1024
489 373
490/* }================================================================== */ 374#ifndef SIMULATOR
491 375typedef void FILE;
492 376#endif
493 377
494 378
495/* 379/*
@@ -516,237 +400,138 @@
516@@ LUA_NUMBER_FMT is the format for writing numbers. 400@@ LUA_NUMBER_FMT is the format for writing numbers.
517@@ lua_number2str converts a number to a string. 401@@ lua_number2str converts a number to a string.
518@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. 402@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
519@@ lua_str2number converts a string to a number.
520*/ 403*/
521#define LUA_NUMBER_SCAN "%ld" 404#define LUA_NUMBER_SCAN "%ld"
522#define LUA_NUMBER_FMT "%ld" 405#define LUA_NUMBER_FMT "%ld"
523#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ 406#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
524#define lua_number2str(s,n) snprintf((s), 32, LUA_NUMBER_FMT, (n)) 407#define lua_number2str(s,n) snprintf((s), 32, LUA_NUMBER_FMT, (n))
525#define lua_str2number(s,p) strtol((s), (p), 10)
526 408
527 409
528/* 410/*
529@@ The luai_num* macros define the primitive operations over numbers. 411@@ l_mathop allows the addition of an 'l' or 'f' to all math operations
530*/ 412*/
531#if defined(LUA_CORE) 413#define l_mathop(x) (x)
532extern long rb_pow(long, long);
533#define luai_numadd(a,b) ((a)+(b))
534#define luai_numsub(a,b) ((a)-(b))
535#define luai_nummul(a,b) ((a)*(b))
536#define luai_numdiv(a,b) ((a)/(b))
537#define luai_nummod(a,b) ((a)%(b))
538#define luai_numpow(a,b) (rb_pow(a,b))
539#define luai_numunm(a) (-(a))
540#define luai_numeq(a,b) ((a)==(b))
541#define luai_numlt(a,b) ((a)<(b))
542#define luai_numle(a,b) ((a)<=(b))
543#define luai_numisnan(a) (!luai_numeq((a), (a)))
544#endif
545 414
546 415
547/* 416/*
548@@ lua_number2int is a macro to convert lua_Number to int. 417@@ lua_str2number converts a decimal numeric string to a number.
549@@ lua_number2integer is a macro to convert lua_Number to lua_Integer. 418@@ lua_strx2number converts an hexadecimal numeric string to a number.
550** CHANGE them if you know a faster way to convert a lua_Number to 419** In C99, 'strtod' does both conversions. C89, however, has no function
551** int (with any rounding method and without throwing errors) in your 420** to convert floating hexadecimal strings to numbers. For these
552** system. In Pentium machines, a naive typecast from double to int 421** systems, you can leave 'lua_strx2number' undefined and Lua will
553** in C is extremely slow, so any alternative is worth trying. 422** provide its own implementation.
554*/ 423*/
424#define lua_str2number(s,p) strtol((s), (p), 10)
555 425
556/* On a Pentium, resort to a trick */ 426#define lua_strx2number(s,p) strtoul((s), (p), 16)
557#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
558 (defined(__i386) || defined (_M_IX86) || defined(__i386__))
559
560/* On a Microsoft compiler, use assembler */
561#if defined(_MSC_VER)
562
563#define lua_number2int(i,d) __asm fld d __asm fistp i
564#define lua_number2integer(i,n) lua_number2int(i, n)
565
566/* the next trick should work on any Pentium, but sometimes clashes
567 with a DirectX idiosyncrasy */
568#else
569 427
570union luai_Cast { double l_d; long l_l; };
571#define lua_number2int(i,d) \
572 { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
573#define lua_number2integer(i,n) lua_number2int(i, n)
574
575#endif
576 428
429/*
430@@ The luai_num* macros define the primitive operations over numbers.
431*/
577 432
578/* this option always works, but may be slow */
579#else
580#define lua_number2int(i,d) ((i)=(int)(d))
581#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
582 433
434/* these are quite standard operations */
435#if defined(LUA_CORE)
436extern long rb_pow(long, long);
437#define luai_numadd(L,a,b) ((a)+(b))
438#define luai_numsub(L,a,b) ((a)-(b))
439#define luai_nummul(L,a,b) ((a)*(b))
440#define luai_numdiv(L,a,b) ((a)/(b))
441#define luai_nummod(L,a,b) ((a)%(b))
442#define luai_numpow(L,a,b) (rb_pow(a,b))
443#define luai_numunm(L,a) (-(a))
444#define luai_numeq(a,b) ((a)==(b))
445#define luai_numlt(L,a,b) ((a)<(b))
446#define luai_numle(L,a,b) ((a)<=(b))
447#define luai_numisnan(L,a) (!luai_numeq((a), (a)))
583#endif 448#endif
584 449
585/* }================================================================== */
586 450
587 451
588/* 452/*
589@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. 453@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
590** CHANGE it if your system requires alignments larger than double. (For 454** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
591** instance, if your system supports long doubles and they must be 455** machines, ptrdiff_t gives a good choice between int or long.)
592** aligned in 16-byte boundaries, then you should add long double in the
593** union.) Probably you do not need to change this.
594*/ 456*/
595#define LUAI_USER_ALIGNMENT_T union { void *s; long l; } 457#define LUA_INTEGER ptrdiff_t
596
597 458
598/* 459/*
599@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling. 460@@ LUA_UNSIGNED is the integral type used by lua_pushunsigned/lua_tounsigned.
600** CHANGE them if you prefer to use longjmp/setjmp even with C++ 461** It must have at least 32 bits.
601** or if want/don't to use _longjmp/_setjmp instead of regular
602** longjmp/setjmp. By default, Lua handles errors with exceptions when
603** compiling as C++ code, with _longjmp/_setjmp when asked to use them,
604** and with longjmp/setjmp otherwise.
605*/ 462*/
606#if defined(__cplusplus) 463#define LUA_UNSIGNED unsigned LUA_INT32
607/* C++ exceptions */
608#define LUAI_THROW(L,c) throw(c)
609#define LUAI_TRY(L,c,a) try { a } catch(...) \
610 { if ((c)->status == 0) (c)->status = -1; }
611#define luai_jmpbuf int /* dummy variable */
612
613#elif defined(LUA_USE_ULONGJMP)
614/* in Unix, try _longjmp/_setjmp (more efficient) */
615#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
616#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
617#define luai_jmpbuf jmp_buf
618
619#else
620/* default handling with long jumps */
621#define LUAI_THROW(L,c) longjmp((c)->b, 1)
622#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
623#define luai_jmpbuf jmp_buf
624 464
625#endif
626 465
627 466
628/* 467/*
629@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern 468** Some tricks with doubles
630@* can do during pattern-matching.
631** CHANGE it if you need more captures. This limit is arbitrary.
632*/ 469*/
633#define LUA_MAXCAPTURES 32
634
635 470
471#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */
636/* 472/*
637@@ lua_tmpnam is the function that the OS library uses to create a 473** The next definitions activate some tricks to speed up the
638@* temporary name. 474** conversion from doubles to integer types, mainly to LUA_UNSIGNED.
639@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam. 475**
640** CHANGE them if you have an alternative to tmpnam (which is considered 476@@ LUA_MSASMTRICK uses Microsoft assembler to avoid clashes with a
641** insecure) or if you want the original tmpnam anyway. By default, Lua 477** DirectX idiosyncrasy.
642** uses tmpnam except when POSIX is available, where it uses mkstemp. 478**
479@@ LUA_IEEE754TRICK uses a trick that should work on any machine
480** using IEEE754 with a 32-bit integer type.
481**
482@@ LUA_IEEELL extends the trick to LUA_INTEGER; should only be
483** defined when LUA_INTEGER is a 32-bit integer.
484**
485@@ LUA_IEEEENDIAN is the endianness of doubles in your machine
486** (0 for little endian, 1 for big endian); if not defined, Lua will
487** check it dynamically for LUA_IEEE754TRICK (but not for LUA_NANTRICK).
488**
489@@ LUA_NANTRICK controls the use of a trick to pack all types into
490** a single double value, using NaN values to represent non-number
491** values. The trick only works on 32-bit machines (ints and pointers
492** are 32-bit values) with numbers represented as IEEE 754-2008 doubles
493** with conventional endianess (12345678 or 87654321), in CPUs that do
494** not produce signaling NaN values (all NaNs are quiet).
643*/ 495*/
644#if defined(loslib_c) || defined(luaall_c)
645
646#if defined(LUA_USE_MKSTEMP)
647#include <unistd.h>
648#define LUA_TMPNAMBUFSIZE 32
649#define lua_tmpnam(b,e) { \
650 strcpy(b, "/tmp/lua_XXXXXX"); \
651 e = mkstemp(b); \
652 if (e != -1) close(e); \
653 e = (e == -1); }
654
655#else
656#define LUA_TMPNAMBUFSIZE L_tmpnam
657#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
658#endif
659
660#endif
661
662
663/*
664@@ lua_popen spawns a new process connected to the current one through
665@* the file streams.
666** CHANGE it if you have a way to implement it in your system.
667*/
668#if defined(LUA_USE_POPEN)
669
670#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m))
671#define lua_pclose(L,file) ((void)L, (pclose(file) != -1))
672 496
673#elif defined(LUA_WIN) 497/* Microsoft compiler on a Pentium (32 bit) ? */
498#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */
674 499
675#define lua_popen(L,c,m) ((void)L, _popen(c,m)) 500#define LUA_MSASMTRICK
676#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1)) 501#define LUA_IEEEENDIAN 0
502#define LUA_NANTRICK
677 503
678#else
679 504
680#define lua_popen(L,c,m) ((void)((void)c, m), \ 505/* pentium 32 bits? */
681 luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) 506#elif defined(__i386__) || defined(__i386) || defined(__X86__) /* }{ */
682#define lua_pclose(L,file) ((void)((void)L, file), 0)
683 507
684#endif 508#define LUA_IEEE754TRICK
509#define LUA_IEEELL
510#define LUA_IEEEENDIAN 0
511#define LUA_NANTRICK
685 512
686/* 513/* pentium 64 bits? */
687@@ LUA_DL_* define which dynamic-library system Lua should use. 514#elif defined(__x86_64) /* }{ */
688** CHANGE here if Lua has problems choosing the appropriate
689** dynamic-library system for your platform (either Windows' DLL, Mac's
690** dyld, or Unix's dlopen). If your system is some kind of Unix, there
691** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for
692** it. To use dlopen you also need to adapt the src/Makefile (probably
693** adding -ldl to the linker options), so Lua does not select it
694** automatically. (When you change the makefile to add -ldl, you must
695** also add -DLUA_USE_DLOPEN.)
696** If you do not want any kind of dynamic library, undefine all these
697** options.
698** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD.
699*/
700#if defined(LUA_USE_DLOPEN)
701#define LUA_DL_DLOPEN
702#endif
703 515
704#if defined(LUA_WIN) 516#define LUA_IEEE754TRICK
705#define LUA_DL_DLL 517#define LUA_IEEEENDIAN 0
706#endif
707 518
519#elif defined(__POWERPC__) || defined(__ppc__) /* }{ */
708 520
709/* 521#define LUA_IEEE754TRICK
710@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State 522#define LUA_IEEEENDIAN 1
711@* (the data goes just *before* the lua_State pointer).
712** CHANGE (define) this if you really need that. This value must be
713** a multiple of the maximum alignment required for your machine.
714*/
715#define LUAI_EXTRASPACE 0
716 523
524#else /* }{ */
717 525
718/* 526/* assume IEEE754 and a 32-bit integer type */
719@@ luai_userstate* allow user-specific actions on threads. 527#define LUA_IEEE754TRICK
720** CHANGE them if you defined LUAI_EXTRASPACE and need to do something
721** extra when a thread is created/deleted/resumed/yielded.
722*/
723#define luai_userstateopen(L) ((void)L)
724#define luai_userstateclose(L) ((void)L)
725#define luai_userstatethread(L,L1) ((void)L)
726#define luai_userstatefree(L) ((void)L)
727#define luai_userstateresume(L,n) ((void)L)
728#define luai_userstateyield(L,n) ((void)L)
729
730
731/*
732@@ LUA_INTFRMLEN is the length modifier for integer conversions
733@* in 'string.format'.
734@@ LUA_INTFRM_T is the integer type correspoding to the previous length
735@* modifier.
736** CHANGE them if your system supports long long or does not support long.
737*/
738 528
739#if defined(LUA_USELONGLONG) 529#endif /* } */
740 530
741#define LUA_INTFRMLEN "ll" 531#endif /* } */
742#define LUA_INTFRM_T long long
743 532
744#else 533/* }================================================================== */
745
746#define LUA_INTFRMLEN "l"
747#define LUA_INTFRM_T long
748 534
749#endif
750 535
751 536
752 537
@@ -758,6 +543,7 @@ union luai_Cast { double l_d; long l_l; };
758*/ 543*/
759 544
760#include "rockconf.h" 545#include "rockconf.h"
546#define LUA_USE_CTYPE 1
761 547
762#endif 548#endif
763 549
diff --git a/apps/plugins/lua/luadir.c b/apps/plugins/lua/luadir.c
index c8c21d2c65..3c65b28bc7 100644
--- a/apps/plugins/lua/luadir.c
+++ b/apps/plugins/lua/luadir.c
@@ -98,7 +98,7 @@ static int dir_iter_factory (lua_State *L) {
98 lua_setmetatable (L, -2); 98 lua_setmetatable (L, -2);
99 d->dir = rb->opendir (path); 99 d->dir = rb->opendir (path);
100 if (d->dir == NULL) 100 if (d->dir == NULL)
101 luaL_error (L, "cannot open %s: %d", path, errno); 101 luaL_error (L, "cannot open dir %s: %d", path, errno);
102 102
103 return 2; 103 return 2;
104} 104}
@@ -125,7 +125,7 @@ static int dir_create_meta (lua_State *L) {
125 return 1; 125 return 1;
126} 126}
127 127
128static const struct luaL_reg fslib[] = { 128static const struct luaL_Reg fslib[] = {
129 {"dir", dir_iter_factory}, 129 {"dir", dir_iter_factory},
130 {"mkdir", make_dir}, 130 {"mkdir", make_dir},
131 {"rmdir", remove_dir}, 131 {"rmdir", remove_dir},
diff --git a/apps/plugins/lua/lualib.h b/apps/plugins/lua/lualib.h
index d4f69fc4af..da82005c9d 100644
--- a/apps/plugins/lua/lualib.h
+++ b/apps/plugins/lua/lualib.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: lualib.h,v 1.43.1.1 2013/04/12 18:48:47 roberto Exp $
3** Lua standard libraries 3** Lua standard libraries
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -11,43 +11,43 @@
11#include "lua.h" 11#include "lua.h"
12 12
13 13
14/* Key to file-handle type */
15#define LUA_FILEHANDLE "FILE*"
16 14
15LUAMOD_API int (luaopen_base) (lua_State *L);
17 16
18#define LUA_COLIBNAME "coroutine" 17#define LUA_COLIBNAME "coroutine"
19LUALIB_API int (luaopen_base) (lua_State *L); 18LUAMOD_API int (luaopen_coroutine) (lua_State *L);
20 19
21#define LUA_TABLIBNAME "table" 20#define LUA_TABLIBNAME "table"
22LUALIB_API int (luaopen_table) (lua_State *L); 21LUAMOD_API int (luaopen_table) (lua_State *L);
23 22
24#define LUA_IOLIBNAME "io" 23#define LUA_IOLIBNAME "io"
25LUALIB_API int (luaopen_io) (lua_State *L); 24LUAMOD_API int (luaopen_io) (lua_State *L);
26 25
27#define LUA_OSLIBNAME "os" 26#define LUA_OSLIBNAME "os"
28LUALIB_API int (luaopen_os) (lua_State *L); 27LUAMOD_API int (luaopen_os) (lua_State *L);
29 28
30#define LUA_STRLIBNAME "string" 29#define LUA_STRLIBNAME "string"
31LUALIB_API int (luaopen_string) (lua_State *L); 30LUAMOD_API int (luaopen_string) (lua_State *L);
31
32#define LUA_BITLIBNAME "bit32"
33LUAMOD_API int (luaopen_bit32) (lua_State *L);
32 34
33#define LUA_MATHLIBNAME "math" 35#define LUA_MATHLIBNAME "math"
34LUALIB_API int (luaopen_math) (lua_State *L); 36LUAMOD_API int (luaopen_math) (lua_State *L);
35 37
36#define LUA_DBLIBNAME "debug" 38#define LUA_DBLIBNAME "debug"
37LUALIB_API int (luaopen_debug) (lua_State *L); 39LUAMOD_API int (luaopen_debug) (lua_State *L);
38 40
39#define LUA_LOADLIBNAME "package" 41#define LUA_LOADLIBNAME "package"
40LUALIB_API int (luaopen_package) (lua_State *L); 42LUAMOD_API int (luaopen_package) (lua_State *L);
41 43
42#define LUA_BITLIBNAME "bit"
43LUALIB_API int (luaopen_bit) (lua_State *L);
44 44
45/* open all previous libraries */ 45/* open all previous libraries */
46LUALIB_API void (luaL_openlibs) (lua_State *L); 46LUALIB_API void (luaL_openlibs) (lua_State *L);
47 47
48 48
49 49
50#ifndef lua_assert 50#if !defined(lua_assert)
51#define lua_assert(x) ((void)0) 51#define lua_assert(x) ((void)0)
52#endif 52#endif
53 53
diff --git a/apps/plugins/lua/lundump.c b/apps/plugins/lua/lundump.c
index 8010a45795..0db70d20ea 100644
--- a/apps/plugins/lua/lundump.c
+++ b/apps/plugins/lua/lundump.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $ 2** $Id: lundump.c,v 2.22.1.1 2013/04/12 18:48:47 roberto Exp $
3** load precompiled Lua chunks 3** load precompiled Lua chunks
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -27,28 +27,24 @@ typedef struct {
27 const char* name; 27 const char* name;
28} LoadState; 28} LoadState;
29 29
30#ifdef LUAC_TRUST_BINARIES 30static l_noret error(LoadState* S, const char* why)
31#define IF(c,s)
32#define error(S,s)
33#else
34#define IF(c,s) if (c) error(S,s)
35
36static void error(LoadState* S, const char* why)
37{ 31{
38 luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why); 32 luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why);
39 luaD_throw(S->L,LUA_ERRSYNTAX); 33 luaD_throw(S->L,LUA_ERRSYNTAX);
40} 34}
41#endif
42 35
43#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) 36#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
44#define LoadByte(S) (lu_byte)LoadChar(S) 37#define LoadByte(S) (lu_byte)LoadChar(S)
45#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) 38#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
46#define LoadVector(S,b,n,size) LoadMem(S,b,n,size) 39#define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
47 40
41#if !defined(luai_verifycode)
42#define luai_verifycode(L,b,f) /* empty */
43#endif
44
48static void LoadBlock(LoadState* S, void* b, size_t size) 45static void LoadBlock(LoadState* S, void* b, size_t size)
49{ 46{
50 size_t r=luaZ_read(S->Z,b,size); 47 if (luaZ_read(S->Z,b,size)!=0) error(S,"truncated");
51 IF (r!=0, "unexpected end");
52} 48}
53 49
54static int LoadChar(LoadState* S) 50static int LoadChar(LoadState* S)
@@ -62,7 +58,7 @@ static int LoadInt(LoadState* S)
62{ 58{
63 int x; 59 int x;
64 LoadVar(S,x); 60 LoadVar(S,x);
65 IF (x<0, "bad integer"); 61 if (x<0) error(S,"corrupted");
66 return x; 62 return x;
67} 63}
68 64
@@ -82,7 +78,7 @@ static TString* LoadString(LoadState* S)
82 else 78 else
83 { 79 {
84 char* s=luaZ_openspace(S->L,S->b,size); 80 char* s=luaZ_openspace(S->L,S->b,size);
85 LoadBlock(S,s,size); 81 LoadBlock(S,s,size*sizeof(char));
86 return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ 82 return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
87 } 83 }
88} 84}
@@ -95,7 +91,7 @@ static void LoadCode(LoadState* S, Proto* f)
95 LoadVector(S,f->code,n,sizeof(Instruction)); 91 LoadVector(S,f->code,n,sizeof(Instruction));
96} 92}
97 93
98static Proto* LoadFunction(LoadState* S, TString* p); 94static void LoadFunction(LoadState* S, Proto* f);
99 95
100static void LoadConstants(LoadState* S, Proto* f) 96static void LoadConstants(LoadState* S, Proto* f)
101{ 97{
@@ -111,10 +107,10 @@ static void LoadConstants(LoadState* S, Proto* f)
111 switch (t) 107 switch (t)
112 { 108 {
113 case LUA_TNIL: 109 case LUA_TNIL:
114 setnilvalue(o); 110 setnilvalue(o);
115 break; 111 break;
116 case LUA_TBOOLEAN: 112 case LUA_TBOOLEAN:
117 setbvalue(o,LoadChar(S)!=0); 113 setbvalue(o,LoadChar(S));
118 break; 114 break;
119 case LUA_TNUMBER: 115 case LUA_TNUMBER:
120 setnvalue(o,LoadNumber(S)); 116 setnvalue(o,LoadNumber(S));
@@ -122,21 +118,38 @@ static void LoadConstants(LoadState* S, Proto* f)
122 case LUA_TSTRING: 118 case LUA_TSTRING:
123 setsvalue2n(S->L,o,LoadString(S)); 119 setsvalue2n(S->L,o,LoadString(S));
124 break; 120 break;
125 default: 121 default: lua_assert(0);
126 error(S,"bad constant");
127 break;
128 } 122 }
129 } 123 }
130 n=LoadInt(S); 124 n=LoadInt(S);
131 f->p=luaM_newvector(S->L,n,Proto*); 125 f->p=luaM_newvector(S->L,n,Proto*);
132 f->sizep=n; 126 f->sizep=n;
133 for (i=0; i<n; i++) f->p[i]=NULL; 127 for (i=0; i<n; i++) f->p[i]=NULL;
134 for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source); 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 }
135} 147}
136 148
137static void LoadDebug(LoadState* S, Proto* f) 149static void LoadDebug(LoadState* S, Proto* f)
138{ 150{
139 int i,n; 151 int i,n;
152 f->source=LoadString(S);
140 n=LoadInt(S); 153 n=LoadInt(S);
141 f->lineinfo=luaM_newvector(S->L,n,int); 154 f->lineinfo=luaM_newvector(S->L,n,int);
142 f->sizelineinfo=n; 155 f->sizelineinfo=n;
@@ -152,49 +165,48 @@ static void LoadDebug(LoadState* S, Proto* f)
152 f->locvars[i].endpc=LoadInt(S); 165 f->locvars[i].endpc=LoadInt(S);
153 } 166 }
154 n=LoadInt(S); 167 n=LoadInt(S);
155 f->upvalues=luaM_newvector(S->L,n,TString*); 168 for (i=0; i<n; i++) f->upvalues[i].name=LoadString(S);
156 f->sizeupvalues=n;
157 for (i=0; i<n; i++) f->upvalues[i]=NULL;
158 for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
159} 169}
160 170
161static Proto* LoadFunction(LoadState* S, TString* p) 171static void LoadFunction(LoadState* S, Proto* f)
162{ 172{
163 Proto* f;
164 if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
165 f=luaF_newproto(S->L);
166 setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
167 f->source=LoadString(S); if (f->source==NULL) f->source=p;
168 f->linedefined=LoadInt(S); 173 f->linedefined=LoadInt(S);
169 f->lastlinedefined=LoadInt(S); 174 f->lastlinedefined=LoadInt(S);
170 f->nups=LoadByte(S);
171 f->numparams=LoadByte(S); 175 f->numparams=LoadByte(S);
172 f->is_vararg=LoadByte(S); 176 f->is_vararg=LoadByte(S);
173 f->maxstacksize=LoadByte(S); 177 f->maxstacksize=LoadByte(S);
174 LoadCode(S,f); 178 LoadCode(S,f);
175 LoadConstants(S,f); 179 LoadConstants(S,f);
180 LoadUpvalues(S,f);
176 LoadDebug(S,f); 181 LoadDebug(S,f);
177 IF (!luaG_checkcode(f), "bad code");
178 S->L->top--;
179 S->L->nCcalls--;
180 return f;
181} 182}
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
183static void LoadHeader(LoadState* S) 190static void LoadHeader(LoadState* S)
184{ 191{
185 char h[LUAC_HEADERSIZE]; 192 lu_byte h[LUAC_HEADERSIZE];
186 char s[LUAC_HEADERSIZE]; 193 lu_byte s[LUAC_HEADERSIZE];
187 luaU_header(h); 194 luaU_header(h);
188 LoadBlock(S,s,LUAC_HEADERSIZE); 195 memcpy(s,h,sizeof(char)); /* first char already read */
189 IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header"); 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");
190} 201}
191 202
192/* 203/*
193** load precompiled chunk 204** load precompiled chunk
194*/ 205*/
195Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) 206Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
196{ 207{
197 LoadState S; 208 LoadState S;
209 Closure* cl;
198 if (*name=='@' || *name=='=') 210 if (*name=='@' || *name=='=')
199 S.name=name+1; 211 S.name=name+1;
200 else if (*name==LUA_SIGNATURE[0]) 212 else if (*name==LUA_SIGNATURE[0])
@@ -205,23 +217,43 @@ Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
205 S.Z=Z; 217 S.Z=Z;
206 S.b=buff; 218 S.b=buff;
207 LoadHeader(&S); 219 LoadHeader(&S);
208 return LoadFunction(&S,luaS_newliteral(L,"=?")); 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;
209} 233}
210 234
235#define MYINT(s) (s[0]-'0')
236#undef VERSION
237#define VERSION MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)
238#define FORMAT 0 /* this is the official format */
239
211/* 240/*
212* make header 241* make header for precompiled chunks
242* if you change the code below be sure to update LoadHeader and FORMAT above
243* and LUAC_HEADERSIZE in lundump.h
213*/ 244*/
214void luaU_header (char* h) 245void luaU_header (lu_byte* h)
215{ 246{
216 int x=1; 247 int x=1;
217 memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); 248 memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-sizeof(char));
218 h+=sizeof(LUA_SIGNATURE)-1; 249 h+=sizeof(LUA_SIGNATURE)-sizeof(char);
219 *h++=(char)LUAC_VERSION; 250 *h++=cast_byte(VERSION);
220 *h++=(char)LUAC_FORMAT; 251 *h++=cast_byte(FORMAT);
221 *h++=(char)*(char*)&x; /* endianness */ 252 *h++=cast_byte(*(char*)&x); /* endianness */
222 *h++=(char)sizeof(int); 253 *h++=cast_byte(sizeof(int));
223 *h++=(char)sizeof(size_t); 254 *h++=cast_byte(sizeof(size_t));
224 *h++=(char)sizeof(Instruction); 255 *h++=cast_byte(sizeof(Instruction));
225 *h++=(char)sizeof(lua_Number); 256 *h++=cast_byte(sizeof(lua_Number));
226 *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ 257 *h++=cast_byte(((lua_Number)0.5)==0); /* is lua_Number integral? */
258 memcpy(h,LUAC_TAIL,sizeof(LUAC_TAIL)-sizeof(char));
227} 259}
diff --git a/apps/plugins/lua/lundump.h b/apps/plugins/lua/lundump.h
index f791a4f173..5255db259d 100644
--- a/apps/plugins/lua/lundump.h
+++ b/apps/plugins/lua/lundump.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: lundump.h,v 1.39.1.1 2013/04/12 18:48:47 roberto Exp $
3** load precompiled Lua chunks 3** load precompiled Lua chunks
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -11,26 +11,18 @@
11#include "lzio.h" 11#include "lzio.h"
12 12
13/* load one chunk; from lundump.c */ 13/* load one chunk; from lundump.c */
14LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); 14LUAI_FUNC Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
15 15
16/* make header; from lundump.c */ 16/* make header; from lundump.c */
17LUAI_FUNC void luaU_header (char* h); 17LUAI_FUNC void luaU_header (lu_byte* h);
18 18
19/* dump one chunk; from ldump.c */ 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); 20LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
21 21
22#ifdef luac_c 22/* data to catch conversion errors */
23/* print one chunk; from print.c */ 23#define LUAC_TAIL "\x19\x93\r\n\x1a\n"
24LUAI_FUNC void luaU_print (const Proto* f, int full);
25#endif
26
27/* for header of binary files -- this is Lua 5.1 */
28#define LUAC_VERSION 0x51
29
30/* for header of binary files -- this is the official format */
31#define LUAC_FORMAT 0
32 24
33/* size of header of binary files */ 25/* size in bytes of header of binary files */
34#define LUAC_HEADERSIZE 12 26#define LUAC_HEADERSIZE (sizeof(LUA_SIGNATURE)-sizeof(char)+2+6+sizeof(LUAC_TAIL)-sizeof(char))
35 27
36#endif 28#endif
diff --git a/apps/plugins/lua/lvm.c b/apps/plugins/lua/lvm.c
index ee3256ab94..141b9fd19c 100644
--- a/apps/plugins/lua/lvm.c
+++ b/apps/plugins/lua/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.63.1.3 2007/12/28 15:32:23 roberto Exp $ 2** $Id: lvm.c,v 2.155.1.1 2013/04/12 18:48:47 roberto Exp $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -35,7 +35,7 @@
35const TValue *luaV_tonumber (const TValue *obj, TValue *n) { 35const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
36 lua_Number num; 36 lua_Number num;
37 if (ttisnumber(obj)) return obj; 37 if (ttisnumber(obj)) return obj;
38 if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { 38 if (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, &num)) {
39 setnvalue(n, num); 39 setnvalue(n, num);
40 return n; 40 return n;
41 } 41 }
@@ -50,58 +50,60 @@ int luaV_tostring (lua_State *L, StkId obj) {
50 else { 50 else {
51 char s[LUAI_MAXNUMBER2STR]; 51 char s[LUAI_MAXNUMBER2STR];
52 lua_Number n = nvalue(obj); 52 lua_Number n = nvalue(obj);
53 lua_number2str(s, n); 53 int l = lua_number2str(s, n);
54 setsvalue2s(L, obj, luaS_new(L, s)); 54 setsvalue2s(L, obj, luaS_newlstr(L, s, l));
55 return 1; 55 return 1;
56 } 56 }
57} 57}
58 58
59 59
60static void traceexec (lua_State *L, const Instruction *pc) { 60static void traceexec (lua_State *L) {
61 CallInfo *ci = L->ci;
61 lu_byte mask = L->hookmask; 62 lu_byte mask = L->hookmask;
62 const Instruction *oldpc = L->savedpc; 63 int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0);
63 L->savedpc = pc; 64 if (counthook)
64 if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { 65 resethookcount(L); /* reset count */
65 resethookcount(L); 66 if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */
66 luaD_callhook(L, LUA_HOOKCOUNT, -1); 67 ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */
68 return; /* do not call hook again (VM yielded, so it did not move) */
67 } 69 }
70 if (counthook)
71 luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */
68 if (mask & LUA_MASKLINE) { 72 if (mask & LUA_MASKLINE) {
69 Proto *p = ci_func(L->ci)->l.p; 73 Proto *p = ci_func(ci)->p;
70 int npc = pcRel(pc, p); 74 int npc = pcRel(ci->u.l.savedpc, p);
71 int newline = getline(p, npc); 75 int newline = getfuncline(p, npc);
72 /* call linehook when enter a new function, when jump back (loop), 76 if (npc == 0 || /* call linehook when enter a new function, */
73 or when enter a new line */ 77 ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */
74 if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p))) 78 newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */
75 luaD_callhook(L, LUA_HOOKLINE, newline); 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);
76 } 89 }
77} 90}
78 91
79 92
80static void callTMres (lua_State *L, StkId res, const TValue *f,
81 const TValue *p1, const TValue *p2) {
82 ptrdiff_t result = savestack(L, res);
83 setobj2s(L, L->top, f); /* push function */
84 setobj2s(L, L->top+1, p1); /* 1st argument */
85 setobj2s(L, L->top+2, p2); /* 2nd argument */
86 luaD_checkstack(L, 3);
87 L->top += 3;
88 luaD_call(L, L->top - 3, 1);
89 res = restorestack(L, result);
90 L->top--;
91 setobjs2s(L, res, L->top);
92}
93
94
95
96static void callTM (lua_State *L, const TValue *f, const TValue *p1, 93static void callTM (lua_State *L, const TValue *f, const TValue *p1,
97 const TValue *p2, const TValue *p3) { 94 const TValue *p2, TValue *p3, int hasres) {
98 setobj2s(L, L->top, f); /* push function */ 95 ptrdiff_t result = savestack(L, p3);
99 setobj2s(L, L->top+1, p1); /* 1st argument */ 96 setobj2s(L, L->top++, f); /* push function */
100 setobj2s(L, L->top+2, p2); /* 2nd argument */ 97 setobj2s(L, L->top++, p1); /* 1st argument */
101 setobj2s(L, L->top+3, p3); /* 3th argument */ 98 setobj2s(L, L->top++, p2); /* 2nd argument */
102 luaD_checkstack(L, 4); 99 if (!hasres) /* no result? 'p3' is third argument */
103 L->top += 4; 100 setobj2s(L, L->top++, p3); /* 3rd argument */
104 luaD_call(L, L->top - 4, 0); 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 }
105} 107}
106 108
107 109
@@ -112,7 +114,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
112 if (ttistable(t)) { /* `t' is a table? */ 114 if (ttistable(t)) { /* `t' is a table? */
113 Table *h = hvalue(t); 115 Table *h = hvalue(t);
114 const TValue *res = luaH_get(h, key); /* do a primitive get */ 116 const TValue *res = luaH_get(h, key); /* do a primitive get */
115 if (!ttisnil(res) || /* result is no nil? */ 117 if (!ttisnil(res) || /* result is not nil? */
116 (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ 118 (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
117 setobj2s(L, val, res); 119 setobj2s(L, val, res);
118 return; 120 return;
@@ -122,10 +124,10 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
122 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) 124 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
123 luaG_typeerror(L, t, "index"); 125 luaG_typeerror(L, t, "index");
124 if (ttisfunction(tm)) { 126 if (ttisfunction(tm)) {
125 callTMres(L, val, tm, t, key); 127 callTM(L, tm, t, key, val, 1);
126 return; 128 return;
127 } 129 }
128 t = tm; /* else repeat with `tm' */ 130 t = tm; /* else repeat with 'tm' */
129 } 131 }
130 luaG_runerror(L, "loop in gettable"); 132 luaG_runerror(L, "loop in gettable");
131} 133}
@@ -137,22 +139,34 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
137 const TValue *tm; 139 const TValue *tm;
138 if (ttistable(t)) { /* `t' is a table? */ 140 if (ttistable(t)) { /* `t' is a table? */
139 Table *h = hvalue(t); 141 Table *h = hvalue(t);
140 TValue *oldval = luaH_set(L, h, key); /* do a primitive set */ 142 TValue *oldval = cast(TValue *, luaH_get(h, key));
141 if (!ttisnil(oldval) || /* result is no nil? */ 143 /* if previous value is not nil, there must be a previous entry
142 (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ 144 in the table; moreover, a metamethod has no relevance */
143 setobj2t(L, oldval, val); 145 if (!ttisnil(oldval) ||
144 luaC_barriert(L, h, val); 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);
145 return; 157 return;
146 } 158 }
147 /* else will try the tag method */ 159 /* else will try the metamethod */
148 } 160 }
149 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) 161 else /* not a table; check metamethod */
150 luaG_typeerror(L, t, "index"); 162 if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
163 luaG_typeerror(L, t, "index");
164 /* there is a metamethod */
151 if (ttisfunction(tm)) { 165 if (ttisfunction(tm)) {
152 callTM(L, tm, t, key, val); 166 callTM(L, tm, t, key, val, 0);
153 return; 167 return;
154 } 168 }
155 t = tm; /* else repeat with `tm' */ 169 t = tm; /* else repeat with 'tm' */
156 } 170 }
157 luaG_runerror(L, "loop in settable"); 171 luaG_runerror(L, "loop in settable");
158} 172}
@@ -164,12 +178,12 @@ static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
164 if (ttisnil(tm)) 178 if (ttisnil(tm))
165 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ 179 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
166 if (ttisnil(tm)) return 0; 180 if (ttisnil(tm)) return 0;
167 callTMres(L, res, tm, p1, p2); 181 callTM(L, tm, p1, p2, res, 1);
168 return 1; 182 return 1;
169} 183}
170 184
171 185
172static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2, 186static const TValue *get_equalTM (lua_State *L, Table *mt1, Table *mt2,
173 TMS event) { 187 TMS event) {
174 const TValue *tm1 = fasttm(L, mt1, event); 188 const TValue *tm1 = fasttm(L, mt1, event);
175 const TValue *tm2; 189 const TValue *tm2;
@@ -177,7 +191,7 @@ static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
177 if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ 191 if (mt1 == mt2) return tm1; /* same metatables => same metamethods */
178 tm2 = fasttm(L, mt2, event); 192 tm2 = fasttm(L, mt2, event);
179 if (tm2 == NULL) return NULL; /* no metamethod */ 193 if (tm2 == NULL) return NULL; /* no metamethod */
180 if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */ 194 if (luaV_rawequalobj(tm1, tm2)) /* same metamethods? */
181 return tm1; 195 return tm1;
182 return NULL; 196 return NULL;
183} 197}
@@ -185,14 +199,10 @@ static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
185 199
186static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, 200static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
187 TMS event) { 201 TMS event) {
188 const TValue *tm1 = luaT_gettmbyobj(L, p1, event); 202 if (!call_binTM(L, p1, p2, L->top, event))
189 const TValue *tm2; 203 return -1; /* no metamethod */
190 if (ttisnil(tm1)) return -1; /* no metamethod? */ 204 else
191 tm2 = luaT_gettmbyobj(L, p2, event); 205 return !l_isfalse(L->top);
192 if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */
193 return -1;
194 callTMres(L, L->top, tm1, p1, p2);
195 return !l_isfalse(L->top);
196} 206}
197 207
198 208
@@ -220,125 +230,261 @@ static int l_strcmp (const TString *ls, const TString *rs) {
220 230
221int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { 231int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
222 int res; 232 int res;
223 if (ttype(l) != ttype(r)) 233 if (ttisnumber(l) && ttisnumber(r))
224 return luaG_ordererror(L, l, r); 234 return luai_numlt(L, nvalue(l), nvalue(r));
225 else if (ttisnumber(l)) 235 else if (ttisstring(l) && ttisstring(r))
226 return luai_numlt(nvalue(l), nvalue(r));
227 else if (ttisstring(l))
228 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; 236 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
229 else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) 237 else if ((res = call_orderTM(L, l, r, TM_LT)) < 0)
230 return res; 238 luaG_ordererror(L, l, r);
231 return luaG_ordererror(L, l, r); 239 return res;
232} 240}
233 241
234 242
235static int lessequal (lua_State *L, const TValue *l, const TValue *r) { 243int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
236 int res; 244 int res;
237 if (ttype(l) != ttype(r)) 245 if (ttisnumber(l) && ttisnumber(r))
238 return luaG_ordererror(L, l, r); 246 return luai_numle(L, nvalue(l), nvalue(r));
239 else if (ttisnumber(l)) 247 else if (ttisstring(l) && ttisstring(r))
240 return luai_numle(nvalue(l), nvalue(r));
241 else if (ttisstring(l))
242 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; 248 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
243 else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ 249 else if ((res = call_orderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */
244 return res; 250 return res;
245 else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ 251 else if ((res = call_orderTM(L, r, l, TM_LT)) < 0) /* else try `lt' */
246 return !res; 252 luaG_ordererror(L, l, r);
247 return luaG_ordererror(L, l, r); 253 return !res;
248} 254}
249 255
250 256
251int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { 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) {
252 const TValue *tm; 261 const TValue *tm;
253 lua_assert(ttype(t1) == ttype(t2)); 262 lua_assert(ttisequal(t1, t2));
254 switch (ttype(t1)) { 263 switch (ttype(t1)) {
255 case LUA_TNIL: return 1; 264 case LUA_TNIL: return 1;
256 case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); 265 case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
257 case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ 266 case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
258 case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); 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));
259 case LUA_TUSERDATA: { 271 case LUA_TUSERDATA: {
260 if (uvalue(t1) == uvalue(t2)) return 1; 272 if (uvalue(t1) == uvalue(t2)) return 1;
261 tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, 273 else if (L == NULL) return 0;
262 TM_EQ); 274 tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ);
263 break; /* will try TM */ 275 break; /* will try TM */
264 } 276 }
265 case LUA_TTABLE: { 277 case LUA_TTABLE: {
266 if (hvalue(t1) == hvalue(t2)) return 1; 278 if (hvalue(t1) == hvalue(t2)) return 1;
267 tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); 279 else if (L == NULL) return 0;
280 tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
268 break; /* will try TM */ 281 break; /* will try TM */
269 } 282 }
270 default: return gcvalue(t1) == gcvalue(t2); 283 default:
284 lua_assert(iscollectable(t1));
285 return gcvalue(t1) == gcvalue(t2);
271 } 286 }
272 if (tm == NULL) return 0; /* no TM? */ 287 if (tm == NULL) return 0; /* no TM? */
273 callTMres(L, L->top, tm, t1, t2); /* call TM */ 288 callTM(L, tm, t1, t2, L->top, 1); /* call TM */
274 return !l_isfalse(L->top); 289 return !l_isfalse(L->top);
275} 290}
276 291
277 292
278void luaV_concat (lua_State *L, int total, int last) { 293void luaV_concat (lua_State *L, int total) {
294 lua_assert(total >= 2);
279 do { 295 do {
280 StkId top = L->base + last + 1; 296 StkId top = L->top;
281 int n = 2; /* number of elements handled in this pass (at least 2) */ 297 int n = 2; /* number of elements handled in this pass (at least 2) */
282 if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { 298 if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
283 if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) 299 if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
284 luaG_concaterror(L, top-2, top-1); 300 luaG_concaterror(L, top-2, top-1);
285 } else if (tsvalue(top-1)->len == 0) /* second op is empty? */ 301 }
286 (void)tostring(L, top - 2); /* result is first op (as string) */ 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 }
287 else { 307 else {
288 /* at least two string values; get as many as possible */ 308 /* at least two non-empty string values; get as many as possible */
289 size_t tl = tsvalue(top-1)->len; 309 size_t tl = tsvalue(top-1)->len;
290 char *buffer; 310 char *buffer;
291 int i; 311 int i;
292 /* collect total length */ 312 /* collect total length */
293 for (n = 1; n < total && tostring(L, top-n-1); n++) { 313 for (i = 1; i < total && tostring(L, top-i-1); i++) {
294 size_t l = tsvalue(top-n-1)->len; 314 size_t l = tsvalue(top-i-1)->len;
295 if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); 315 if (l >= (MAX_SIZET/sizeof(char)) - tl)
316 luaG_runerror(L, "string length overflow");
296 tl += l; 317 tl += l;
297 } 318 }
298 buffer = luaZ_openspace(L, &G(L)->buff, tl); 319 buffer = luaZ_openspace(L, &G(L)->buff, tl);
299 tl = 0; 320 tl = 0;
300 for (i=n; i>0; i--) { /* concat all strings */ 321 n = i;
322 do { /* concat all strings */
301 size_t l = tsvalue(top-i)->len; 323 size_t l = tsvalue(top-i)->len;
302 memcpy(buffer+tl, svalue(top-i), l); 324 memcpy(buffer+tl, svalue(top-i), l * sizeof(char));
303 tl += l; 325 tl += l;
304 } 326 } while (--i > 0);
305 setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); 327 setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
306 } 328 }
307 total -= n-1; /* got `n' strings to create 1 new */ 329 total -= n-1; /* got 'n' strings to create 1 new */
308 last -= n-1; 330 L->top -= n-1; /* popped 'n' strings and pushed one */
309 } while (total > 1); /* repeat until only 1 result left */ 331 } while (total > 1); /* repeat until only 1 result left */
310} 332}
311 333
312 334
313static void Arith (lua_State *L, StkId ra, const TValue *rb, 335void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
314 const TValue *rc, TMS op) { 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(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) {
315 TValue tempb, tempc; 362 TValue tempb, tempc;
316 const TValue *b, *c; 363 const TValue *b, *c;
317 if ((b = luaV_tonumber(rb, &tempb)) != NULL && 364 if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
318 (c = luaV_tonumber(rc, &tempc)) != NULL) { 365 (c = luaV_tonumber(rc, &tempc)) != NULL) {
319 lua_Number nb = nvalue(b), nc = nvalue(c); 366 lua_Number res = luaO_arith(op - TM_ADD + LUA_OPADD, nvalue(b), nvalue(c));
320 switch (op) { 367 setnvalue(ra, res);
321 case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
322 case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
323 case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
324 case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
325 case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
326 case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
327 case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
328 default: lua_assert(0); break;
329 }
330 } 368 }
331 else if (!call_binTM(L, rb, rc, ra, op)) 369 else if (!call_binTM(L, rb, rc, ra, op))
332 luaG_aritherror(L, rb, rc); 370 luaG_aritherror(L, rb, rc);
333} 371}
334 372
335 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
336 479
337/* 480/*
338** some macros for common tasks in `luaV_execute' 481** some macros for common tasks in `luaV_execute'
339*/ 482*/
340 483
341#define runtime_check(L, c) { if (!(c)) break; } 484#if !defined luai_runtimecheck
485#define luai_runtimecheck(L, c) /* void */
486#endif
487
342 488
343#define RA(i) (base+GETARG_A(i)) 489#define RA(i) (base+GETARG_A(i))
344/* to be used after possible stack reallocation */ 490/* to be used after possible stack reallocation */
@@ -348,13 +494,27 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb,
348 ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) 494 ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
349#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ 495#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
350 ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) 496 ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
351#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) 497#define KBx(i) \
498 (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++)))
499
352 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; }
353 506
354#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);} 507/* for test instructions, execute the jump instruction that follows it */
508#define donextjump(ci) { i = *ci->u.l.savedpc; dojump(ci, i, 1); }
355 509
356 510
357#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; } 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); )
358 518
359 519
360#define arith_op(op,tm) { \ 520#define arith_op(op,tm) { \
@@ -362,401 +522,345 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb,
362 TValue *rc = RKC(i); \ 522 TValue *rc = RKC(i); \
363 if (ttisnumber(rb) && ttisnumber(rc)) { \ 523 if (ttisnumber(rb) && ttisnumber(rc)) { \
364 lua_Number nb = nvalue(rb), nc = nvalue(rc); \ 524 lua_Number nb = nvalue(rb), nc = nvalue(rc); \
365 setnvalue(ra, op(nb, nc)); \ 525 setnvalue(ra, op(L, nb, nc)); \
366 } \ 526 } \
367 else \ 527 else { Protect(luaV_arith(L, ra, rb, rc, tm)); } }
368 Protect(Arith(L, ra, rb, rc, tm)); \
369 }
370 528
371 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 */
372 533
373void luaV_execute (lua_State *L, int nexeccalls) { 534void luaV_execute (lua_State *L) {
535 CallInfo *ci = L->ci;
374 LClosure *cl; 536 LClosure *cl;
375 StkId base;
376 TValue *k; 537 TValue *k;
377 const Instruction *pc; 538 StkId base;
378 reentry: /* entry point */ 539 newframe: /* reentry point when frame changes (call/return) */
379 lua_assert(isLua(L->ci)); 540 lua_assert(ci == L->ci);
380 pc = L->savedpc; 541 cl = clLvalue(ci->func);
381 cl = &clvalue(L->ci->func)->l;
382 base = L->base;
383 k = cl->p->k; 542 k = cl->p->k;
543 base = ci->u.l.base;
384 /* main loop of interpreter */ 544 /* main loop of interpreter */
385 for (;;) { 545 for (;;) {
386 const Instruction i = *pc++; 546 Instruction i = *(ci->u.l.savedpc++);
387 StkId ra; 547 StkId ra;
388 if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && 548 if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
389 (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { 549 (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
390 traceexec(L, pc); 550 Protect(traceexec(L));
391 if (L->status == LUA_YIELD) { /* did hook yield? */
392 L->savedpc = pc - 1;
393 return;
394 }
395 base = L->base;
396 } 551 }
397 /* warning!! several calls may realloc the stack and invalidate `ra' */ 552 /* WARNING: several calls may realloc the stack and invalidate `ra' */
398 ra = RA(i); 553 ra = RA(i);
399 lua_assert(base == L->base && L->base == L->ci->base); 554 lua_assert(base == ci->u.l.base);
400 lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); 555 lua_assert(base <= L->top && L->top < L->stack + L->stacksize);
401 lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); 556 vmdispatch (GET_OPCODE(i)) {
402 switch (GET_OPCODE(i)) { 557 vmcase(OP_MOVE,
403 case OP_MOVE: {
404 setobjs2s(L, ra, RB(i)); 558 setobjs2s(L, ra, RB(i));
405 continue; 559 )
406 } 560 vmcase(OP_LOADK,
407 case OP_LOADK: { 561 TValue *rb = k + GETARG_Bx(i);
408 setobj2s(L, ra, KBx(i)); 562 setobj2s(L, ra, rb);
409 continue; 563 )
410 } 564 vmcase(OP_LOADKX,
411 case OP_LOADBOOL: { 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,
412 setbvalue(ra, GETARG_B(i)); 571 setbvalue(ra, GETARG_B(i));
413 if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ 572 if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */
414 continue; 573 )
415 } 574 vmcase(OP_LOADNIL,
416 case OP_LOADNIL: { 575 int b = GETARG_B(i);
417 TValue *rb = RB(i);
418 do { 576 do {
419 setnilvalue(rb--); 577 setnilvalue(ra++);
420 } while (rb >= ra); 578 } while (b--);
421 continue; 579 )
422 } 580 vmcase(OP_GETUPVAL,
423 case OP_GETUPVAL: {
424 int b = GETARG_B(i); 581 int b = GETARG_B(i);
425 setobj2s(L, ra, cl->upvals[b]->v); 582 setobj2s(L, ra, cl->upvals[b]->v);
426 continue; 583 )
427 } 584 vmcase(OP_GETTABUP,
428 case OP_GETGLOBAL: { 585 int b = GETARG_B(i);
429 TValue g; 586 Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra));
430 TValue *rb = KBx(i); 587 )
431 sethvalue(L, &g, cl->env); 588 vmcase(OP_GETTABLE,
432 lua_assert(ttisstring(rb));
433 Protect(luaV_gettable(L, &g, rb, ra));
434 continue;
435 }
436 case OP_GETTABLE: {
437 Protect(luaV_gettable(L, RB(i), RKC(i), ra)); 589 Protect(luaV_gettable(L, RB(i), RKC(i), ra));
438 continue; 590 )
439 } 591 vmcase(OP_SETTABUP,
440 case OP_SETGLOBAL: { 592 int a = GETARG_A(i);
441 TValue g; 593 Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i)));
442 sethvalue(L, &g, cl->env); 594 )
443 lua_assert(ttisstring(KBx(i))); 595 vmcase(OP_SETUPVAL,
444 Protect(luaV_settable(L, &g, KBx(i), ra));
445 continue;
446 }
447 case OP_SETUPVAL: {
448 UpVal *uv = cl->upvals[GETARG_B(i)]; 596 UpVal *uv = cl->upvals[GETARG_B(i)];
449 setobj(L, uv->v, ra); 597 setobj(L, uv->v, ra);
450 luaC_barrier(L, uv, ra); 598 luaC_barrier(L, uv, ra);
451 continue; 599 )
452 } 600 vmcase(OP_SETTABLE,
453 case OP_SETTABLE: {
454 Protect(luaV_settable(L, ra, RKB(i), RKC(i))); 601 Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
455 continue; 602 )
456 } 603 vmcase(OP_NEWTABLE,
457 case OP_NEWTABLE: {
458 int b = GETARG_B(i); 604 int b = GETARG_B(i);
459 int c = GETARG_C(i); 605 int c = GETARG_C(i);
460 sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c))); 606 Table *t = luaH_new(L);
461 Protect(luaC_checkGC(L)); 607 sethvalue(L, ra, t);
462 continue; 608 if (b != 0 || c != 0)
463 } 609 luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c));
464 case OP_SELF: { 610 checkGC(L, ra + 1);
611 )
612 vmcase(OP_SELF,
465 StkId rb = RB(i); 613 StkId rb = RB(i);
466 setobjs2s(L, ra+1, rb); 614 setobjs2s(L, ra+1, rb);
467 Protect(luaV_gettable(L, rb, RKC(i), ra)); 615 Protect(luaV_gettable(L, rb, RKC(i), ra));
468 continue; 616 )
469 } 617 vmcase(OP_ADD,
470 case OP_ADD: {
471 arith_op(luai_numadd, TM_ADD); 618 arith_op(luai_numadd, TM_ADD);
472 continue; 619 )
473 } 620 vmcase(OP_SUB,
474 case OP_SUB: {
475 arith_op(luai_numsub, TM_SUB); 621 arith_op(luai_numsub, TM_SUB);
476 continue; 622 )
477 } 623 vmcase(OP_MUL,
478 case OP_MUL: {
479 arith_op(luai_nummul, TM_MUL); 624 arith_op(luai_nummul, TM_MUL);
480 continue; 625 )
481 } 626 vmcase(OP_DIV,
482 case OP_DIV: {
483 arith_op(luai_numdiv, TM_DIV); 627 arith_op(luai_numdiv, TM_DIV);
484 continue; 628 )
485 } 629 vmcase(OP_MOD,
486 case OP_MOD: {
487 arith_op(luai_nummod, TM_MOD); 630 arith_op(luai_nummod, TM_MOD);
488 continue; 631 )
489 } 632 vmcase(OP_POW,
490 case OP_POW: {
491 arith_op(luai_numpow, TM_POW); 633 arith_op(luai_numpow, TM_POW);
492 continue; 634 )
493 } 635 vmcase(OP_UNM,
494 case OP_UNM: {
495 TValue *rb = RB(i); 636 TValue *rb = RB(i);
496 if (ttisnumber(rb)) { 637 if (ttisnumber(rb)) {
497 lua_Number nb = nvalue(rb); 638 lua_Number nb = nvalue(rb);
498 setnvalue(ra, luai_numunm(nb)); 639 setnvalue(ra, luai_numunm(L, nb));
499 } 640 }
500 else { 641 else {
501 Protect(Arith(L, ra, rb, rb, TM_UNM)); 642 Protect(luaV_arith(L, ra, rb, rb, TM_UNM));
502 } 643 }
503 continue; 644 )
504 } 645 vmcase(OP_NOT,
505 case OP_NOT: { 646 TValue *rb = RB(i);
506 int res = l_isfalse(RB(i)); /* next assignment may change this value */ 647 int res = l_isfalse(rb); /* next assignment may change this value */
507 setbvalue(ra, res); 648 setbvalue(ra, res);
508 continue; 649 )
509 } 650 vmcase(OP_LEN,
510 case OP_LEN: { 651 Protect(luaV_objlen(L, ra, RB(i)));
511 const TValue *rb = RB(i); 652 )
512 switch (ttype(rb)) { 653 vmcase(OP_CONCAT,
513 case LUA_TTABLE: {
514 setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
515 break;
516 }
517 case LUA_TSTRING: {
518 setnvalue(ra, cast_num(tsvalue(rb)->len));
519 break;
520 }
521 default: { /* try metamethod */
522 Protect(
523 if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))
524 luaG_typeerror(L, rb, "get length of");
525 )
526 }
527 }
528 continue;
529 }
530 case OP_CONCAT: {
531 int b = GETARG_B(i); 654 int b = GETARG_B(i);
532 int c = GETARG_C(i); 655 int c = GETARG_C(i);
533 Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L)); 656 StkId rb;
534 setobjs2s(L, RA(i), base+b); 657 L->top = base + c + 1; /* mark the end of concat operands */
535 continue; 658 Protect(luaV_concat(L, c - b + 1));
536 } 659 ra = RA(i); /* 'luav_concat' may invoke TMs and move the stack */
537 case OP_JMP: { 660 rb = b + base;
538 dojump(L, pc, GETARG_sBx(i)); 661 setobjs2s(L, ra, rb);
539 continue; 662 checkGC(L, (ra >= rb ? ra + 1 : rb));
540 } 663 L->top = ci->top; /* restore top */
541 case OP_EQ: { 664 )
665 vmcase(OP_JMP,
666 dojump(ci, i, 0);
667 )
668 vmcase(OP_EQ,
542 TValue *rb = RKB(i); 669 TValue *rb = RKB(i);
543 TValue *rc = RKC(i); 670 TValue *rc = RKC(i);
544 Protect( 671 Protect(
545 if (equalobj(L, rb, rc) == GETARG_A(i)) 672 if (cast_int(equalobj(L, rb, rc)) != GETARG_A(i))
546 dojump(L, pc, GETARG_sBx(*pc)); 673 ci->u.l.savedpc++;
674 else
675 donextjump(ci);
547 ) 676 )
548 pc++; 677 )
549 continue; 678 vmcase(OP_LT,
550 }
551 case OP_LT: {
552 Protect( 679 Protect(
553 if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) 680 if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i))
554 dojump(L, pc, GETARG_sBx(*pc)); 681 ci->u.l.savedpc++;
682 else
683 donextjump(ci);
555 ) 684 )
556 pc++; 685 )
557 continue; 686 vmcase(OP_LE,
558 }
559 case OP_LE: {
560 Protect( 687 Protect(
561 if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) 688 if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i))
562 dojump(L, pc, GETARG_sBx(*pc)); 689 ci->u.l.savedpc++;
690 else
691 donextjump(ci);
563 ) 692 )
564 pc++; 693 )
565 continue; 694 vmcase(OP_TEST,
566 } 695 if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra))
567 case OP_TEST: { 696 ci->u.l.savedpc++;
568 if (l_isfalse(ra) != GETARG_C(i)) 697 else
569 dojump(L, pc, GETARG_sBx(*pc)); 698 donextjump(ci);
570 pc++; 699 )
571 continue; 700 vmcase(OP_TESTSET,
572 }
573 case OP_TESTSET: {
574 TValue *rb = RB(i); 701 TValue *rb = RB(i);
575 if (l_isfalse(rb) != GETARG_C(i)) { 702 if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb))
703 ci->u.l.savedpc++;
704 else {
576 setobjs2s(L, ra, rb); 705 setobjs2s(L, ra, rb);
577 dojump(L, pc, GETARG_sBx(*pc)); 706 donextjump(ci);
578 } 707 }
579 pc++; 708 )
580 continue; 709 vmcase(OP_CALL,
581 }
582 case OP_CALL: {
583 int b = GETARG_B(i); 710 int b = GETARG_B(i);
584 int nresults = GETARG_C(i) - 1; 711 int nresults = GETARG_C(i) - 1;
585 if (b != 0) L->top = ra+b; /* else previous instruction set top */ 712 if (b != 0) L->top = ra+b; /* else previous instruction set top */
586 L->savedpc = pc; 713 if (luaD_precall(L, ra, nresults)) { /* C function? */
587 switch (luaD_precall(L, ra, nresults)) { 714 if (nresults >= 0) L->top = ci->top; /* adjust results */
588 case PCRLUA: { 715 base = ci->u.l.base;
589 nexeccalls++;
590 goto reentry; /* restart luaV_execute over new Lua function */
591 }
592 case PCRC: {
593 /* it was a C function (`precall' called it); adjust results */
594 if (nresults >= 0) L->top = L->ci->top;
595 base = L->base;
596 continue;
597 }
598 default: {
599 return; /* yield */
600 }
601 } 716 }
602 } 717 else { /* Lua function */
603 case OP_TAILCALL: { 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,
604 int b = GETARG_B(i); 724 int b = GETARG_B(i);
605 if (b != 0) L->top = ra+b; /* else previous instruction set top */ 725 if (b != 0) L->top = ra+b; /* else previous instruction set top */
606 L->savedpc = pc;
607 lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); 726 lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
608 switch (luaD_precall(L, ra, LUA_MULTRET)) { 727 if (luaD_precall(L, ra, LUA_MULTRET)) /* C function? */
609 case PCRLUA: { 728 base = ci->u.l.base;
610 /* tail call: put new frame in place of previous one */ 729 else {
611 CallInfo *ci = L->ci - 1; /* previous frame */ 730 /* tail call: put called frame (n) in place of caller one (o) */
612 int aux; 731 CallInfo *nci = L->ci; /* called frame */
613 StkId func = ci->func; 732 CallInfo *oci = nci->previous; /* caller frame */
614 StkId pfunc = (ci+1)->func; /* previous function index */ 733 StkId nfunc = nci->func; /* called function */
615 if (L->openupval) luaF_close(L, ci->base); 734 StkId ofunc = oci->func; /* caller function */
616 L->base = ci->base = ci->func + ((ci+1)->base - pfunc); 735 /* last stack slot filled by 'precall' */
617 for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ 736 StkId lim = nci->u.l.base + getproto(nfunc)->numparams;
618 setobjs2s(L, func+aux, pfunc+aux); 737 int aux;
619 ci->top = L->top = func+aux; /* correct top */ 738 /* close all upvalues from previous call */
620 lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); 739 if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base);
621 ci->savedpc = L->savedpc; 740 /* move new frame into old one */
622 ci->tailcalls++; /* one more call lost */ 741 for (aux = 0; nfunc + aux < lim; aux++)
623 L->ci--; /* remove new frame */ 742 setobjs2s(L, ofunc + aux, nfunc + aux);
624 goto reentry; 743 oci->u.l.base = ofunc + (nci->u.l.base - nfunc); /* correct base */
625 } 744 oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */
626 case PCRC: { /* it was a C function (`precall' called it) */ 745 oci->u.l.savedpc = nci->u.l.savedpc;
627 base = L->base; 746 oci->callstatus |= CIST_TAIL; /* function was tail called */
628 continue; 747 ci = L->ci = oci; /* remove new frame */
629 } 748 lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize);
630 default: { 749 goto newframe; /* restart luaV_execute over new Lua function */
631 return; /* yield */
632 }
633 } 750 }
634 } 751 )
635 case OP_RETURN: { 752 vmcasenb(OP_RETURN,
636 int b = GETARG_B(i); 753 int b = GETARG_B(i);
637 if (b != 0) L->top = ra+b-1; 754 if (b != 0) L->top = ra+b-1;
638 if (L->openupval) luaF_close(L, base); 755 if (cl->p->sizep > 0) luaF_close(L, base);
639 L->savedpc = pc;
640 b = luaD_poscall(L, ra); 756 b = luaD_poscall(L, ra);
641 if (--nexeccalls == 0) /* was previous function running `here'? */ 757 if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */
642 return; /* no: return */ 758 return; /* external invocation: return */
643 else { /* yes: continue its execution */ 759 else { /* invocation via reentry: continue execution */
644 if (b) L->top = L->ci->top; 760 ci = L->ci;
645 lua_assert(isLua(L->ci)); 761 if (b) L->top = ci->top;
646 lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL); 762 lua_assert(isLua(ci));
647 goto reentry; 763 lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL);
764 goto newframe; /* restart luaV_execute over new Lua function */
648 } 765 }
649 } 766 )
650 case OP_FORLOOP: { 767 vmcase(OP_FORLOOP,
651 lua_Number step = nvalue(ra+2); 768 lua_Number step = nvalue(ra+2);
652 lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ 769 lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */
653 lua_Number limit = nvalue(ra+1); 770 lua_Number limit = nvalue(ra+1);
654 if (luai_numlt(0, step) ? luai_numle(idx, limit) 771 if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit)
655 : luai_numle(limit, idx)) { 772 : luai_numle(L, limit, idx)) {
656 dojump(L, pc, GETARG_sBx(i)); /* jump back */ 773 ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
657 setnvalue(ra, idx); /* update internal index... */ 774 setnvalue(ra, idx); /* update internal index... */
658 setnvalue(ra+3, idx); /* ...and external index */ 775 setnvalue(ra+3, idx); /* ...and external index */
659 } 776 }
660 continue; 777 )
661 } 778 vmcase(OP_FORPREP,
662 case OP_FORPREP: {
663 const TValue *init = ra; 779 const TValue *init = ra;
664 const TValue *plimit = ra+1; 780 const TValue *plimit = ra+1;
665 const TValue *pstep = ra+2; 781 const TValue *pstep = ra+2;
666 L->savedpc = pc; /* next steps may throw errors */
667 if (!tonumber(init, ra)) 782 if (!tonumber(init, ra))
668 luaG_runerror(L, LUA_QL("for") " initial value must be a number"); 783 luaG_runerror(L, LUA_QL("for") " initial value must be a number");
669 else if (!tonumber(plimit, ra+1)) 784 else if (!tonumber(plimit, ra+1))
670 luaG_runerror(L, LUA_QL("for") " limit must be a number"); 785 luaG_runerror(L, LUA_QL("for") " limit must be a number");
671 else if (!tonumber(pstep, ra+2)) 786 else if (!tonumber(pstep, ra+2))
672 luaG_runerror(L, LUA_QL("for") " step must be a number"); 787 luaG_runerror(L, LUA_QL("for") " step must be a number");
673 setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); 788 setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep)));
674 dojump(L, pc, GETARG_sBx(i)); 789 ci->u.l.savedpc += GETARG_sBx(i);
675 continue; 790 )
676 } 791 vmcasenb(OP_TFORCALL,
677 case OP_TFORLOOP: {
678 StkId cb = ra + 3; /* call base */ 792 StkId cb = ra + 3; /* call base */
679 setobjs2s(L, cb+2, ra+2); 793 setobjs2s(L, cb+2, ra+2);
680 setobjs2s(L, cb+1, ra+1); 794 setobjs2s(L, cb+1, ra+1);
681 setobjs2s(L, cb, ra); 795 setobjs2s(L, cb, ra);
682 L->top = cb+3; /* func. + 2 args (state and index) */ 796 L->top = cb + 3; /* func. + 2 args (state and index) */
683 Protect(luaD_call(L, cb, GETARG_C(i))); 797 Protect(luaD_call(L, cb, GETARG_C(i), 1));
684 L->top = L->ci->top; 798 L->top = ci->top;
685 cb = RA(i) + 3; /* previous call may change the stack */ 799 i = *(ci->u.l.savedpc++); /* go to next instruction */
686 if (!ttisnil(cb)) { /* continue loop? */ 800 ra = RA(i);
687 setobjs2s(L, cb-1, cb); /* save control variable */ 801 lua_assert(GET_OPCODE(i) == OP_TFORLOOP);
688 dojump(L, pc, GETARG_sBx(*pc)); /* jump back */ 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 */
689 } 809 }
690 pc++; 810 )
691 continue; 811 vmcase(OP_SETLIST,
692 }
693 case OP_SETLIST: {
694 int n = GETARG_B(i); 812 int n = GETARG_B(i);
695 int c = GETARG_C(i); 813 int c = GETARG_C(i);
696 int last; 814 int last;
697 Table *h; 815 Table *h;
698 if (n == 0) { 816 if (n == 0) n = cast_int(L->top - ra) - 1;
699 n = cast_int(L->top - ra) - 1; 817 if (c == 0) {
700 L->top = L->ci->top; 818 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG);
819 c = GETARG_Ax(*ci->u.l.savedpc++);
701 } 820 }
702 if (c == 0) c = cast_int(*pc++); 821 luai_runtimecheck(L, ttistable(ra));
703 runtime_check(L, ttistable(ra));
704 h = hvalue(ra); 822 h = hvalue(ra);
705 last = ((c-1)*LFIELDS_PER_FLUSH) + n; 823 last = ((c-1)*LFIELDS_PER_FLUSH) + n;
706 if (last > h->sizearray) /* needs more space? */ 824 if (last > h->sizearray) /* needs more space? */
707 luaH_resizearray(L, h, last); /* pre-alloc it at once */ 825 luaH_resizearray(L, h, last); /* pre-allocate it at once */
708 for (; n > 0; n--) { 826 for (; n > 0; n--) {
709 TValue *val = ra+n; 827 TValue *val = ra+n;
710 setobj2t(L, luaH_setnum(L, h, last--), val); 828 luaH_setint(L, h, last--, val);
711 luaC_barriert(L, h, val); 829 luaC_barrierback(L, obj2gco(h), val);
712 } 830 }
713 continue; 831 L->top = ci->top; /* correct top (in case of previous open call) */
714 } 832 )
715 case OP_CLOSE: { 833 vmcase(OP_CLOSURE,
716 luaF_close(L, ra); 834 Proto *p = cl->p->p[GETARG_Bx(i)];
717 continue; 835 Closure *ncl = getcached(p, cl->upvals, base); /* cached closure */
718 } 836 if (ncl == NULL) /* no match? */
719 case OP_CLOSURE: { 837 pushclosure(L, p, cl->upvals, base, ra); /* create a new one */
720 Proto *p; 838 else
721 Closure *ncl; 839 setclLvalue(L, ra, ncl); /* push cashed closure */
722 int nup, j; 840 checkGC(L, ra + 1);
723 p = cl->p->p[GETARG_Bx(i)]; 841 )
724 nup = p->nups; 842 vmcase(OP_VARARG,
725 ncl = luaF_newLclosure(L, nup, cl->env);
726 ncl->l.p = p;
727 for (j=0; j<nup; j++, pc++) {
728 if (GET_OPCODE(*pc) == OP_GETUPVAL)
729 ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
730 else {
731 lua_assert(GET_OPCODE(*pc) == OP_MOVE);
732 ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
733 }
734 }
735 setclvalue(L, ra, ncl);
736 Protect(luaC_checkGC(L));
737 continue;
738 }
739 case OP_VARARG: {
740 int b = GETARG_B(i) - 1; 843 int b = GETARG_B(i) - 1;
741 int j; 844 int j;
742 CallInfo *ci = L->ci; 845 int n = cast_int(base - ci->func) - cl->p->numparams - 1;
743 int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1; 846 if (b < 0) { /* B == 0? */
744 if (b == LUA_MULTRET) { 847 b = n; /* get all var. arguments */
745 Protect(luaD_checkstack(L, n)); 848 Protect(luaD_checkstack(L, n));
746 ra = RA(i); /* previous call may change the stack */ 849 ra = RA(i); /* previous call may change the stack */
747 b = n;
748 L->top = ra + n; 850 L->top = ra + n;
749 } 851 }
750 for (j = 0; j < b; j++) { 852 for (j = 0; j < b; j++) {
751 if (j < n) { 853 if (j < n) {
752 setobjs2s(L, ra + j, ci->base - n + j); 854 setobjs2s(L, ra + j, base - n + j);
753 } 855 }
754 else { 856 else {
755 setnilvalue(ra + j); 857 setnilvalue(ra + j);
756 } 858 }
757 } 859 }
758 continue; 860 )
759 } 861 vmcase(OP_EXTRAARG,
862 lua_assert(0);
863 )
760 } 864 }
761 } 865 }
762} 866}
diff --git a/apps/plugins/lua/lvm.h b/apps/plugins/lua/lvm.h
index dff2a139f7..5380270da6 100644
--- a/apps/plugins/lua/lvm.h
+++ b/apps/plugins/lua/lvm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: lvm.h,v 2.18.1.1 2013/04/12 18:48:47 roberto Exp $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -13,24 +13,32 @@
13#include "ltm.h" 13#include "ltm.h"
14 14
15 15
16#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o))) 16#define tostring(L,o) (ttisstring(o) || (luaV_tostring(L, o)))
17 17
18#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \ 18#define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL))
19 (((o) = luaV_tonumber(o,n)) != NULL))
20 19
21#define equalobj(L,o1,o2) \ 20#define equalobj(L,o1,o2) (ttisequal(o1, o2) && luaV_equalobj_(L, o1, o2))
22 (ttype(o1) == ttype(o2) && luaV_equalval(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);
23 27
24 28
25LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); 29LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
26LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); 30LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
27LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); 31LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
28LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); 32LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
29LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, 33LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
30 StkId val); 34 StkId val);
31LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, 35LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
32 StkId val); 36 StkId val);
33LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls); 37LUAI_FUNC void luaV_finishOp (lua_State *L);
34LUAI_FUNC void luaV_concat (lua_State *L, int total, int last); 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);
35 43
36#endif 44#endif
diff --git a/apps/plugins/lua/lzio.c b/apps/plugins/lua/lzio.c
index 293edd59b0..20efea9830 100644
--- a/apps/plugins/lua/lzio.c
+++ b/apps/plugins/lua/lzio.c
@@ -1,6 +1,6 @@
1/* 1/*
2** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ 2** $Id: lzio.c,v 1.35.1.1 2013/04/12 18:48:47 roberto Exp $
3** a generic input stream interface 3** Buffered streams
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
6 6
@@ -25,23 +25,11 @@ int luaZ_fill (ZIO *z) {
25 lua_unlock(L); 25 lua_unlock(L);
26 buff = z->reader(L, z->data, &size); 26 buff = z->reader(L, z->data, &size);
27 lua_lock(L); 27 lua_lock(L);
28 if (buff == NULL || size == 0) return EOZ; 28 if (buff == NULL || size == 0)
29 z->n = size - 1; 29 return EOZ;
30 z->n = size - 1; /* discount char being returned */
30 z->p = buff; 31 z->p = buff;
31 return char2int(*(z->p++)); 32 return cast_uchar(*(z->p++));
32}
33
34
35int luaZ_lookahead (ZIO *z) {
36 if (z->n == 0) {
37 if (luaZ_fill(z) == EOZ)
38 return EOZ;
39 else {
40 z->n++; /* luaZ_fill removed first byte; put back it */
41 z->p--;
42 }
43 }
44 return char2int(*z->p);
45} 33}
46 34
47 35
@@ -58,8 +46,14 @@ void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
58size_t luaZ_read (ZIO *z, void *b, size_t n) { 46size_t luaZ_read (ZIO *z, void *b, size_t n) {
59 while (n) { 47 while (n) {
60 size_t m; 48 size_t m;
61 if (luaZ_lookahead(z) == EOZ) 49 if (z->n == 0) { /* no bytes in buffer? */
62 return n; /* return number of missing bytes */ 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 }
63 m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 57 m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
64 memcpy(b, z->p, m); 58 memcpy(b, z->p, m);
65 z->n -= m; 59 z->n -= m;
diff --git a/apps/plugins/lua/lzio.h b/apps/plugins/lua/lzio.h
index 9aa9e4b537..441f7479cb 100644
--- a/apps/plugins/lua/lzio.h
+++ b/apps/plugins/lua/lzio.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id$ 2** $Id: lzio.h,v 1.26.1.1 2013/04/12 18:48:47 roberto Exp $
3** Buffered streams 3** Buffered streams
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -17,9 +17,8 @@
17 17
18typedef struct Zio ZIO; 18typedef struct Zio ZIO;
19 19
20#define char2int(c) cast(int, cast(unsigned char, (c))) 20#define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z))
21 21
22#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z))
23 22
24typedef struct Mbuffer { 23typedef struct Mbuffer {
25 char *buffer; 24 char *buffer;
@@ -47,7 +46,6 @@ LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
47LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, 46LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
48 void *data); 47 void *data);
49LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ 48LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */
50LUAI_FUNC int luaZ_lookahead (ZIO *z);
51 49
52 50
53 51
@@ -56,7 +54,7 @@ LUAI_FUNC int luaZ_lookahead (ZIO *z);
56struct Zio { 54struct Zio {
57 size_t n; /* bytes still unread */ 55 size_t n; /* bytes still unread */
58 const char *p; /* current position in buffer */ 56 const char *p; /* current position in buffer */
59 lua_Reader reader; 57 lua_Reader reader; /* reader function */
60 void* data; /* additional data */ 58 void* data; /* additional data */
61 lua_State *L; /* Lua state (for reader) */ 59 lua_State *L; /* Lua state (for reader) */
62}; 60};
diff --git a/apps/plugins/lua/rockconf.h b/apps/plugins/lua/rockconf.h
index a13146d7e9..eda1e05084 100644
--- a/apps/plugins/lua/rockconf.h
+++ b/apps/plugins/lua/rockconf.h
@@ -25,10 +25,6 @@
25#include "plugin.h" 25#include "plugin.h"
26#include <tlsf.h> 26#include <tlsf.h>
27 27
28#undef LUAI_THROW
29#undef LUAI_TRY
30#undef luai_jmpbuf
31
32#undef LUA_PATH_DEFAULT 28#undef LUA_PATH_DEFAULT
33#define LUA_PATH_DEFAULT "$/?.lua;" "$/?/init.lua;" VIEWERS_DIR"/lua/?.lua;" VIEWERS_DIR"/lua/?/init.lua;" 29#define LUA_PATH_DEFAULT "$/?.lua;" "$/?/init.lua;" VIEWERS_DIR"/lua/?.lua;" VIEWERS_DIR"/lua/?/init.lua;"
34 30
@@ -36,20 +32,11 @@
36 32
37#include "lib/pluginlib_exit.h" 33#include "lib/pluginlib_exit.h"
38 34
39#define LUAI_THROW(L,c) longjmp((c)->b, 1)
40#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
41#define luai_jmpbuf jmp_buf
42
43extern char curpath[MAX_PATH]; 35extern char curpath[MAX_PATH];
44struct tm *gmtime(const time_t *timep); 36struct tm *gmtime(const time_t *timep);
45long strtol(const char *nptr, char **endptr, int base); 37long strtol(const char *nptr, char **endptr, int base);
46unsigned long strtoul(const char *str, char **endptr, int base); 38unsigned long strtoul(const char *str, char **endptr, int base);
47size_t strftime(char* dst, size_t max, const char* format, const struct tm* tm); 39size_t strftime(char* dst, size_t max, const char* format, const struct tm* tm);
48long lfloor(long x);
49long lpow(long x, long y);
50
51#define floor lfloor
52#define pow lpow
53 40
54/* Simple substitutions */ 41/* Simple substitutions */
55#define malloc tlsf_malloc 42#define malloc tlsf_malloc
@@ -63,5 +50,17 @@ long lpow(long x, long y);
63#define strcpy rb->strcpy 50#define strcpy rb->strcpy
64#define strlen rb->strlen 51#define strlen rb->strlen
65 52
53#define getlocaledecpoint() '.'
54#define abort() exit(EXIT_FAILURE)
55#define difftime(t1,t0) ((t1) - (t0))
56#define localtime gmtime
57#if CONFIG_RTC
58#define time(x) mktime(rb->get_time())
59#define mktime rb->mktime
60#else
61#define time(x) (0)
62#define mktime(x) (0)
63#endif
64
66#endif /* _ROCKCONF_H_ */ 65#endif /* _ROCKCONF_H_ */
67 66
diff --git a/apps/plugins/lua/rocklib.c b/apps/plugins/lua/rocklib.c
index 27c1177748..f214aca694 100644
--- a/apps/plugins/lua/rocklib.c
+++ b/apps/plugins/lua/rocklib.c
@@ -156,7 +156,19 @@ static int rli_tostring(lua_State *L)
156 return 1; 156 return 1;
157} 157}
158 158
159static const struct luaL_reg rli_lib [] = 159int rli_checkboolean (lua_State *L, int narg) {
160 int b = lua_toboolean(L, narg);
161 if (b == 0)
162 luaL_checktype(L, narg, LUA_TBOOLEAN);
163 return b;
164}
165
166
167int rli_optboolean (lua_State *L, int narg, int def) {
168 return luaL_opt(L, rli_checkboolean, narg, def);
169}
170
171static const struct luaL_Reg rli_lib [] =
160{ 172{
161 {"__tostring", rli_tostring}, 173 {"__tostring", rli_tostring},
162 {"set", rli_set}, 174 {"set", rli_set},
@@ -472,8 +484,8 @@ RB_WRAP(read_bmp_file)
472{ 484{
473 struct bitmap bm; 485 struct bitmap bm;
474 const char* filename = luaL_checkstring(L, 1); 486 const char* filename = luaL_checkstring(L, 1);
475 bool dither = luaL_optboolean(L, 2, true); 487 bool dither = rli_optboolean(L, 2, true);
476 bool transparent = luaL_optboolean(L, 3, false); 488 bool transparent = rli_optboolean(L, 3, false);
477 int format = FORMAT_NATIVE; 489 int format = FORMAT_NATIVE;
478 490
479 if(dither) 491 if(dither)
@@ -516,7 +528,7 @@ static void fill_text_message(lua_State *L, struct text_message * message,
516{ 528{
517 int i; 529 int i;
518 luaL_checktype(L, pos, LUA_TTABLE); 530 luaL_checktype(L, pos, LUA_TTABLE);
519 int n = luaL_getn(L, pos); 531 int n = lua_rawlen(L, pos);
520 const char **lines = (const char**) tlsf_malloc(n * sizeof(const char*)); 532 const char **lines = (const char**) tlsf_malloc(n * sizeof(const char*));
521 if(lines == NULL) 533 if(lines == NULL)
522 luaL_error(L, "Can't allocate %d bytes!", n * sizeof(const char*)); 534 luaL_error(L, "Can't allocate %d bytes!", n * sizeof(const char*));
@@ -565,7 +577,7 @@ RB_WRAP(do_menu)
565 luaL_checktype(L, 2, LUA_TTABLE); 577 luaL_checktype(L, 2, LUA_TTABLE);
566 start_selected = luaL_optint(L, 3, 0); 578 start_selected = luaL_optint(L, 3, 0);
567 579
568 n = luaL_getn(L, 2); 580 n = lua_rawlen(L, 2);
569 items = (const char**) tlsf_malloc(n * sizeof(const char*)); 581 items = (const char**) tlsf_malloc(n * sizeof(const char*));
570 if(items == NULL) 582 if(items == NULL)
571 luaL_error(L, "Can't allocate %d bytes!", n * sizeof(const char*)); 583 luaL_error(L, "Can't allocate %d bytes!", n * sizeof(const char*));
@@ -758,8 +770,9 @@ extern const luaL_Reg rocklib_aux[];
758 */ 770 */
759LUALIB_API int luaopen_rock(lua_State *L) 771LUALIB_API int luaopen_rock(lua_State *L)
760{ 772{
761 luaL_register(L, LUA_ROCKLIBNAME, rocklib); 773 rli_init(L);
762 luaL_register(L, LUA_ROCKLIBNAME, rocklib_aux); 774 luaL_newlib(L, rocklib);
775 luaL_setfuncs(L, rocklib_aux, 0);
763 776
764 RB_CONSTANT(HZ); 777 RB_CONSTANT(HZ);
765 778
@@ -797,7 +810,6 @@ LUALIB_API int luaopen_rock(lua_State *L)
797 RB_STRING_CONSTANT(PLUGIN_DATA_DIR); 810 RB_STRING_CONSTANT(PLUGIN_DATA_DIR);
798 RB_STRING_CONSTANT(VIEWERS_DATA_DIR); 811 RB_STRING_CONSTANT(VIEWERS_DATA_DIR);
799 812
800 rli_init(L);
801 813
802 return 1; 814 return 1;
803} 815}
diff --git a/apps/plugins/lua/rocklib.h b/apps/plugins/lua/rocklib.h
index 84b5fd2de0..2b259ee53e 100644
--- a/apps/plugins/lua/rocklib.h
+++ b/apps/plugins/lua/rocklib.h
@@ -25,6 +25,7 @@
25#define LUA_ROCKLIBNAME "rb" 25#define LUA_ROCKLIBNAME "rb"
26LUALIB_API int (luaopen_rock) (lua_State *L); 26LUALIB_API int (luaopen_rock) (lua_State *L);
27const char* get_current_path(lua_State *L, int level); 27const char* get_current_path(lua_State *L, int level);
28int rli_checkboolean (lua_State *L, int narg);
28 29
29#endif /* _ROCKLIB_H_ */ 30#endif /* _ROCKLIB_H_ */
30 31
diff --git a/apps/plugins/lua/rocklib_aux.pl b/apps/plugins/lua/rocklib_aux.pl
index 9103fccbda..61e0115bdf 100755
--- a/apps/plugins/lua/rocklib_aux.pl
+++ b/apps/plugins/lua/rocklib_aux.pl
@@ -133,6 +133,7 @@ print <<EOF
133 133
134#define _ROCKCONF_H_ /* We don't need strcmp() etc. wrappers */ 134#define _ROCKCONF_H_ /* We don't need strcmp() etc. wrappers */
135#include "lua.h" 135#include "lua.h"
136#include "rocklib.h"
136#include "lauxlib.h" 137#include "lauxlib.h"
137#include "plugin.h" 138#include "plugin.h"
138 139
@@ -207,7 +208,7 @@ sub in_string
207sub in_bool 208sub in_bool
208{ 209{
209 my ($name, $type, $pos) = @_; 210 my ($name, $type, $pos) = @_;
210 return sprintf("\tbool %s = luaL_checkboolean(L, %d);\n", $name, $pos) 211 return sprintf("\tbool %s = rli_checkboolean(L, %d);\n", $name, $pos)
211} 212}
212 213
213sub out_void 214sub out_void
diff --git a/apps/plugins/lua/rocklibc.h b/apps/plugins/lua/rocklibc.h
index 44f916fded..430889bb70 100644
--- a/apps/plugins/lua/rocklibc.h
+++ b/apps/plugins/lua/rocklibc.h
@@ -30,6 +30,7 @@
30#include <errno.h> 30#include <errno.h>
31#define PREFIX(_x_) sim_ ## _x_ 31#define PREFIX(_x_) sim_ ## _x_
32#else 32#else
33#undef errno
33extern int errno; 34extern int errno;
34#define EINVAL 22 /* Invalid argument */ 35#define EINVAL 22 /* Invalid argument */
35#define ERANGE 34 /* Math result not representable */ 36#define ERANGE 34 /* Math result not representable */
@@ -43,7 +44,8 @@ extern int errno;
43#define memcmp rb->memcmp 44#define memcmp rb->memcmp
44#define strlen rb->strlen 45#define strlen rb->strlen
45 46
46extern int PREFIX(fscanf)(int fd, const char *fmt, ...); 47extern int PREFIX(fscanf)(void *fd, const char *fmt, ...);
48extern int PREFIX(getc)(int fd);
47 49
48#endif /* _ROCKLIBC_H_ */ 50#endif /* _ROCKLIBC_H_ */
49 51
diff --git a/apps/plugins/lua/rocklua.c b/apps/plugins/lua/rocklua.c
index 5539618a43..4f328dd84a 100644
--- a/apps/plugins/lua/rocklua.c
+++ b/apps/plugins/lua/rocklua.c
@@ -26,7 +26,8 @@
26#include "rocklib.h" 26#include "rocklib.h"
27#include "luadir.h" 27#include "luadir.h"
28 28
29 29#undef LUA_BITLIBNAME
30#define LUA_BITLIBNAME "bit"
30 31
31static const luaL_Reg lualibs[] = { 32static const luaL_Reg lualibs[] = {
32 {"", luaopen_base}, 33 {"", luaopen_base},
@@ -34,7 +35,7 @@ static const luaL_Reg lualibs[] = {
34 {LUA_STRLIBNAME, luaopen_string}, 35 {LUA_STRLIBNAME, luaopen_string},
35 {LUA_OSLIBNAME, luaopen_os}, 36 {LUA_OSLIBNAME, luaopen_os},
36 {LUA_ROCKLIBNAME, luaopen_rock}, 37 {LUA_ROCKLIBNAME, luaopen_rock},
37 {LUA_BITLIBNAME, luaopen_bit}, 38 {LUA_BITLIBNAME, luaopen_bit32},
38 {LUA_IOLIBNAME, luaopen_io}, 39 {LUA_IOLIBNAME, luaopen_io},
39 {LUA_LOADLIBNAME, luaopen_package}, 40 {LUA_LOADLIBNAME, luaopen_package},
40 {LUA_MATHLIBNAME, luaopen_math}, 41 {LUA_MATHLIBNAME, luaopen_math},
@@ -43,11 +44,10 @@ static const luaL_Reg lualibs[] = {
43}; 44};
44 45
45static void rocklua_openlibs(lua_State *L) { 46static void rocklua_openlibs(lua_State *L) {
46 const luaL_Reg *lib = lualibs; 47 const luaL_Reg *lib;
47 for (; lib->func; lib++) { 48 for (lib = lualibs; lib->func; lib++) {
48 lua_pushcfunction(L, lib->func); 49 luaL_requiref(L, lib->name, lib->func, 1);
49 lua_pushstring(L, lib->name); 50 lua_pop(L, 1); /* remove lib */
50 lua_call(L, 1, 0);
51 } 51 }
52} 52}
53 53
diff --git a/apps/plugins/lua/strcspn.c b/apps/plugins/lua/strcspn.c
deleted file mode 100644
index 0a19eaebf2..0000000000
--- a/apps/plugins/lua/strcspn.c
+++ /dev/null
@@ -1,17 +0,0 @@
1#include "rocklibc.h"
2
3#undef strcspn
4size_t strcspn(const char *s, const char *reject)
5{
6 size_t l=0;
7 int a=1,i,al=strlen(reject);
8
9 while((a)&&(*s))
10 {
11 for(i=0;(a)&&(i<al);i++)
12 if (*s==reject[i]) a=0;
13 if (a) l++;
14 s++;
15 }
16 return l;
17}
diff --git a/apps/plugins/lua/strspn.c b/apps/plugins/lua/strspn.c
new file mode 100644
index 0000000000..e95500a1dc
--- /dev/null
+++ b/apps/plugins/lua/strspn.c
@@ -0,0 +1,19 @@
1#include "rocklibc.h"
2
3#undef strspn
4
5size_t strspn(const char *s, const char *accept)
6{
7 size_t count;
8 for (count = 0; *s != 0; s++, count++) {
9 const char *ac;
10 for (ac = accept; *ac != 0; ac++) {
11 if (*ac == *s)
12 break;
13 }
14 if (*ac == 0) /* no acceptable char found */
15 break;
16 }
17 return count;
18}
19